ieee80211_hostap.c revision 297604
1190214Srpaulo/*- 2190214Srpaulo * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting 3190214Srpaulo * All rights reserved. 4190214Srpaulo * 5190214Srpaulo * Redistribution and use in source and binary forms, with or without 6190214Srpaulo * modification, are permitted provided that the following conditions 7190214Srpaulo * are met: 8190214Srpaulo * 1. Redistributions of source code must retain the above copyright 9190214Srpaulo * notice, this list of conditions and the following disclaimer. 10190214Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 11190214Srpaulo * notice, this list of conditions and the following disclaimer in the 12190214Srpaulo * documentation and/or other materials provided with the distribution. 13190214Srpaulo * 14190214Srpaulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15190214Srpaulo * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16190214Srpaulo * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17190214Srpaulo * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18190214Srpaulo * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19190214Srpaulo * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20190214Srpaulo * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21190214Srpaulo * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22190214Srpaulo * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23190214Srpaulo * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24190214Srpaulo */ 25190214Srpaulo 26190214Srpaulo#include <sys/cdefs.h> 27190214Srpaulo#ifdef __FreeBSD__ 28190214Srpaulo__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_hostap.c 297604 2016-04-06 01:22:20Z adrian $"); 29190214Srpaulo#endif 30190214Srpaulo 31190214Srpaulo/* 32190214Srpaulo * IEEE 802.11 HOSTAP mode support. 33190214Srpaulo */ 34190214Srpaulo#include "opt_inet.h" 35190214Srpaulo#include "opt_wlan.h" 36190214Srpaulo 37190214Srpaulo#include <sys/param.h> 38190214Srpaulo#include <sys/systm.h> 39190214Srpaulo#include <sys/mbuf.h> 40214518Srpaulo#include <sys/malloc.h> 41190214Srpaulo#include <sys/kernel.h> 42190214Srpaulo 43190214Srpaulo#include <sys/socket.h> 44190214Srpaulo#include <sys/sockio.h> 45190214Srpaulo#include <sys/endian.h> 46190214Srpaulo#include <sys/errno.h> 47190214Srpaulo#include <sys/proc.h> 48190214Srpaulo#include <sys/sysctl.h> 49190214Srpaulo 50190214Srpaulo#include <net/if.h> 51235426Sdelphij#include <net/if_var.h> 52235426Sdelphij#include <net/if_media.h> 53235426Sdelphij#include <net/if_llc.h> 54235426Sdelphij#include <net/ethernet.h> 55190214Srpaulo 56190214Srpaulo#include <net/bpf.h> 57235426Sdelphij 58235426Sdelphij#include <net80211/ieee80211_var.h> 59235426Sdelphij#include <net80211/ieee80211_hostap.h> 60235426Sdelphij#include <net80211/ieee80211_input.h> 61235426Sdelphij#ifdef IEEE80211_SUPPORT_SUPERG 62235426Sdelphij#include <net80211/ieee80211_superg.h> 63235426Sdelphij#endif 64235426Sdelphij#include <net80211/ieee80211_wds.h> 65235426Sdelphij 66235426Sdelphij#define IEEE80211_RATE2MBS(r) (((r) & IEEE80211_RATE_VAL) / 2) 67235426Sdelphij 68235426Sdelphijstatic void hostap_vattach(struct ieee80211vap *); 69235426Sdelphijstatic int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int); 70235426Sdelphijstatic int hostap_input(struct ieee80211_node *ni, struct mbuf *m, 71235426Sdelphij const struct ieee80211_rx_stats *, 72235426Sdelphij int rssi, int nf); 73235426Sdelphijstatic void hostap_deliver_data(struct ieee80211vap *, 74235426Sdelphij struct ieee80211_node *, struct mbuf *); 75190214Srpaulostatic void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *, 76190214Srpaulo int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf); 77190214Srpaulostatic void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int); 78190214Srpaulo 79190214Srpaulovoid 80190214Srpauloieee80211_hostap_attach(struct ieee80211com *ic) 81190214Srpaulo{ 82190214Srpaulo ic->ic_vattach[IEEE80211_M_HOSTAP] = hostap_vattach; 83190214Srpaulo} 84190214Srpaulo 85190214Srpaulovoid 86190214Srpauloieee80211_hostap_detach(struct ieee80211com *ic) 87190214Srpaulo{ 88190214Srpaulo} 89190214Srpaulo 90190214Srpaulostatic void 91190214Srpaulohostap_vdetach(struct ieee80211vap *vap) 92190214Srpaulo{ 93235426Sdelphij} 94235426Sdelphij 95235426Sdelphijstatic void 96190214Srpaulohostap_vattach(struct ieee80211vap *vap) 97190214Srpaulo{ 98190214Srpaulo vap->iv_newstate = hostap_newstate; 99190214Srpaulo vap->iv_input = hostap_input; 100190214Srpaulo vap->iv_recv_mgmt = hostap_recv_mgmt; 101190214Srpaulo vap->iv_recv_ctl = hostap_recv_ctl; 102190214Srpaulo vap->iv_opdetach = hostap_vdetach; 103190214Srpaulo vap->iv_deliver_data = hostap_deliver_data; 104190214Srpaulo vap->iv_recv_pspoll = ieee80211_recv_pspoll; 105190214Srpaulo} 106190214Srpaulo 107190214Srpaulostatic void 108190214Srpaulosta_disassoc(void *arg, struct ieee80211_node *ni) 109190214Srpaulo{ 110190214Srpaulo struct ieee80211vap *vap = arg; 111190214Srpaulo 112190214Srpaulo if (ni->ni_vap == vap && ni->ni_associd != 0) { 113235426Sdelphij IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DISASSOC, 114190214Srpaulo IEEE80211_REASON_ASSOC_LEAVE); 115190214Srpaulo ieee80211_node_leave(ni); 116190214Srpaulo } 117190214Srpaulo} 118190214Srpaulo 119190214Srpaulostatic void 120190214Srpaulosta_csa(void *arg, struct ieee80211_node *ni) 121190214Srpaulo{ 122235426Sdelphij struct ieee80211vap *vap = arg; 123235426Sdelphij 124235426Sdelphij if (ni->ni_vap == vap && ni->ni_associd != 0) 125235426Sdelphij if (ni->ni_inact > vap->iv_inact_init) { 126235426Sdelphij ni->ni_inact = vap->iv_inact_init; 127235426Sdelphij IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni, 128190214Srpaulo "%s: inact %u", __func__, ni->ni_inact); 129190214Srpaulo } 130190214Srpaulo} 131190214Srpaulo 132190214Srpaulostatic void 133190214Srpaulosta_drop(void *arg, struct ieee80211_node *ni) 134190214Srpaulo{ 135190214Srpaulo struct ieee80211vap *vap = arg; 136190214Srpaulo 137190214Srpaulo if (ni->ni_vap == vap && ni->ni_associd != 0) 138190214Srpaulo ieee80211_node_leave(ni); 139190214Srpaulo} 140190214Srpaulo 141190214Srpaulo/* 142190214Srpaulo * Does a channel change require associated stations to re-associate 143190214Srpaulo * so protocol state is correct. This is used when doing CSA across 144190214Srpaulo * bands or similar (e.g. HT -> legacy). 145190214Srpaulo */ 146190214Srpaulostatic int 147190214Srpauloisbandchange(struct ieee80211com *ic) 148190214Srpaulo{ 149190214Srpaulo return ((ic->ic_bsschan->ic_flags ^ ic->ic_csa_newchan->ic_flags) & 150190214Srpaulo (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HALF | 151190214Srpaulo IEEE80211_CHAN_QUARTER | IEEE80211_CHAN_HT)) != 0; 152190214Srpaulo} 153190214Srpaulo 154190214Srpaulo/* 155190214Srpaulo * IEEE80211_M_HOSTAP vap state machine handler. 156190214Srpaulo */ 157190214Srpaulostatic int 158190214Srpaulohostap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 159190214Srpaulo{ 160190214Srpaulo struct ieee80211com *ic = vap->iv_ic; 161190214Srpaulo enum ieee80211_state ostate; 162190214Srpaulo 163190214Srpaulo IEEE80211_LOCK_ASSERT(ic); 164190214Srpaulo 165190214Srpaulo ostate = vap->iv_state; 166190214Srpaulo IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", 167190214Srpaulo __func__, ieee80211_state_name[ostate], 168190214Srpaulo ieee80211_state_name[nstate], arg); 169190214Srpaulo vap->iv_state = nstate; /* state transition */ 170190214Srpaulo if (ostate != IEEE80211_S_SCAN) 171190214Srpaulo ieee80211_cancel_scan(vap); /* background scan */ 172190214Srpaulo switch (nstate) { 173190214Srpaulo case IEEE80211_S_INIT: 174190214Srpaulo switch (ostate) { 175190214Srpaulo case IEEE80211_S_SCAN: 176190214Srpaulo ieee80211_cancel_scan(vap); 177190214Srpaulo break; 178190214Srpaulo case IEEE80211_S_CAC: 179190214Srpaulo ieee80211_dfs_cac_stop(vap); 180241231Sdelphij break; 181241231Sdelphij case IEEE80211_S_RUN: 182241231Sdelphij ieee80211_iterate_nodes(&ic->ic_sta, sta_disassoc, vap); 183241231Sdelphij break; 184241231Sdelphij default: 185241231Sdelphij break; 186241231Sdelphij } 187241231Sdelphij if (ostate != IEEE80211_S_INIT) { 188241231Sdelphij /* NB: optimize INIT -> INIT case */ 189241231Sdelphij ieee80211_reset_bss(vap); 190241231Sdelphij } 191190214Srpaulo if (vap->iv_auth->ia_detach != NULL) 192190214Srpaulo vap->iv_auth->ia_detach(vap); 193241231Sdelphij break; 194241231Sdelphij case IEEE80211_S_SCAN: 195241231Sdelphij switch (ostate) { 196241231Sdelphij case IEEE80211_S_CSA: 197241231Sdelphij case IEEE80211_S_RUN: 198241231Sdelphij ieee80211_iterate_nodes(&ic->ic_sta, sta_disassoc, vap); 199241231Sdelphij /* 200241231Sdelphij * Clear overlapping BSS state; the beacon frame 201241231Sdelphij * will be reconstructed on transition to the RUN 202241231Sdelphij * state and the timeout routines check if the flag 203241231Sdelphij * is set before doing anything so this is sufficient. 204241231Sdelphij */ 205241231Sdelphij ic->ic_flags_ext &= ~IEEE80211_FEXT_NONERP_PR; 206241231Sdelphij ic->ic_flags_ht &= ~IEEE80211_FHT_NONHT_PR; 207241231Sdelphij /* fall thru... */ 208241231Sdelphij case IEEE80211_S_CAC: 209241231Sdelphij /* 210241231Sdelphij * NB: We may get here because of a manual channel 211190214Srpaulo * change in which case we need to stop CAC 212190214Srpaulo * XXX no need to stop if ostate RUN but it's ok 213190214Srpaulo */ 214190214Srpaulo ieee80211_dfs_cac_stop(vap); 215190214Srpaulo /* fall thru... */ 216190214Srpaulo case IEEE80211_S_INIT: 217190214Srpaulo if (vap->iv_des_chan != IEEE80211_CHAN_ANYC && 218190214Srpaulo !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) { 219190214Srpaulo /* 220190214Srpaulo * Already have a channel; bypass the 221190214Srpaulo * scan and startup immediately. 222190214Srpaulo * ieee80211_create_ibss will call back to 223190214Srpaulo * move us to RUN state. 224190214Srpaulo */ 225190214Srpaulo ieee80211_create_ibss(vap, vap->iv_des_chan); 226190214Srpaulo break; 227190214Srpaulo } 228190214Srpaulo /* 229190214Srpaulo * Initiate a scan. We can come here as a result 230190214Srpaulo * of an IEEE80211_IOC_SCAN_REQ too in which case 231190214Srpaulo * the vap will be marked with IEEE80211_FEXT_SCANREQ 232190214Srpaulo * and the scan request parameters will be present 233190214Srpaulo * in iv_scanreq. Otherwise we do the default. 234190214Srpaulo */ 235190214Srpaulo if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { 236190214Srpaulo ieee80211_check_scan(vap, 237190214Srpaulo vap->iv_scanreq_flags, 238235426Sdelphij vap->iv_scanreq_duration, 239235426Sdelphij vap->iv_scanreq_mindwell, 240235426Sdelphij vap->iv_scanreq_maxdwell, 241190214Srpaulo vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); 242190214Srpaulo vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; 243190214Srpaulo } else 244235426Sdelphij ieee80211_check_scan_current(vap); 245235426Sdelphij break; 246235426Sdelphij case IEEE80211_S_SCAN: 247235426Sdelphij /* 248235426Sdelphij * A state change requires a reset; scan. 249235426Sdelphij */ 250235426Sdelphij ieee80211_check_scan_current(vap); 251235426Sdelphij break; 252235426Sdelphij default: 253235426Sdelphij break; 254235426Sdelphij } 255235426Sdelphij break; 256190214Srpaulo case IEEE80211_S_CAC: 257190214Srpaulo /* 258190214Srpaulo * Start CAC on a DFS channel. We come here when starting 259190214Srpaulo * a bss on a DFS channel (see ieee80211_create_ibss). 260190214Srpaulo */ 261190214Srpaulo ieee80211_dfs_cac_start(vap); 262190214Srpaulo break; 263190214Srpaulo case IEEE80211_S_RUN: 264190214Srpaulo if (vap->iv_flags & IEEE80211_F_WPA) { 265190214Srpaulo /* XXX validate prerequisites */ 266190214Srpaulo } 267190214Srpaulo switch (ostate) { 268190214Srpaulo case IEEE80211_S_INIT: 269190214Srpaulo /* 270190214Srpaulo * Already have a channel; bypass the 271190214Srpaulo * scan and startup immediately. 272190214Srpaulo * Note that ieee80211_create_ibss will call 273190214Srpaulo * back to do a RUN->RUN state change. 274190214Srpaulo */ 275190214Srpaulo ieee80211_create_ibss(vap, 276190214Srpaulo ieee80211_ht_adjust_channel(ic, 277190214Srpaulo ic->ic_curchan, vap->iv_flags_ht)); 278190214Srpaulo /* NB: iv_bss is changed on return */ 279190214Srpaulo break; 280190214Srpaulo case IEEE80211_S_CAC: 281190214Srpaulo /* 282190214Srpaulo * NB: This is the normal state change when CAC 283190214Srpaulo * expires and no radar was detected; no need to 284190214Srpaulo * clear the CAC timer as it's already expired. 285190214Srpaulo */ 286190214Srpaulo /* fall thru... */ 287190214Srpaulo case IEEE80211_S_CSA: 288190214Srpaulo /* 289190214Srpaulo * Shorten inactivity timer of associated stations 290190214Srpaulo * to weed out sta's that don't follow a CSA. 291190214Srpaulo */ 292190214Srpaulo ieee80211_iterate_nodes(&ic->ic_sta, sta_csa, vap); 293190214Srpaulo /* 294190214Srpaulo * Update bss node channel to reflect where 295190214Srpaulo * we landed after CSA. 296190214Srpaulo */ 297190214Srpaulo ieee80211_node_set_chan(vap->iv_bss, 298190214Srpaulo ieee80211_ht_adjust_channel(ic, ic->ic_curchan, 299190214Srpaulo ieee80211_htchanflags(vap->iv_bss->ni_chan))); 300190214Srpaulo /* XXX bypass debug msgs */ 301190214Srpaulo break; 302190214Srpaulo case IEEE80211_S_SCAN: 303190214Srpaulo case IEEE80211_S_RUN: 304190214Srpaulo#ifdef IEEE80211_DEBUG 305190214Srpaulo if (ieee80211_msg_debug(vap)) { 306190214Srpaulo struct ieee80211_node *ni = vap->iv_bss; 307190214Srpaulo ieee80211_note(vap, 308190214Srpaulo "synchronized with %s ssid ", 309190214Srpaulo ether_sprintf(ni->ni_bssid)); 310190214Srpaulo ieee80211_print_essid(ni->ni_essid, 311190214Srpaulo ni->ni_esslen); 312190214Srpaulo /* XXX MCS/HT */ 313190214Srpaulo printf(" channel %d start %uMb\n", 314190214Srpaulo ieee80211_chan2ieee(ic, ic->ic_curchan), 315190214Srpaulo IEEE80211_RATE2MBS(ni->ni_txrate)); 316190214Srpaulo } 317190214Srpaulo#endif 318190214Srpaulo break; 319190214Srpaulo default: 320190214Srpaulo break; 321190214Srpaulo } 322190214Srpaulo /* 323190214Srpaulo * Start/stop the authenticator. We delay until here 324190214Srpaulo * to allow configuration to happen out of order. 325190214Srpaulo */ 326190214Srpaulo if (vap->iv_auth->ia_attach != NULL) { 327190214Srpaulo /* XXX check failure */ 328190214Srpaulo vap->iv_auth->ia_attach(vap); 329190214Srpaulo } else if (vap->iv_auth->ia_detach != NULL) { 330190214Srpaulo vap->iv_auth->ia_detach(vap); 331190214Srpaulo } 332190214Srpaulo ieee80211_node_authorize(vap->iv_bss); 333190214Srpaulo break; 334190214Srpaulo case IEEE80211_S_CSA: 335190214Srpaulo if (ostate == IEEE80211_S_RUN && isbandchange(ic)) { 336190214Srpaulo /* 337190214Srpaulo * On a ``band change'' silently drop associated 338190214Srpaulo * stations as they must re-associate before they 339190214Srpaulo * can pass traffic (as otherwise protocol state 340190214Srpaulo * such as capabilities and the negotiated rate 341241231Sdelphij * set may/will be wrong). 342190214Srpaulo */ 343190214Srpaulo ieee80211_iterate_nodes(&ic->ic_sta, sta_drop, vap); 344190214Srpaulo } 345190214Srpaulo break; 346190214Srpaulo default: 347190214Srpaulo break; 348190214Srpaulo } 349190214Srpaulo return 0; 350190214Srpaulo} 351190214Srpaulo 352190214Srpaulostatic void 353190214Srpaulohostap_deliver_data(struct ieee80211vap *vap, 354190214Srpaulo struct ieee80211_node *ni, struct mbuf *m) 355190214Srpaulo{ 356190214Srpaulo struct ether_header *eh = mtod(m, struct ether_header *); 357190214Srpaulo struct ifnet *ifp = vap->iv_ifp; 358190214Srpaulo 359190214Srpaulo /* clear driver/net80211 flags before passing up */ 360190214Srpaulo m->m_flags &= ~(M_MCAST | M_BCAST); 361190214Srpaulo m_clrprotoflags(m); 362190214Srpaulo 363190214Srpaulo KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP, 364241231Sdelphij ("gack, opmode %d", vap->iv_opmode)); 365241231Sdelphij /* 366241231Sdelphij * Do accounting. 367241231Sdelphij */ 368241231Sdelphij if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 369241231Sdelphij IEEE80211_NODE_STAT(ni, rx_data); 370241231Sdelphij IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); 371241231Sdelphij if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 372241231Sdelphij m->m_flags |= M_MCAST; /* XXX M_BCAST? */ 373241231Sdelphij IEEE80211_NODE_STAT(ni, rx_mcast); 374241231Sdelphij } else 375241231Sdelphij IEEE80211_NODE_STAT(ni, rx_ucast); 376241231Sdelphij 377241231Sdelphij /* perform as a bridge within the AP */ 378241231Sdelphij if ((vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) { 379241231Sdelphij struct mbuf *mcopy = NULL; 380241231Sdelphij 381241231Sdelphij if (m->m_flags & M_MCAST) { 382241231Sdelphij mcopy = m_dup(m, M_NOWAIT); 383241231Sdelphij if (mcopy == NULL) 384241231Sdelphij if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 385241231Sdelphij else 386241231Sdelphij mcopy->m_flags |= M_MCAST; 387241231Sdelphij } else { 388241231Sdelphij /* 389241231Sdelphij * Check if the destination is associated with the 390241231Sdelphij * same vap and authorized to receive traffic. 391241231Sdelphij * Beware of traffic destined for the vap itself; 392241231Sdelphij * sending it will not work; just let it be delivered 393241231Sdelphij * normally. 394241231Sdelphij */ 395241231Sdelphij struct ieee80211_node *sta = ieee80211_find_vap_node( 396241231Sdelphij &vap->iv_ic->ic_sta, vap, eh->ether_dhost); 397241231Sdelphij if (sta != NULL) { 398241231Sdelphij if (ieee80211_node_is_authorized(sta)) { 399241231Sdelphij /* 400190214Srpaulo * Beware of sending to ourself; this 401241231Sdelphij * needs to happen via the normal 402241231Sdelphij * input path. 403241231Sdelphij */ 404190214Srpaulo if (sta != vap->iv_bss) { 405241231Sdelphij mcopy = m; 406190214Srpaulo m = NULL; 407190214Srpaulo } 408190214Srpaulo } else { 409190214Srpaulo vap->iv_stats.is_rx_unauth++; 410190214Srpaulo IEEE80211_NODE_STAT(sta, rx_unauth); 411190214Srpaulo } 412190214Srpaulo ieee80211_free_node(sta); 413190214Srpaulo } 414190214Srpaulo } 415190214Srpaulo if (mcopy != NULL) { 416190214Srpaulo int len, err; 417190214Srpaulo len = mcopy->m_pkthdr.len; 418190214Srpaulo err = ieee80211_vap_xmitpkt(vap, mcopy); 419190214Srpaulo if (err) { 420190214Srpaulo /* NB: IFQ_HANDOFF reclaims mcopy */ 421190214Srpaulo } else { 422190214Srpaulo if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 423190214Srpaulo } 424190214Srpaulo } 425190214Srpaulo } 426190214Srpaulo if (m != NULL) { 427190214Srpaulo /* 428190214Srpaulo * Mark frame as coming from vap's interface. 429190214Srpaulo */ 430190214Srpaulo m->m_pkthdr.rcvif = ifp; 431190214Srpaulo if (m->m_flags & M_MCAST) { 432190214Srpaulo /* 433190214Srpaulo * Spam DWDS vap's w/ multicast traffic. 434190214Srpaulo */ 435190214Srpaulo /* XXX only if dwds in use? */ 436190214Srpaulo ieee80211_dwds_mcast(vap, m); 437190214Srpaulo } 438190214Srpaulo if (ni->ni_vlan != 0) { 439190214Srpaulo /* attach vlan tag */ 440190214Srpaulo m->m_pkthdr.ether_vtag = ni->ni_vlan; 441190214Srpaulo m->m_flags |= M_VLANTAG; 442190214Srpaulo } 443190214Srpaulo ifp->if_input(ifp, m); 444190214Srpaulo } 445190214Srpaulo} 446190214Srpaulo 447190214Srpaulo/* 448190214Srpaulo * Decide if a received management frame should be 449190214Srpaulo * printed when debugging is enabled. This filters some 450190214Srpaulo * of the less interesting frames that come frequently 451190214Srpaulo * (e.g. beacons). 452190214Srpaulo */ 453190214Srpaulostatic __inline int 454190214Srpaulodoprint(struct ieee80211vap *vap, int subtype) 455190214Srpaulo{ 456190214Srpaulo switch (subtype) { 457190214Srpaulo case IEEE80211_FC0_SUBTYPE_BEACON: 458190214Srpaulo return (vap->iv_ic->ic_flags & IEEE80211_F_SCAN); 459190214Srpaulo case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 460190214Srpaulo return 0; 461190214Srpaulo } 462190214Srpaulo return 1; 463190214Srpaulo} 464190214Srpaulo 465190214Srpaulo/* 466190214Srpaulo * Process a received frame. The node associated with the sender 467190214Srpaulo * should be supplied. If nothing was found in the node table then 468190214Srpaulo * the caller is assumed to supply a reference to iv_bss instead. 469190214Srpaulo * The RSSI and a timestamp are also supplied. The RSSI data is used 470190214Srpaulo * during AP scanning to select a AP to associate with; it can have 471190214Srpaulo * any units so long as values have consistent units and higher values 472190214Srpaulo * mean ``better signal''. The receive timestamp is currently not used 473190214Srpaulo * by the 802.11 layer. 474190214Srpaulo */ 475190214Srpaulostatic int 476190214Srpaulohostap_input(struct ieee80211_node *ni, struct mbuf *m, 477190214Srpaulo const struct ieee80211_rx_stats *rxs, int rssi, int nf) 478190214Srpaulo{ 479190214Srpaulo struct ieee80211vap *vap = ni->ni_vap; 480190214Srpaulo struct ieee80211com *ic = ni->ni_ic; 481190214Srpaulo struct ifnet *ifp = vap->iv_ifp; 482190214Srpaulo struct ieee80211_frame *wh; 483190214Srpaulo struct ieee80211_key *key; 484190214Srpaulo struct ether_header *eh; 485190214Srpaulo int hdrspace, need_tap = 1; /* mbuf need to be tapped. */ 486190214Srpaulo uint8_t dir, type, subtype, qos; 487190214Srpaulo uint8_t *bssid; 488190214Srpaulo 489190214Srpaulo if (m->m_flags & M_AMPDU_MPDU) { 490190214Srpaulo /* 491190214Srpaulo * Fastpath for A-MPDU reorder q resubmission. Frames 492190214Srpaulo * w/ M_AMPDU_MPDU marked have already passed through 493190214Srpaulo * here but were received out of order and been held on 494190214Srpaulo * the reorder queue. When resubmitted they are marked 495190214Srpaulo * with the M_AMPDU_MPDU flag and we can bypass most of 496190214Srpaulo * the normal processing. 497190214Srpaulo */ 498190214Srpaulo wh = mtod(m, struct ieee80211_frame *); 499190214Srpaulo type = IEEE80211_FC0_TYPE_DATA; 500190214Srpaulo dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 501190214Srpaulo subtype = IEEE80211_FC0_SUBTYPE_QOS; 502190214Srpaulo hdrspace = ieee80211_hdrspace(ic, wh); /* XXX optimize? */ 503190214Srpaulo goto resubmit_ampdu; 504190214Srpaulo } 505190214Srpaulo 506190214Srpaulo KASSERT(ni != NULL, ("null node")); 507190214Srpaulo ni->ni_inact = ni->ni_inact_reload; 508190214Srpaulo 509190214Srpaulo type = -1; /* undefined */ 510190214Srpaulo 511190214Srpaulo if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { 512190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 513190214Srpaulo ni->ni_macaddr, NULL, 514190214Srpaulo "too short (1): len %u", m->m_pkthdr.len); 515190214Srpaulo vap->iv_stats.is_rx_tooshort++; 516190214Srpaulo goto out; 517190214Srpaulo } 518190214Srpaulo /* 519190214Srpaulo * Bit of a cheat here, we use a pointer for a 3-address 520190214Srpaulo * frame format but don't reference fields past outside 521190214Srpaulo * ieee80211_frame_min w/o first validating the data is 522190214Srpaulo * present. 523190214Srpaulo */ 524190214Srpaulo wh = mtod(m, struct ieee80211_frame *); 525190214Srpaulo 526190214Srpaulo if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 527190214Srpaulo IEEE80211_FC0_VERSION_0) { 528190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 529190214Srpaulo ni->ni_macaddr, NULL, "wrong version, fc %02x:%02x", 530190214Srpaulo wh->i_fc[0], wh->i_fc[1]); 531190214Srpaulo vap->iv_stats.is_rx_badversion++; 532190214Srpaulo goto err; 533190214Srpaulo } 534190214Srpaulo 535190214Srpaulo dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 536190214Srpaulo type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 537190214Srpaulo subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 538190214Srpaulo if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { 539190214Srpaulo if (dir != IEEE80211_FC1_DIR_NODS) 540190214Srpaulo bssid = wh->i_addr1; 541190214Srpaulo else if (type == IEEE80211_FC0_TYPE_CTL) 542190214Srpaulo bssid = wh->i_addr1; 543190214Srpaulo else { 544190214Srpaulo if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { 545190214Srpaulo IEEE80211_DISCARD_MAC(vap, 546190214Srpaulo IEEE80211_MSG_ANY, ni->ni_macaddr, 547190214Srpaulo NULL, "too short (2): len %u", 548190214Srpaulo m->m_pkthdr.len); 549190214Srpaulo vap->iv_stats.is_rx_tooshort++; 550190214Srpaulo goto out; 551190214Srpaulo } 552190214Srpaulo bssid = wh->i_addr3; 553190214Srpaulo } 554190214Srpaulo /* 555190214Srpaulo * Validate the bssid. 556190214Srpaulo */ 557190214Srpaulo if (!(type == IEEE80211_FC0_TYPE_MGT && 558190214Srpaulo subtype == IEEE80211_FC0_SUBTYPE_BEACON) && 559190214Srpaulo !IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) && 560190214Srpaulo !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { 561190214Srpaulo /* not interested in */ 562190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 563190214Srpaulo bssid, NULL, "%s", "not to bss"); 564190214Srpaulo vap->iv_stats.is_rx_wrongbss++; 565190214Srpaulo goto out; 566190214Srpaulo } 567190214Srpaulo 568190214Srpaulo IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); 569190214Srpaulo ni->ni_noise = nf; 570190214Srpaulo if (IEEE80211_HAS_SEQ(type, subtype)) { 571190214Srpaulo uint8_t tid = ieee80211_gettid(wh); 572190214Srpaulo if (IEEE80211_QOS_HAS_SEQ(wh) && 573190214Srpaulo TID_TO_WME_AC(tid) >= WME_AC_VI) 574190214Srpaulo ic->ic_wme.wme_hipri_traffic++; 575190214Srpaulo if (! ieee80211_check_rxseq(ni, wh, bssid)) 576190214Srpaulo goto out; 577190214Srpaulo } 578190214Srpaulo } 579190214Srpaulo 580190214Srpaulo switch (type) { 581190214Srpaulo case IEEE80211_FC0_TYPE_DATA: 582190214Srpaulo hdrspace = ieee80211_hdrspace(ic, wh); 583190214Srpaulo if (m->m_len < hdrspace && 584190214Srpaulo (m = m_pullup(m, hdrspace)) == NULL) { 585190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 586190214Srpaulo ni->ni_macaddr, NULL, 587190214Srpaulo "data too short: expecting %u", hdrspace); 588190214Srpaulo vap->iv_stats.is_rx_tooshort++; 589190214Srpaulo goto out; /* XXX */ 590190214Srpaulo } 591190214Srpaulo if (!(dir == IEEE80211_FC1_DIR_TODS || 592190214Srpaulo (dir == IEEE80211_FC1_DIR_DSTODS && 593190214Srpaulo (vap->iv_flags & IEEE80211_F_DWDS)))) { 594190214Srpaulo if (dir != IEEE80211_FC1_DIR_DSTODS) { 595190214Srpaulo IEEE80211_DISCARD(vap, 596190214Srpaulo IEEE80211_MSG_INPUT, wh, "data", 597190214Srpaulo "incorrect dir 0x%x", dir); 598190214Srpaulo } else { 599190214Srpaulo IEEE80211_DISCARD(vap, 600190214Srpaulo IEEE80211_MSG_INPUT | 601190214Srpaulo IEEE80211_MSG_WDS, wh, 602190214Srpaulo "4-address data", 603241231Sdelphij "%s", "DWDS not enabled"); 604190214Srpaulo } 605190214Srpaulo vap->iv_stats.is_rx_wrongdir++; 606190214Srpaulo goto out; 607190214Srpaulo } 608190214Srpaulo /* check if source STA is associated */ 609190214Srpaulo if (ni == vap->iv_bss) { 610190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 611190214Srpaulo wh, "data", "%s", "unknown src"); 612190214Srpaulo ieee80211_send_error(ni, wh->i_addr2, 613190214Srpaulo IEEE80211_FC0_SUBTYPE_DEAUTH, 614190214Srpaulo IEEE80211_REASON_NOT_AUTHED); 615190214Srpaulo vap->iv_stats.is_rx_notassoc++; 616190214Srpaulo goto err; 617190214Srpaulo } 618190214Srpaulo if (ni->ni_associd == 0) { 619190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 620190214Srpaulo wh, "data", "%s", "unassoc src"); 621190214Srpaulo IEEE80211_SEND_MGMT(ni, 622190214Srpaulo IEEE80211_FC0_SUBTYPE_DISASSOC, 623190214Srpaulo IEEE80211_REASON_NOT_ASSOCED); 624190214Srpaulo vap->iv_stats.is_rx_notassoc++; 625190214Srpaulo goto err; 626190214Srpaulo } 627190214Srpaulo 628190214Srpaulo /* 629190214Srpaulo * Check for power save state change. 630190214Srpaulo * XXX out-of-order A-MPDU frames? 631190214Srpaulo */ 632190214Srpaulo if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^ 633190214Srpaulo (ni->ni_flags & IEEE80211_NODE_PWR_MGT))) 634190214Srpaulo vap->iv_node_ps(ni, 635190214Srpaulo wh->i_fc[1] & IEEE80211_FC1_PWR_MGT); 636190214Srpaulo /* 637190214Srpaulo * For 4-address packets handle WDS discovery 638190214Srpaulo * notifications. Once a WDS link is setup frames 639190214Srpaulo * are just delivered to the WDS vap (see below). 640190214Srpaulo */ 641190214Srpaulo if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap == NULL) { 642190214Srpaulo if (!ieee80211_node_is_authorized(ni)) { 643190214Srpaulo IEEE80211_DISCARD(vap, 644190214Srpaulo IEEE80211_MSG_INPUT | 645190214Srpaulo IEEE80211_MSG_WDS, wh, 646190214Srpaulo "4-address data", 647190214Srpaulo "%s", "unauthorized port"); 648190214Srpaulo vap->iv_stats.is_rx_unauth++; 649190214Srpaulo IEEE80211_NODE_STAT(ni, rx_unauth); 650190214Srpaulo goto err; 651190214Srpaulo } 652190214Srpaulo ieee80211_dwds_discover(ni, m); 653190214Srpaulo return type; 654190214Srpaulo } 655190214Srpaulo 656190214Srpaulo /* 657190214Srpaulo * Handle A-MPDU re-ordering. If the frame is to be 658190214Srpaulo * processed directly then ieee80211_ampdu_reorder 659190214Srpaulo * will return 0; otherwise it has consumed the mbuf 660190214Srpaulo * and we should do nothing more with it. 661190214Srpaulo */ 662190214Srpaulo if ((m->m_flags & M_AMPDU) && 663190214Srpaulo ieee80211_ampdu_reorder(ni, m) != 0) { 664190214Srpaulo m = NULL; 665190214Srpaulo goto out; 666190214Srpaulo } 667190214Srpaulo resubmit_ampdu: 668190214Srpaulo 669190214Srpaulo /* 670190214Srpaulo * Handle privacy requirements. Note that we 671190214Srpaulo * must not be preempted from here until after 672190214Srpaulo * we (potentially) call ieee80211_crypto_demic; 673190214Srpaulo * otherwise we may violate assumptions in the 674190214Srpaulo * crypto cipher modules used to do delayed update 675190214Srpaulo * of replay sequence numbers. 676190214Srpaulo */ 677190214Srpaulo if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 678190214Srpaulo if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { 679190214Srpaulo /* 680190214Srpaulo * Discard encrypted frames when privacy is off. 681190214Srpaulo */ 682190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 683190214Srpaulo wh, "WEP", "%s", "PRIVACY off"); 684190214Srpaulo vap->iv_stats.is_rx_noprivacy++; 685190214Srpaulo IEEE80211_NODE_STAT(ni, rx_noprivacy); 686190214Srpaulo goto out; 687190214Srpaulo } 688190214Srpaulo key = ieee80211_crypto_decap(ni, m, hdrspace); 689190214Srpaulo if (key == NULL) { 690190214Srpaulo /* NB: stats+msgs handled in crypto_decap */ 691190214Srpaulo IEEE80211_NODE_STAT(ni, rx_wepfail); 692190214Srpaulo goto out; 693190214Srpaulo } 694190214Srpaulo wh = mtod(m, struct ieee80211_frame *); 695190214Srpaulo wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED; 696190214Srpaulo } else { 697190214Srpaulo /* XXX M_WEP and IEEE80211_F_PRIVACY */ 698190214Srpaulo key = NULL; 699190214Srpaulo } 700190214Srpaulo 701190214Srpaulo /* 702190214Srpaulo * Save QoS bits for use below--before we strip the header. 703190214Srpaulo */ 704190214Srpaulo if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { 705190214Srpaulo qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? 706190214Srpaulo ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : 707190214Srpaulo ((struct ieee80211_qosframe *)wh)->i_qos[0]; 708190214Srpaulo } else 709190214Srpaulo qos = 0; 710190214Srpaulo 711190214Srpaulo /* 712190214Srpaulo * Next up, any fragmentation. 713190214Srpaulo */ 714190214Srpaulo if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 715190214Srpaulo m = ieee80211_defrag(ni, m, hdrspace); 716190214Srpaulo if (m == NULL) { 717190214Srpaulo /* Fragment dropped or frame not complete yet */ 718190214Srpaulo goto out; 719190214Srpaulo } 720190214Srpaulo } 721190214Srpaulo wh = NULL; /* no longer valid, catch any uses */ 722190214Srpaulo 723190214Srpaulo /* 724190214Srpaulo * Next strip any MSDU crypto bits. 725190214Srpaulo */ 726190214Srpaulo if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) { 727190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 728190214Srpaulo ni->ni_macaddr, "data", "%s", "demic error"); 729190214Srpaulo vap->iv_stats.is_rx_demicfail++; 730190214Srpaulo IEEE80211_NODE_STAT(ni, rx_demicfail); 731190214Srpaulo goto out; 732190214Srpaulo } 733190214Srpaulo /* copy to listener after decrypt */ 734190214Srpaulo if (ieee80211_radiotap_active_vap(vap)) 735190214Srpaulo ieee80211_radiotap_rx(vap, m); 736190214Srpaulo need_tap = 0; 737190214Srpaulo /* 738190214Srpaulo * Finally, strip the 802.11 header. 739190214Srpaulo */ 740190214Srpaulo m = ieee80211_decap(vap, m, hdrspace); 741190214Srpaulo if (m == NULL) { 742190214Srpaulo /* XXX mask bit to check for both */ 743190214Srpaulo /* don't count Null data frames as errors */ 744190214Srpaulo if (subtype == IEEE80211_FC0_SUBTYPE_NODATA || 745190214Srpaulo subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) 746190214Srpaulo goto out; 747190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 748190214Srpaulo ni->ni_macaddr, "data", "%s", "decap error"); 749190214Srpaulo vap->iv_stats.is_rx_decap++; 750190214Srpaulo IEEE80211_NODE_STAT(ni, rx_decap); 751190214Srpaulo goto err; 752190214Srpaulo } 753190214Srpaulo eh = mtod(m, struct ether_header *); 754190214Srpaulo if (!ieee80211_node_is_authorized(ni)) { 755190214Srpaulo /* 756190214Srpaulo * Deny any non-PAE frames received prior to 757190214Srpaulo * authorization. For open/shared-key 758190214Srpaulo * authentication the port is mark authorized 759190214Srpaulo * after authentication completes. For 802.1x 760190214Srpaulo * the port is not marked authorized by the 761190214Srpaulo * authenticator until the handshake has completed. 762190214Srpaulo */ 763190214Srpaulo if (eh->ether_type != htons(ETHERTYPE_PAE)) { 764190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 765190214Srpaulo eh->ether_shost, "data", 766190214Srpaulo "unauthorized port: ether type 0x%x len %u", 767190214Srpaulo eh->ether_type, m->m_pkthdr.len); 768190214Srpaulo vap->iv_stats.is_rx_unauth++; 769190214Srpaulo IEEE80211_NODE_STAT(ni, rx_unauth); 770190214Srpaulo goto err; 771190214Srpaulo } 772190214Srpaulo } else { 773190214Srpaulo /* 774190214Srpaulo * When denying unencrypted frames, discard 775190214Srpaulo * any non-PAE frames received without encryption. 776190214Srpaulo */ 777235426Sdelphij if ((vap->iv_flags & IEEE80211_F_DROPUNENC) && 778235426Sdelphij (key == NULL && (m->m_flags & M_WEP) == 0) && 779190214Srpaulo eh->ether_type != htons(ETHERTYPE_PAE)) { 780190214Srpaulo /* 781190214Srpaulo * Drop unencrypted frames. 782190214Srpaulo */ 783190214Srpaulo vap->iv_stats.is_rx_unencrypted++; 784190214Srpaulo IEEE80211_NODE_STAT(ni, rx_unencrypted); 785190214Srpaulo goto out; 786190214Srpaulo } 787190214Srpaulo } 788190214Srpaulo /* XXX require HT? */ 789190214Srpaulo if (qos & IEEE80211_QOS_AMSDU) { 790190214Srpaulo m = ieee80211_decap_amsdu(ni, m); 791190214Srpaulo if (m == NULL) 792190214Srpaulo return IEEE80211_FC0_TYPE_DATA; 793190214Srpaulo } else { 794190214Srpaulo#ifdef IEEE80211_SUPPORT_SUPERG 795190214Srpaulo m = ieee80211_decap_fastframe(vap, ni, m); 796190214Srpaulo if (m == NULL) 797190214Srpaulo return IEEE80211_FC0_TYPE_DATA; 798190214Srpaulo#endif 799190214Srpaulo } 800190214Srpaulo if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap != NULL) 801190214Srpaulo ieee80211_deliver_data(ni->ni_wdsvap, ni, m); 802190214Srpaulo else 803190214Srpaulo hostap_deliver_data(vap, ni, m); 804190214Srpaulo return IEEE80211_FC0_TYPE_DATA; 805190214Srpaulo 806190214Srpaulo case IEEE80211_FC0_TYPE_MGT: 807190214Srpaulo vap->iv_stats.is_rx_mgmt++; 808190214Srpaulo IEEE80211_NODE_STAT(ni, rx_mgmt); 809190214Srpaulo if (dir != IEEE80211_FC1_DIR_NODS) { 810190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 811190214Srpaulo wh, "mgt", "incorrect dir 0x%x", dir); 812190214Srpaulo vap->iv_stats.is_rx_wrongdir++; 813190214Srpaulo goto err; 814190214Srpaulo } 815190214Srpaulo if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { 816190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 817190214Srpaulo ni->ni_macaddr, "mgt", "too short: len %u", 818190214Srpaulo m->m_pkthdr.len); 819190214Srpaulo vap->iv_stats.is_rx_tooshort++; 820190214Srpaulo goto out; 821190214Srpaulo } 822190214Srpaulo if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { 823190214Srpaulo /* ensure return frames are unicast */ 824190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 825190214Srpaulo wh, NULL, "source is multicast: %s", 826190214Srpaulo ether_sprintf(wh->i_addr2)); 827190214Srpaulo vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */ 828190214Srpaulo goto out; 829190214Srpaulo } 830190214Srpaulo#ifdef IEEE80211_DEBUG 831190214Srpaulo if ((ieee80211_msg_debug(vap) && doprint(vap, subtype)) || 832190214Srpaulo ieee80211_msg_dumppkts(vap)) { 833190214Srpaulo if_printf(ifp, "received %s from %s rssi %d\n", 834190214Srpaulo ieee80211_mgt_subtype_name[subtype >> 835190214Srpaulo IEEE80211_FC0_SUBTYPE_SHIFT], 836190214Srpaulo ether_sprintf(wh->i_addr2), rssi); 837190214Srpaulo } 838190214Srpaulo#endif 839190214Srpaulo if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 840190214Srpaulo if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) { 841190214Srpaulo /* 842190214Srpaulo * Only shared key auth frames with a challenge 843190214Srpaulo * should be encrypted, discard all others. 844190214Srpaulo */ 845190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 846190214Srpaulo wh, NULL, 847190214Srpaulo "%s", "WEP set but not permitted"); 848190214Srpaulo vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ 849190214Srpaulo goto out; 850190214Srpaulo } 851190214Srpaulo if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { 852190214Srpaulo /* 853190214Srpaulo * Discard encrypted frames when privacy is off. 854190214Srpaulo */ 855190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 856190214Srpaulo wh, NULL, "%s", "WEP set but PRIVACY off"); 857190214Srpaulo vap->iv_stats.is_rx_noprivacy++; 858190214Srpaulo goto out; 859190214Srpaulo } 860190214Srpaulo hdrspace = ieee80211_hdrspace(ic, wh); 861190214Srpaulo key = ieee80211_crypto_decap(ni, m, hdrspace); 862190214Srpaulo if (key == NULL) { 863190214Srpaulo /* NB: stats+msgs handled in crypto_decap */ 864190214Srpaulo goto out; 865190214Srpaulo } 866190214Srpaulo wh = mtod(m, struct ieee80211_frame *); 867190214Srpaulo wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED; 868190214Srpaulo } 869190214Srpaulo /* 870190214Srpaulo * Pass the packet to radiotap before calling iv_recv_mgmt(). 871190214Srpaulo * Otherwise iv_recv_mgmt() might pass another packet to 872190214Srpaulo * radiotap, resulting in out of order packet captures. 873190214Srpaulo */ 874190214Srpaulo if (ieee80211_radiotap_active_vap(vap)) 875190214Srpaulo ieee80211_radiotap_rx(vap, m); 876190214Srpaulo need_tap = 0; 877190214Srpaulo vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf); 878190214Srpaulo goto out; 879190214Srpaulo 880190214Srpaulo case IEEE80211_FC0_TYPE_CTL: 881190214Srpaulo vap->iv_stats.is_rx_ctl++; 882190214Srpaulo IEEE80211_NODE_STAT(ni, rx_ctrl); 883190214Srpaulo vap->iv_recv_ctl(ni, m, subtype); 884190214Srpaulo goto out; 885190214Srpaulo default: 886190214Srpaulo IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 887190214Srpaulo wh, "bad", "frame type 0x%x", type); 888190214Srpaulo /* should not come here */ 889190214Srpaulo break; 890190214Srpaulo } 891190214Srpauloerr: 892190214Srpaulo if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 893190214Srpauloout: 894190214Srpaulo if (m != NULL) { 895190214Srpaulo if (need_tap && ieee80211_radiotap_active_vap(vap)) 896190214Srpaulo ieee80211_radiotap_rx(vap, m); 897190214Srpaulo m_freem(m); 898190214Srpaulo } 899190214Srpaulo return type; 900190214Srpaulo} 901190214Srpaulo 902190214Srpaulostatic void 903214518Srpaulohostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, 904214518Srpaulo int rssi, int nf, uint16_t seq, uint16_t status) 905214518Srpaulo{ 906214518Srpaulo struct ieee80211vap *vap = ni->ni_vap; 907214518Srpaulo 908214518Srpaulo KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); 909214518Srpaulo 910190214Srpaulo if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { 911190214Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 912214518Srpaulo ni->ni_macaddr, "open auth", 913214518Srpaulo "bad sta auth mode %u", ni->ni_authmode); 914214518Srpaulo vap->iv_stats.is_rx_bad_auth++; /* XXX */ 915214518Srpaulo /* 916214518Srpaulo * Clear any challenge text that may be there if 917214518Srpaulo * a previous shared key auth failed and then an 918214518Srpaulo * open auth is attempted. 919214518Srpaulo */ 920214518Srpaulo if (ni->ni_challenge != NULL) { 921214518Srpaulo IEEE80211_FREE(ni->ni_challenge, M_80211_NODE); 922214518Srpaulo ni->ni_challenge = NULL; 923214518Srpaulo } 924214518Srpaulo /* XXX hack to workaround calling convention */ 925214518Srpaulo ieee80211_send_error(ni, wh->i_addr2, 926214518Srpaulo IEEE80211_FC0_SUBTYPE_AUTH, 927214518Srpaulo (seq + 1) | (IEEE80211_STATUS_ALG<<16)); 928214518Srpaulo return; 929214518Srpaulo } 930214518Srpaulo if (seq != IEEE80211_AUTH_OPEN_REQUEST) { 931214518Srpaulo vap->iv_stats.is_rx_bad_auth++; 932214518Srpaulo return; 933214518Srpaulo } 934214518Srpaulo /* always accept open authentication requests */ 935214518Srpaulo if (ni == vap->iv_bss) { 936214518Srpaulo ni = ieee80211_dup_bss(vap, wh->i_addr2); 937214518Srpaulo if (ni == NULL) 938214518Srpaulo return; 939214518Srpaulo } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 940214518Srpaulo (void) ieee80211_ref_node(ni); 941214518Srpaulo /* 942214518Srpaulo * Mark the node as referenced to reflect that it's 943214518Srpaulo * reference count has been bumped to insure it remains 944214518Srpaulo * after the transaction completes. 945214518Srpaulo */ 946214518Srpaulo ni->ni_flags |= IEEE80211_NODE_AREF; 947214518Srpaulo /* 948214518Srpaulo * Mark the node as requiring a valid association id 949214518Srpaulo * before outbound traffic is permitted. 950214518Srpaulo */ 951214518Srpaulo ni->ni_flags |= IEEE80211_NODE_ASSOCID; 952214518Srpaulo 953214518Srpaulo if (vap->iv_acl != NULL && 954214518Srpaulo vap->iv_acl->iac_getpolicy(vap) == IEEE80211_MACCMD_POLICY_RADIUS) { 955214518Srpaulo /* 956214518Srpaulo * When the ACL policy is set to RADIUS we defer the 957214518Srpaulo * authorization to a user agent. Dispatch an event, 958214518Srpaulo * a subsequent MLME call will decide the fate of the 959214518Srpaulo * station. If the user agent is not present then the 960214518Srpaulo * node will be reclaimed due to inactivity. 961214518Srpaulo */ 962214518Srpaulo IEEE80211_NOTE_MAC(vap, 963214518Srpaulo IEEE80211_MSG_AUTH | IEEE80211_MSG_ACL, ni->ni_macaddr, 964214518Srpaulo "%s", "station authentication defered (radius acl)"); 965214518Srpaulo ieee80211_notify_node_auth(ni); 966214518Srpaulo } else { 967214518Srpaulo IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 968214518Srpaulo IEEE80211_NOTE_MAC(vap, 969214518Srpaulo IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, ni->ni_macaddr, 970214518Srpaulo "%s", "station authenticated (open)"); 971214518Srpaulo /* 972214518Srpaulo * When 802.1x is not in use mark the port 973214518Srpaulo * authorized at this point so traffic can flow. 974214518Srpaulo */ 975214518Srpaulo if (ni->ni_authmode != IEEE80211_AUTH_8021X) 976214518Srpaulo ieee80211_node_authorize(ni); 977214518Srpaulo } 978214518Srpaulo} 979214518Srpaulo 980214518Srpaulostatic void 981214518Srpaulohostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, 982214518Srpaulo uint8_t *frm, uint8_t *efrm, int rssi, int nf, 983214518Srpaulo uint16_t seq, uint16_t status) 984214518Srpaulo{ 985214518Srpaulo struct ieee80211vap *vap = ni->ni_vap; 986214518Srpaulo uint8_t *challenge; 987214518Srpaulo int allocbs, estatus; 988214518Srpaulo 989214518Srpaulo KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); 990214518Srpaulo 991214518Srpaulo /* 992214518Srpaulo * NB: this can happen as we allow pre-shared key 993214518Srpaulo * authentication to be enabled w/o wep being turned 994214518Srpaulo * on so that configuration of these can be done 995214518Srpaulo * in any order. It may be better to enforce the 996214518Srpaulo * ordering in which case this check would just be 997214518Srpaulo * for sanity/consistency. 998214518Srpaulo */ 999214518Srpaulo if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { 1000214518Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1001214518Srpaulo ni->ni_macaddr, "shared key auth", 1002214518Srpaulo "%s", " PRIVACY is disabled"); 1003214518Srpaulo estatus = IEEE80211_STATUS_ALG; 1004214518Srpaulo goto bad; 1005214518Srpaulo } 1006214518Srpaulo /* 1007214518Srpaulo * Pre-shared key authentication is evil; accept 1008214518Srpaulo * it only if explicitly configured (it is supported 1009214518Srpaulo * mainly for compatibility with clients like Mac OS X). 1010214518Srpaulo */ 1011214518Srpaulo if (ni->ni_authmode != IEEE80211_AUTH_AUTO && 1012214518Srpaulo ni->ni_authmode != IEEE80211_AUTH_SHARED) { 1013214518Srpaulo IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1014214518Srpaulo ni->ni_macaddr, "shared key auth", 1015214518Srpaulo "bad sta auth mode %u", ni->ni_authmode); 1016214518Srpaulo vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ 1017214518Srpaulo estatus = IEEE80211_STATUS_ALG; 1018214518Srpaulo goto bad; 1019214518Srpaulo } 1020214518Srpaulo 1021214518Srpaulo challenge = NULL; 1022214518Srpaulo if (frm + 1 < efrm) { 1023214518Srpaulo if ((frm[1] + 2) > (efrm - frm)) { 1024235426Sdelphij IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1025214518Srpaulo ni->ni_macaddr, "shared key auth", 1026214518Srpaulo "ie %d/%d too long", 1027214518Srpaulo frm[0], (frm[1] + 2) - (efrm - frm)); 1028214518Srpaulo vap->iv_stats.is_rx_bad_auth++; 1029214518Srpaulo estatus = IEEE80211_STATUS_CHALLENGE; 1030214518Srpaulo goto bad; 1031214518Srpaulo } 1032214518Srpaulo if (*frm == IEEE80211_ELEMID_CHALLENGE) 1033235426Sdelphij challenge = frm; 1034214518Srpaulo frm += frm[1] + 2; 1035214518Srpaulo } 1036214518Srpaulo switch (seq) { 1037214518Srpaulo case IEEE80211_AUTH_SHARED_CHALLENGE: 1038214518Srpaulo case IEEE80211_AUTH_SHARED_RESPONSE: 1039235426Sdelphij if (challenge == NULL) { 1040235426Sdelphij IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1041214518Srpaulo ni->ni_macaddr, "shared key auth", 1042214518Srpaulo "%s", "no challenge"); 1043235426Sdelphij vap->iv_stats.is_rx_bad_auth++; 1044235426Sdelphij estatus = IEEE80211_STATUS_CHALLENGE; 1045235426Sdelphij goto bad; 1046235426Sdelphij } 1047235426Sdelphij if (challenge[1] != IEEE80211_CHALLENGE_LEN) { 1048235426Sdelphij IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1049235426Sdelphij ni->ni_macaddr, "shared key auth", 1050235426Sdelphij "bad challenge len %d", challenge[1]); 1051235426Sdelphij vap->iv_stats.is_rx_bad_auth++; 1052235426Sdelphij estatus = IEEE80211_STATUS_CHALLENGE; 1053235426Sdelphij goto bad; 1054235426Sdelphij } 1055235426Sdelphij default: 1056235426Sdelphij break; 1057235426Sdelphij } 1058235426Sdelphij switch (seq) { 1059235426Sdelphij case IEEE80211_AUTH_SHARED_REQUEST: 1060235426Sdelphij if (ni == vap->iv_bss) { 1061235426Sdelphij ni = ieee80211_dup_bss(vap, wh->i_addr2); 1062235426Sdelphij if (ni == NULL) { 1063235426Sdelphij /* NB: no way to return an error */ 1064235426Sdelphij return; 1065235426Sdelphij } 1066235426Sdelphij allocbs = 1; 1067235426Sdelphij } else { 1068235426Sdelphij if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 1069235426Sdelphij (void) ieee80211_ref_node(ni); 1070235426Sdelphij allocbs = 0; 1071235426Sdelphij } 1072235426Sdelphij /* 1073235426Sdelphij * Mark the node as referenced to reflect that it's 1074235426Sdelphij * reference count has been bumped to insure it remains 1075235426Sdelphij * after the transaction completes. 1076235426Sdelphij */ 1077235426Sdelphij ni->ni_flags |= IEEE80211_NODE_AREF; 1078235426Sdelphij /* 1079235426Sdelphij * Mark the node as requiring a valid associatio id 1080235426Sdelphij * before outbound traffic is permitted. 1081235426Sdelphij */ 1082235426Sdelphij ni->ni_flags |= IEEE80211_NODE_ASSOCID; 1083235426Sdelphij IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); 1084235426Sdelphij ni->ni_noise = nf; 1085235426Sdelphij if (!ieee80211_alloc_challenge(ni)) { 1086235426Sdelphij /* NB: don't return error so they rexmit */ 1087235426Sdelphij return; 1088235426Sdelphij } 1089235426Sdelphij get_random_bytes(ni->ni_challenge, 1090235426Sdelphij IEEE80211_CHALLENGE_LEN); 1091235426Sdelphij IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1092235426Sdelphij ni, "shared key %sauth request", allocbs ? "" : "re"); 1093235426Sdelphij /* 1094235426Sdelphij * When the ACL policy is set to RADIUS we defer the 1095235426Sdelphij * authorization to a user agent. Dispatch an event, 1096235426Sdelphij * a subsequent MLME call will decide the fate of the 1097235426Sdelphij * station. If the user agent is not present then the 1098235426Sdelphij * node will be reclaimed due to inactivity. 1099235426Sdelphij */ 1100235426Sdelphij if (vap->iv_acl != NULL && 1101235426Sdelphij vap->iv_acl->iac_getpolicy(vap) == IEEE80211_MACCMD_POLICY_RADIUS) { 1102235426Sdelphij IEEE80211_NOTE_MAC(vap, 1103235426Sdelphij IEEE80211_MSG_AUTH | IEEE80211_MSG_ACL, 1104235426Sdelphij ni->ni_macaddr, 1105235426Sdelphij "%s", "station authentication defered (radius acl)"); 1106235426Sdelphij ieee80211_notify_node_auth(ni); 1107235426Sdelphij return; 1108235426Sdelphij } 1109235426Sdelphij break; 1110235426Sdelphij case IEEE80211_AUTH_SHARED_RESPONSE: 1111235426Sdelphij if (ni == vap->iv_bss) { 1112235426Sdelphij IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1113235426Sdelphij ni->ni_macaddr, "shared key response", 1114235426Sdelphij "%s", "unknown station"); 1115235426Sdelphij /* NB: don't send a response */ 1116235426Sdelphij return; 1117235426Sdelphij } 1118235426Sdelphij if (ni->ni_challenge == NULL) { 1119235426Sdelphij IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1120235426Sdelphij ni->ni_macaddr, "shared key response", 1121235426Sdelphij "%s", "no challenge recorded"); 1122235426Sdelphij vap->iv_stats.is_rx_bad_auth++; 1123235426Sdelphij estatus = IEEE80211_STATUS_CHALLENGE; 1124235426Sdelphij goto bad; 1125235426Sdelphij } 1126235426Sdelphij if (memcmp(ni->ni_challenge, &challenge[2], 1127235426Sdelphij challenge[1]) != 0) { 1128235426Sdelphij IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1129235426Sdelphij ni->ni_macaddr, "shared key response", 1130235426Sdelphij "%s", "challenge mismatch"); 1131235426Sdelphij vap->iv_stats.is_rx_auth_fail++; 1132235426Sdelphij estatus = IEEE80211_STATUS_CHALLENGE; 1133235426Sdelphij goto bad; 1134235426Sdelphij } 1135235426Sdelphij IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1136235426Sdelphij ni, "%s", "station authenticated (shared key)"); 1137235426Sdelphij ieee80211_node_authorize(ni); 1138235426Sdelphij break; 1139235426Sdelphij default: 1140235426Sdelphij IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH, 1141235426Sdelphij ni->ni_macaddr, "shared key auth", 1142241231Sdelphij "bad seq %d", seq); 1143241231Sdelphij vap->iv_stats.is_rx_bad_auth++; 1144241231Sdelphij estatus = IEEE80211_STATUS_SEQUENCE; 1145241231Sdelphij goto bad; 1146241231Sdelphij } 1147241231Sdelphij IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); 1148235426Sdelphij return; 1149235426Sdelphijbad: 1150241231Sdelphij /* 1151241231Sdelphij * Send an error response; but only when operating as an AP. 1152241231Sdelphij */ 1153241231Sdelphij /* XXX hack to workaround calling convention */ 1154241231Sdelphij ieee80211_send_error(ni, wh->i_addr2, 1155241231Sdelphij IEEE80211_FC0_SUBTYPE_AUTH, 1156241231Sdelphij (seq + 1) | (estatus<<16)); 1157241231Sdelphij} 1158241231Sdelphij 1159241231Sdelphij/* 1160241231Sdelphij * Convert a WPA cipher selector OUI to an internal 1161241231Sdelphij * cipher algorithm. Where appropriate we also 1162241231Sdelphij * record any key length. 1163241231Sdelphij */ 1164241231Sdelphijstatic int 1165241231Sdelphijwpa_cipher(const uint8_t *sel, uint8_t *keylen) 1166241231Sdelphij{ 1167241231Sdelphij#define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1168241231Sdelphij uint32_t w = LE_READ_4(sel); 1169241231Sdelphij 1170241231Sdelphij switch (w) { 1171241231Sdelphij case WPA_SEL(WPA_CSE_NULL): 1172241231Sdelphij return IEEE80211_CIPHER_NONE; 1173241231Sdelphij case WPA_SEL(WPA_CSE_WEP40): 1174241231Sdelphij if (keylen) 1175241231Sdelphij *keylen = 40 / NBBY; 1176241231Sdelphij return IEEE80211_CIPHER_WEP; 1177241231Sdelphij case WPA_SEL(WPA_CSE_WEP104): 1178241231Sdelphij if (keylen) 1179241231Sdelphij *keylen = 104 / NBBY; 1180241231Sdelphij return IEEE80211_CIPHER_WEP; 1181190214Srpaulo case WPA_SEL(WPA_CSE_TKIP): 1182190214Srpaulo return IEEE80211_CIPHER_TKIP; 1183190214Srpaulo case WPA_SEL(WPA_CSE_CCMP): 1184190214Srpaulo return IEEE80211_CIPHER_AES_CCM; 1185190214Srpaulo } 1186190214Srpaulo return 32; /* NB: so 1<< is discarded */ 1187190214Srpaulo#undef WPA_SEL 1188190214Srpaulo} 1189190214Srpaulo 1190190214Srpaulo/* 1191190214Srpaulo * Convert a WPA key management/authentication algorithm 1192190214Srpaulo * to an internal code. 1193190214Srpaulo */ 1194190214Srpaulostatic int 1195190214Srpaulowpa_keymgmt(const uint8_t *sel) 1196190214Srpaulo{ 1197190214Srpaulo#define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1198190214Srpaulo uint32_t w = LE_READ_4(sel); 1199190214Srpaulo 1200190214Srpaulo switch (w) { 1201190214Srpaulo case WPA_SEL(WPA_ASE_8021X_UNSPEC): 1202190214Srpaulo return WPA_ASE_8021X_UNSPEC; 1203190214Srpaulo case WPA_SEL(WPA_ASE_8021X_PSK): 1204190214Srpaulo return WPA_ASE_8021X_PSK; 1205190214Srpaulo case WPA_SEL(WPA_ASE_NONE): 1206190214Srpaulo return WPA_ASE_NONE; 1207190214Srpaulo } 1208190214Srpaulo return 0; /* NB: so is discarded */ 1209190214Srpaulo#undef WPA_SEL 1210190214Srpaulo} 1211190214Srpaulo 1212190214Srpaulo/* 1213190214Srpaulo * Parse a WPA information element to collect parameters. 1214190214Srpaulo * Note that we do not validate security parameters; that 1215190214Srpaulo * is handled by the authenticator; the parsing done here 1216190214Srpaulo * is just for internal use in making operational decisions. 1217190214Srpaulo */ 1218190214Srpaulostatic int 1219190214Srpauloieee80211_parse_wpa(struct ieee80211vap *vap, const uint8_t *frm, 1220190214Srpaulo struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1221190214Srpaulo{ 1222190214Srpaulo uint8_t len = frm[1]; 1223190214Srpaulo uint32_t w; 1224190214Srpaulo int n; 1225190214Srpaulo 1226190214Srpaulo /* 1227190214Srpaulo * Check the length once for fixed parts: OUI, type, 1228190214Srpaulo * version, mcast cipher, and 2 selector counts. 1229190214Srpaulo * Other, variable-length data, must be checked separately. 1230190214Srpaulo */ 1231190214Srpaulo if ((vap->iv_flags & IEEE80211_F_WPA1) == 0) { 1232190214Srpaulo IEEE80211_DISCARD_IE(vap, 1233190214Srpaulo IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1234190214Srpaulo wh, "WPA", "not WPA, flags 0x%x", vap->iv_flags); 1235190214Srpaulo return IEEE80211_REASON_IE_INVALID; 1236190214Srpaulo } 1237190214Srpaulo if (len < 14) { 1238190214Srpaulo IEEE80211_DISCARD_IE(vap, 1239190214Srpaulo IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1240190214Srpaulo wh, "WPA", "too short, len %u", len); 1241190214Srpaulo return IEEE80211_REASON_IE_INVALID; 1242190214Srpaulo } 1243190214Srpaulo frm += 6, len -= 4; /* NB: len is payload only */ 1244190214Srpaulo /* NB: iswpaoui already validated the OUI and type */ 1245190214Srpaulo w = LE_READ_2(frm); 1246190214Srpaulo if (w != WPA_VERSION) { 1247190214Srpaulo IEEE80211_DISCARD_IE(vap, 1248190214Srpaulo IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1249190214Srpaulo wh, "WPA", "bad version %u", w); 1250190214Srpaulo return IEEE80211_REASON_IE_INVALID; 1251190214Srpaulo } 1252190214Srpaulo frm += 2, len -= 2; 1253190214Srpaulo 1254190214Srpaulo memset(rsn, 0, sizeof(*rsn)); 1255190214Srpaulo 1256190214Srpaulo /* multicast/group cipher */ 1257190214Srpaulo rsn->rsn_mcastcipher = wpa_cipher(frm, &rsn->rsn_mcastkeylen); 1258190214Srpaulo frm += 4, len -= 4; 1259190214Srpaulo 1260190214Srpaulo /* unicast ciphers */ 1261190214Srpaulo n = LE_READ_2(frm); 1262190214Srpaulo frm += 2, len -= 2; 1263190214Srpaulo if (len < n*4+2) { 1264190214Srpaulo IEEE80211_DISCARD_IE(vap, 1265190214Srpaulo IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1266190214Srpaulo wh, "WPA", "ucast cipher data too short; len %u, n %u", 1267190214Srpaulo len, n); 1268190214Srpaulo return IEEE80211_REASON_IE_INVALID; 1269190214Srpaulo } 1270190214Srpaulo w = 0; 1271190214Srpaulo for (; n > 0; n--) { 1272190214Srpaulo w |= 1<<wpa_cipher(frm, &rsn->rsn_ucastkeylen); 1273190214Srpaulo frm += 4, len -= 4; 1274190944Srpaulo } 1275190214Srpaulo if (w & (1<<IEEE80211_CIPHER_TKIP)) 1276190214Srpaulo rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1277190214Srpaulo else 1278190214Srpaulo rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1279190214Srpaulo 1280190214Srpaulo /* key management algorithms */ 1281190214Srpaulo n = LE_READ_2(frm); 1282190214Srpaulo frm += 2, len -= 2; 1283190214Srpaulo if (len < n*4) { 1284190214Srpaulo IEEE80211_DISCARD_IE(vap, 1285190214Srpaulo IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1286190214Srpaulo wh, "WPA", "key mgmt alg data too short; len %u, n %u", 1287190214Srpaulo len, n); 1288190214Srpaulo return IEEE80211_REASON_IE_INVALID; 1289235426Sdelphij } 1290 w = 0; 1291 for (; n > 0; n--) { 1292 w |= wpa_keymgmt(frm); 1293 frm += 4, len -= 4; 1294 } 1295 if (w & WPA_ASE_8021X_UNSPEC) 1296 rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC; 1297 else 1298 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK; 1299 1300 if (len > 2) /* optional capabilities */ 1301 rsn->rsn_caps = LE_READ_2(frm); 1302 1303 return 0; 1304} 1305 1306/* 1307 * Convert an RSN cipher selector OUI to an internal 1308 * cipher algorithm. Where appropriate we also 1309 * record any key length. 1310 */ 1311static int 1312rsn_cipher(const uint8_t *sel, uint8_t *keylen) 1313{ 1314#define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1315 uint32_t w = LE_READ_4(sel); 1316 1317 switch (w) { 1318 case RSN_SEL(RSN_CSE_NULL): 1319 return IEEE80211_CIPHER_NONE; 1320 case RSN_SEL(RSN_CSE_WEP40): 1321 if (keylen) 1322 *keylen = 40 / NBBY; 1323 return IEEE80211_CIPHER_WEP; 1324 case RSN_SEL(RSN_CSE_WEP104): 1325 if (keylen) 1326 *keylen = 104 / NBBY; 1327 return IEEE80211_CIPHER_WEP; 1328 case RSN_SEL(RSN_CSE_TKIP): 1329 return IEEE80211_CIPHER_TKIP; 1330 case RSN_SEL(RSN_CSE_CCMP): 1331 return IEEE80211_CIPHER_AES_CCM; 1332 case RSN_SEL(RSN_CSE_WRAP): 1333 return IEEE80211_CIPHER_AES_OCB; 1334 } 1335 return 32; /* NB: so 1<< is discarded */ 1336#undef WPA_SEL 1337} 1338 1339/* 1340 * Convert an RSN key management/authentication algorithm 1341 * to an internal code. 1342 */ 1343static int 1344rsn_keymgmt(const uint8_t *sel) 1345{ 1346#define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1347 uint32_t w = LE_READ_4(sel); 1348 1349 switch (w) { 1350 case RSN_SEL(RSN_ASE_8021X_UNSPEC): 1351 return RSN_ASE_8021X_UNSPEC; 1352 case RSN_SEL(RSN_ASE_8021X_PSK): 1353 return RSN_ASE_8021X_PSK; 1354 case RSN_SEL(RSN_ASE_NONE): 1355 return RSN_ASE_NONE; 1356 } 1357 return 0; /* NB: so is discarded */ 1358#undef RSN_SEL 1359} 1360 1361/* 1362 * Parse a WPA/RSN information element to collect parameters 1363 * and validate the parameters against what has been 1364 * configured for the system. 1365 */ 1366static int 1367ieee80211_parse_rsn(struct ieee80211vap *vap, const uint8_t *frm, 1368 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1369{ 1370 uint8_t len = frm[1]; 1371 uint32_t w; 1372 int n; 1373 1374 /* 1375 * Check the length once for fixed parts: 1376 * version, mcast cipher, and 2 selector counts. 1377 * Other, variable-length data, must be checked separately. 1378 */ 1379 if ((vap->iv_flags & IEEE80211_F_WPA2) == 0) { 1380 IEEE80211_DISCARD_IE(vap, 1381 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1382 wh, "WPA", "not RSN, flags 0x%x", vap->iv_flags); 1383 return IEEE80211_REASON_IE_INVALID; 1384 } 1385 if (len < 10) { 1386 IEEE80211_DISCARD_IE(vap, 1387 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1388 wh, "RSN", "too short, len %u", len); 1389 return IEEE80211_REASON_IE_INVALID; 1390 } 1391 frm += 2; 1392 w = LE_READ_2(frm); 1393 if (w != RSN_VERSION) { 1394 IEEE80211_DISCARD_IE(vap, 1395 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1396 wh, "RSN", "bad version %u", w); 1397 return IEEE80211_REASON_IE_INVALID; 1398 } 1399 frm += 2, len -= 2; 1400 1401 memset(rsn, 0, sizeof(*rsn)); 1402 1403 /* multicast/group cipher */ 1404 rsn->rsn_mcastcipher = rsn_cipher(frm, &rsn->rsn_mcastkeylen); 1405 frm += 4, len -= 4; 1406 1407 /* unicast ciphers */ 1408 n = LE_READ_2(frm); 1409 frm += 2, len -= 2; 1410 if (len < n*4+2) { 1411 IEEE80211_DISCARD_IE(vap, 1412 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1413 wh, "RSN", "ucast cipher data too short; len %u, n %u", 1414 len, n); 1415 return IEEE80211_REASON_IE_INVALID; 1416 } 1417 w = 0; 1418 for (; n > 0; n--) { 1419 w |= 1<<rsn_cipher(frm, &rsn->rsn_ucastkeylen); 1420 frm += 4, len -= 4; 1421 } 1422 if (w & (1<<IEEE80211_CIPHER_TKIP)) 1423 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1424 else 1425 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1426 1427 /* key management algorithms */ 1428 n = LE_READ_2(frm); 1429 frm += 2, len -= 2; 1430 if (len < n*4) { 1431 IEEE80211_DISCARD_IE(vap, 1432 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1433 wh, "RSN", "key mgmt alg data too short; len %u, n %u", 1434 len, n); 1435 return IEEE80211_REASON_IE_INVALID; 1436 } 1437 w = 0; 1438 for (; n > 0; n--) { 1439 w |= rsn_keymgmt(frm); 1440 frm += 4, len -= 4; 1441 } 1442 if (w & RSN_ASE_8021X_UNSPEC) 1443 rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC; 1444 else 1445 rsn->rsn_keymgmt = RSN_ASE_8021X_PSK; 1446 1447 /* optional RSN capabilities */ 1448 if (len > 2) 1449 rsn->rsn_caps = LE_READ_2(frm); 1450 /* XXXPMKID */ 1451 1452 return 0; 1453} 1454 1455/* 1456 * WPA/802.11i assocation request processing. 1457 */ 1458static int 1459wpa_assocreq(struct ieee80211_node *ni, struct ieee80211_rsnparms *rsnparms, 1460 const struct ieee80211_frame *wh, const uint8_t *wpa, 1461 const uint8_t *rsn, uint16_t capinfo) 1462{ 1463 struct ieee80211vap *vap = ni->ni_vap; 1464 uint8_t reason; 1465 int badwparsn; 1466 1467 ni->ni_flags &= ~(IEEE80211_NODE_WPS|IEEE80211_NODE_TSN); 1468 if (wpa == NULL && rsn == NULL) { 1469 if (vap->iv_flags_ext & IEEE80211_FEXT_WPS) { 1470 /* 1471 * W-Fi Protected Setup (WPS) permits 1472 * clients to associate and pass EAPOL frames 1473 * to establish initial credentials. 1474 */ 1475 ni->ni_flags |= IEEE80211_NODE_WPS; 1476 return 1; 1477 } 1478 if ((vap->iv_flags_ext & IEEE80211_FEXT_TSN) && 1479 (capinfo & IEEE80211_CAPINFO_PRIVACY)) { 1480 /* 1481 * Transitional Security Network. Permits clients 1482 * to associate and use WEP while WPA is configured. 1483 */ 1484 ni->ni_flags |= IEEE80211_NODE_TSN; 1485 return 1; 1486 } 1487 IEEE80211_DISCARD(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 1488 wh, NULL, "%s", "no WPA/RSN IE in association request"); 1489 vap->iv_stats.is_rx_assoc_badwpaie++; 1490 reason = IEEE80211_REASON_IE_INVALID; 1491 goto bad; 1492 } 1493 /* assert right association security credentials */ 1494 badwparsn = 0; /* NB: to silence compiler */ 1495 switch (vap->iv_flags & IEEE80211_F_WPA) { 1496 case IEEE80211_F_WPA1: 1497 badwparsn = (wpa == NULL); 1498 break; 1499 case IEEE80211_F_WPA2: 1500 badwparsn = (rsn == NULL); 1501 break; 1502 case IEEE80211_F_WPA1|IEEE80211_F_WPA2: 1503 badwparsn = (wpa == NULL && rsn == NULL); 1504 break; 1505 } 1506 if (badwparsn) { 1507 IEEE80211_DISCARD(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 1508 wh, NULL, 1509 "%s", "missing WPA/RSN IE in association request"); 1510 vap->iv_stats.is_rx_assoc_badwpaie++; 1511 reason = IEEE80211_REASON_IE_INVALID; 1512 goto bad; 1513 } 1514 /* 1515 * Parse WPA/RSN information element. 1516 */ 1517 if (wpa != NULL) 1518 reason = ieee80211_parse_wpa(vap, wpa, rsnparms, wh); 1519 else 1520 reason = ieee80211_parse_rsn(vap, rsn, rsnparms, wh); 1521 if (reason != 0) { 1522 /* XXX distinguish WPA/RSN? */ 1523 vap->iv_stats.is_rx_assoc_badwpaie++; 1524 goto bad; 1525 } 1526 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, ni, 1527 "%s ie: mc %u/%u uc %u/%u key %u caps 0x%x", 1528 wpa != NULL ? "WPA" : "RSN", 1529 rsnparms->rsn_mcastcipher, rsnparms->rsn_mcastkeylen, 1530 rsnparms->rsn_ucastcipher, rsnparms->rsn_ucastkeylen, 1531 rsnparms->rsn_keymgmt, rsnparms->rsn_caps); 1532 1533 return 1; 1534bad: 1535 ieee80211_node_deauth(ni, reason); 1536 return 0; 1537} 1538 1539/* XXX find a better place for definition */ 1540struct l2_update_frame { 1541 struct ether_header eh; 1542 uint8_t dsap; 1543 uint8_t ssap; 1544 uint8_t control; 1545 uint8_t xid[3]; 1546} __packed; 1547 1548/* 1549 * Deliver a TGf L2UF frame on behalf of a station. 1550 * This primes any bridge when the station is roaming 1551 * between ap's on the same wired network. 1552 */ 1553static void 1554ieee80211_deliver_l2uf(struct ieee80211_node *ni) 1555{ 1556 struct ieee80211vap *vap = ni->ni_vap; 1557 struct ifnet *ifp = vap->iv_ifp; 1558 struct mbuf *m; 1559 struct l2_update_frame *l2uf; 1560 struct ether_header *eh; 1561 1562 m = m_gethdr(M_NOWAIT, MT_DATA); 1563 if (m == NULL) { 1564 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, 1565 "%s", "no mbuf for l2uf frame"); 1566 vap->iv_stats.is_rx_nobuf++; /* XXX not right */ 1567 return; 1568 } 1569 l2uf = mtod(m, struct l2_update_frame *); 1570 eh = &l2uf->eh; 1571 /* dst: Broadcast address */ 1572 IEEE80211_ADDR_COPY(eh->ether_dhost, ifp->if_broadcastaddr); 1573 /* src: associated STA */ 1574 IEEE80211_ADDR_COPY(eh->ether_shost, ni->ni_macaddr); 1575 eh->ether_type = htons(sizeof(*l2uf) - sizeof(*eh)); 1576 1577 l2uf->dsap = 0; 1578 l2uf->ssap = 0; 1579 l2uf->control = 0xf5; 1580 l2uf->xid[0] = 0x81; 1581 l2uf->xid[1] = 0x80; 1582 l2uf->xid[2] = 0x00; 1583 1584 m->m_pkthdr.len = m->m_len = sizeof(*l2uf); 1585 hostap_deliver_data(vap, ni, m); 1586} 1587 1588static void 1589ratesetmismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh, 1590 int reassoc, int resp, const char *tag, int rate) 1591{ 1592 IEEE80211_NOTE_MAC(ni->ni_vap, IEEE80211_MSG_ANY, wh->i_addr2, 1593 "deny %s request, %s rate set mismatch, rate/MCS %d", 1594 reassoc ? "reassoc" : "assoc", tag, rate & IEEE80211_RATE_VAL); 1595 IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_BASIC_RATE); 1596 ieee80211_node_leave(ni); 1597} 1598 1599static void 1600capinfomismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh, 1601 int reassoc, int resp, const char *tag, int capinfo) 1602{ 1603 struct ieee80211vap *vap = ni->ni_vap; 1604 1605 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, wh->i_addr2, 1606 "deny %s request, %s mismatch 0x%x", 1607 reassoc ? "reassoc" : "assoc", tag, capinfo); 1608 IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_CAPINFO); 1609 ieee80211_node_leave(ni); 1610 vap->iv_stats.is_rx_assoc_capmismatch++; 1611} 1612 1613static void 1614htcapmismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh, 1615 int reassoc, int resp) 1616{ 1617 IEEE80211_NOTE_MAC(ni->ni_vap, IEEE80211_MSG_ANY, wh->i_addr2, 1618 "deny %s request, %s missing HT ie", reassoc ? "reassoc" : "assoc"); 1619 /* XXX no better code */ 1620 IEEE80211_SEND_MGMT(ni, resp, IEEE80211_STATUS_MISSING_HT_CAPS); 1621 ieee80211_node_leave(ni); 1622} 1623 1624static void 1625authalgreject(struct ieee80211_node *ni, const struct ieee80211_frame *wh, 1626 int algo, int seq, int status) 1627{ 1628 struct ieee80211vap *vap = ni->ni_vap; 1629 1630 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 1631 wh, NULL, "unsupported alg %d", algo); 1632 vap->iv_stats.is_rx_auth_unsupported++; 1633 ieee80211_send_error(ni, wh->i_addr2, IEEE80211_FC0_SUBTYPE_AUTH, 1634 seq | (status << 16)); 1635} 1636 1637static __inline int 1638ishtmixed(const uint8_t *ie) 1639{ 1640 const struct ieee80211_ie_htinfo *ht = 1641 (const struct ieee80211_ie_htinfo *) ie; 1642 return (ht->hi_byte2 & IEEE80211_HTINFO_OPMODE) == 1643 IEEE80211_HTINFO_OPMODE_MIXED; 1644} 1645 1646static int 1647is11bclient(const uint8_t *rates, const uint8_t *xrates) 1648{ 1649 static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11); 1650 int i; 1651 1652 /* NB: the 11b clients we care about will not have xrates */ 1653 if (xrates != NULL || rates == NULL) 1654 return 0; 1655 for (i = 0; i < rates[1]; i++) { 1656 int r = rates[2+i] & IEEE80211_RATE_VAL; 1657 if (r > 2*11 || ((1<<r) & brates) == 0) 1658 return 0; 1659 } 1660 return 1; 1661} 1662 1663static void 1664hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, 1665 int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf) 1666{ 1667 struct ieee80211vap *vap = ni->ni_vap; 1668 struct ieee80211com *ic = ni->ni_ic; 1669 struct ieee80211_frame *wh; 1670 uint8_t *frm, *efrm, *sfrm; 1671 uint8_t *ssid, *rates, *xrates, *wpa, *rsn, *wme, *ath, *htcap; 1672 int reassoc, resp; 1673 uint8_t rate; 1674 1675 wh = mtod(m0, struct ieee80211_frame *); 1676 frm = (uint8_t *)&wh[1]; 1677 efrm = mtod(m0, uint8_t *) + m0->m_len; 1678 switch (subtype) { 1679 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 1680 case IEEE80211_FC0_SUBTYPE_BEACON: { 1681 struct ieee80211_scanparams scan; 1682 /* 1683 * We process beacon/probe response frames when scanning; 1684 * otherwise we check beacon frames for overlapping non-ERP 1685 * BSS in 11g and/or overlapping legacy BSS when in HT. 1686 */ 1687 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0 && 1688 subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) { 1689 vap->iv_stats.is_rx_mgtdiscard++; 1690 return; 1691 } 1692 /* NB: accept off-channel frames */ 1693 /* XXX TODO: use rxstatus to determine off-channel details */ 1694 if (ieee80211_parse_beacon(ni, m0, ic->ic_curchan, &scan) &~ IEEE80211_BPARSE_OFFCHAN) 1695 return; 1696 /* 1697 * Count frame now that we know it's to be processed. 1698 */ 1699 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { 1700 vap->iv_stats.is_rx_beacon++; /* XXX remove */ 1701 IEEE80211_NODE_STAT(ni, rx_beacons); 1702 } else 1703 IEEE80211_NODE_STAT(ni, rx_proberesp); 1704 /* 1705 * If scanning, just pass information to the scan module. 1706 */ 1707 if (ic->ic_flags & IEEE80211_F_SCAN) { 1708 if (scan.status == 0 && /* NB: on channel */ 1709 (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN)) { 1710 /* 1711 * Actively scanning a channel marked passive; 1712 * send a probe request now that we know there 1713 * is 802.11 traffic present. 1714 * 1715 * XXX check if the beacon we recv'd gives 1716 * us what we need and suppress the probe req 1717 */ 1718 ieee80211_probe_curchan(vap, 1); 1719 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; 1720 } 1721 ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh, 1722 subtype, rssi, nf); 1723 return; 1724 } 1725 /* 1726 * Check beacon for overlapping bss w/ non ERP stations. 1727 * If we detect one and protection is configured but not 1728 * enabled, enable it and start a timer that'll bring us 1729 * out if we stop seeing the bss. 1730 */ 1731 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && 1732 scan.status == 0 && /* NB: on-channel */ 1733 ((scan.erp & 0x100) == 0 || /* NB: no ERP, 11b sta*/ 1734 (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) { 1735 ic->ic_lastnonerp = ticks; 1736 ic->ic_flags_ext |= IEEE80211_FEXT_NONERP_PR; 1737 if (ic->ic_protmode != IEEE80211_PROT_NONE && 1738 (ic->ic_flags & IEEE80211_F_USEPROT) == 0) { 1739 IEEE80211_NOTE_FRAME(vap, 1740 IEEE80211_MSG_ASSOC, wh, 1741 "non-ERP present on channel %d " 1742 "(saw erp 0x%x from channel %d), " 1743 "enable use of protection", 1744 ic->ic_curchan->ic_ieee, 1745 scan.erp, scan.chan); 1746 ic->ic_flags |= IEEE80211_F_USEPROT; 1747 ieee80211_notify_erp(ic); 1748 } 1749 } 1750 /* 1751 * Check beacon for non-HT station on HT channel 1752 * and update HT BSS occupancy as appropriate. 1753 */ 1754 if (IEEE80211_IS_CHAN_HT(ic->ic_curchan)) { 1755 if (scan.status & IEEE80211_BPARSE_OFFCHAN) { 1756 /* 1757 * Off control channel; only check frames 1758 * that come in the extension channel when 1759 * operating w/ HT40. 1760 */ 1761 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan)) 1762 break; 1763 if (scan.chan != ic->ic_curchan->ic_extieee) 1764 break; 1765 } 1766 if (scan.htinfo == NULL) { 1767 ieee80211_htprot_update(ic, 1768 IEEE80211_HTINFO_OPMODE_PROTOPT | 1769 IEEE80211_HTINFO_NONHT_PRESENT); 1770 } else if (ishtmixed(scan.htinfo)) { 1771 /* XXX? take NONHT_PRESENT from beacon? */ 1772 ieee80211_htprot_update(ic, 1773 IEEE80211_HTINFO_OPMODE_MIXED | 1774 IEEE80211_HTINFO_NONHT_PRESENT); 1775 } 1776 } 1777 break; 1778 } 1779 1780 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 1781 if (vap->iv_state != IEEE80211_S_RUN) { 1782 vap->iv_stats.is_rx_mgtdiscard++; 1783 return; 1784 } 1785 /* 1786 * Consult the ACL policy module if setup. 1787 */ 1788 if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) { 1789 IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, 1790 wh, NULL, "%s", "disallowed by ACL"); 1791 vap->iv_stats.is_rx_acl++; 1792 return; 1793 } 1794 /* 1795 * prreq frame format 1796 * [tlv] ssid 1797 * [tlv] supported rates 1798 * [tlv] extended supported rates 1799 */ 1800 ssid = rates = xrates = NULL; 1801 sfrm = frm; 1802 while (efrm - frm > 1) { 1803 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); 1804 switch (*frm) { 1805 case IEEE80211_ELEMID_SSID: 1806 ssid = frm; 1807 break; 1808 case IEEE80211_ELEMID_RATES: 1809 rates = frm; 1810 break; 1811 case IEEE80211_ELEMID_XRATES: 1812 xrates = frm; 1813 break; 1814 } 1815 frm += frm[1] + 2; 1816 } 1817 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return); 1818 if (xrates != NULL) 1819 IEEE80211_VERIFY_ELEMENT(xrates, 1820 IEEE80211_RATE_MAXSIZE - rates[1], return); 1821 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return); 1822 IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return); 1823 if ((vap->iv_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { 1824 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 1825 wh, NULL, 1826 "%s", "no ssid with ssid suppression enabled"); 1827 vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/ 1828 return; 1829 } 1830 1831 /* XXX find a better class or define it's own */ 1832 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, 1833 "%s", "recv probe req"); 1834 /* 1835 * Some legacy 11b clients cannot hack a complete 1836 * probe response frame. When the request includes 1837 * only a bare-bones rate set, communicate this to 1838 * the transmit side. 1839 */ 1840 ieee80211_send_proberesp(vap, wh->i_addr2, 1841 is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0); 1842 break; 1843 1844 case IEEE80211_FC0_SUBTYPE_AUTH: { 1845 uint16_t algo, seq, status; 1846 1847 if (vap->iv_state != IEEE80211_S_RUN) { 1848 vap->iv_stats.is_rx_mgtdiscard++; 1849 return; 1850 } 1851 if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bss->ni_bssid)) { 1852 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 1853 wh, NULL, "%s", "wrong bssid"); 1854 vap->iv_stats.is_rx_wrongbss++; /*XXX unique stat?*/ 1855 return; 1856 } 1857 /* 1858 * auth frame format 1859 * [2] algorithm 1860 * [2] sequence 1861 * [2] status 1862 * [tlv*] challenge 1863 */ 1864 IEEE80211_VERIFY_LENGTH(efrm - frm, 6, return); 1865 algo = le16toh(*(uint16_t *)frm); 1866 seq = le16toh(*(uint16_t *)(frm + 2)); 1867 status = le16toh(*(uint16_t *)(frm + 4)); 1868 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, 1869 "recv auth frame with algorithm %d seq %d", algo, seq); 1870 /* 1871 * Consult the ACL policy module if setup. 1872 */ 1873 if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) { 1874 IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL, 1875 wh, NULL, "%s", "disallowed by ACL"); 1876 vap->iv_stats.is_rx_acl++; 1877 ieee80211_send_error(ni, wh->i_addr2, 1878 IEEE80211_FC0_SUBTYPE_AUTH, 1879 (seq+1) | (IEEE80211_STATUS_UNSPECIFIED<<16)); 1880 return; 1881 } 1882 if (vap->iv_flags & IEEE80211_F_COUNTERM) { 1883 IEEE80211_DISCARD(vap, 1884 IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO, 1885 wh, NULL, "%s", "TKIP countermeasures enabled"); 1886 vap->iv_stats.is_rx_auth_countermeasures++; 1887 ieee80211_send_error(ni, wh->i_addr2, 1888 IEEE80211_FC0_SUBTYPE_AUTH, 1889 IEEE80211_REASON_MIC_FAILURE); 1890 return; 1891 } 1892 if (algo == IEEE80211_AUTH_ALG_SHARED) 1893 hostap_auth_shared(ni, wh, frm + 6, efrm, rssi, nf, 1894 seq, status); 1895 else if (algo == IEEE80211_AUTH_ALG_OPEN) 1896 hostap_auth_open(ni, wh, rssi, nf, seq, status); 1897 else if (algo == IEEE80211_AUTH_ALG_LEAP) { 1898 authalgreject(ni, wh, algo, 1899 seq+1, IEEE80211_STATUS_ALG); 1900 return; 1901 } else { 1902 /* 1903 * We assume that an unknown algorithm is the result 1904 * of a decryption failure on a shared key auth frame; 1905 * return a status code appropriate for that instead 1906 * of IEEE80211_STATUS_ALG. 1907 * 1908 * NB: a seq# of 4 is intentional; the decrypted 1909 * frame likely has a bogus seq value. 1910 */ 1911 authalgreject(ni, wh, algo, 1912 4, IEEE80211_STATUS_CHALLENGE); 1913 return; 1914 } 1915 break; 1916 } 1917 1918 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 1919 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: { 1920 uint16_t capinfo, lintval; 1921 struct ieee80211_rsnparms rsnparms; 1922 1923 if (vap->iv_state != IEEE80211_S_RUN) { 1924 vap->iv_stats.is_rx_mgtdiscard++; 1925 return; 1926 } 1927 if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bss->ni_bssid)) { 1928 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 1929 wh, NULL, "%s", "wrong bssid"); 1930 vap->iv_stats.is_rx_assoc_bss++; 1931 return; 1932 } 1933 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 1934 reassoc = 1; 1935 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 1936 } else { 1937 reassoc = 0; 1938 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 1939 } 1940 if (ni == vap->iv_bss) { 1941 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, wh->i_addr2, 1942 "deny %s request, sta not authenticated", 1943 reassoc ? "reassoc" : "assoc"); 1944 ieee80211_send_error(ni, wh->i_addr2, 1945 IEEE80211_FC0_SUBTYPE_DEAUTH, 1946 IEEE80211_REASON_ASSOC_NOT_AUTHED); 1947 vap->iv_stats.is_rx_assoc_notauth++; 1948 return; 1949 } 1950 1951 /* 1952 * asreq frame format 1953 * [2] capability information 1954 * [2] listen interval 1955 * [6*] current AP address (reassoc only) 1956 * [tlv] ssid 1957 * [tlv] supported rates 1958 * [tlv] extended supported rates 1959 * [tlv] WPA or RSN 1960 * [tlv] HT capabilities 1961 * [tlv] Atheros capabilities 1962 */ 1963 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4), return); 1964 capinfo = le16toh(*(uint16_t *)frm); frm += 2; 1965 lintval = le16toh(*(uint16_t *)frm); frm += 2; 1966 if (reassoc) 1967 frm += 6; /* ignore current AP info */ 1968 ssid = rates = xrates = wpa = rsn = wme = ath = htcap = NULL; 1969 sfrm = frm; 1970 while (efrm - frm > 1) { 1971 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); 1972 switch (*frm) { 1973 case IEEE80211_ELEMID_SSID: 1974 ssid = frm; 1975 break; 1976 case IEEE80211_ELEMID_RATES: 1977 rates = frm; 1978 break; 1979 case IEEE80211_ELEMID_XRATES: 1980 xrates = frm; 1981 break; 1982 case IEEE80211_ELEMID_RSN: 1983 rsn = frm; 1984 break; 1985 case IEEE80211_ELEMID_HTCAP: 1986 htcap = frm; 1987 break; 1988 case IEEE80211_ELEMID_VENDOR: 1989 if (iswpaoui(frm)) 1990 wpa = frm; 1991 else if (iswmeinfo(frm)) 1992 wme = frm; 1993#ifdef IEEE80211_SUPPORT_SUPERG 1994 else if (isatherosoui(frm)) 1995 ath = frm; 1996#endif 1997 else if (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) { 1998 if (ishtcapoui(frm) && htcap == NULL) 1999 htcap = frm; 2000 } 2001 break; 2002 } 2003 frm += frm[1] + 2; 2004 } 2005 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return); 2006 if (xrates != NULL) 2007 IEEE80211_VERIFY_ELEMENT(xrates, 2008 IEEE80211_RATE_MAXSIZE - rates[1], return); 2009 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return); 2010 IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return); 2011 if (htcap != NULL) { 2012 IEEE80211_VERIFY_LENGTH(htcap[1], 2013 htcap[0] == IEEE80211_ELEMID_VENDOR ? 2014 4 + sizeof(struct ieee80211_ie_htcap)-2 : 2015 sizeof(struct ieee80211_ie_htcap)-2, 2016 return); /* XXX just NULL out? */ 2017 } 2018 2019 if ((vap->iv_flags & IEEE80211_F_WPA) && 2020 !wpa_assocreq(ni, &rsnparms, wh, wpa, rsn, capinfo)) 2021 return; 2022 /* discard challenge after association */ 2023 if (ni->ni_challenge != NULL) { 2024 IEEE80211_FREE(ni->ni_challenge, M_80211_NODE); 2025 ni->ni_challenge = NULL; 2026 } 2027 /* NB: 802.11 spec says to ignore station's privacy bit */ 2028 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0) { 2029 capinfomismatch(ni, wh, reassoc, resp, 2030 "capability", capinfo); 2031 return; 2032 } 2033 /* 2034 * Disallow re-associate w/ invalid slot time setting. 2035 */ 2036 if (ni->ni_associd != 0 && 2037 IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan) && 2038 ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME)) { 2039 capinfomismatch(ni, wh, reassoc, resp, 2040 "slot time", capinfo); 2041 return; 2042 } 2043 rate = ieee80211_setup_rates(ni, rates, xrates, 2044 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 2045 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 2046 if (rate & IEEE80211_RATE_BASIC) { 2047 ratesetmismatch(ni, wh, reassoc, resp, "legacy", rate); 2048 vap->iv_stats.is_rx_assoc_norate++; 2049 return; 2050 } 2051 /* 2052 * If constrained to 11g-only stations reject an 2053 * 11b-only station. We cheat a bit here by looking 2054 * at the max negotiated xmit rate and assuming anyone 2055 * with a best rate <24Mb/s is an 11b station. 2056 */ 2057 if ((vap->iv_flags & IEEE80211_F_PUREG) && rate < 48) { 2058 ratesetmismatch(ni, wh, reassoc, resp, "11g", rate); 2059 vap->iv_stats.is_rx_assoc_norate++; 2060 return; 2061 } 2062 /* 2063 * Do HT rate set handling and setup HT node state. 2064 */ 2065 ni->ni_chan = vap->iv_bss->ni_chan; 2066 if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && htcap != NULL) { 2067 rate = ieee80211_setup_htrates(ni, htcap, 2068 IEEE80211_F_DOFMCS | IEEE80211_F_DONEGO | 2069 IEEE80211_F_DOBRS); 2070 if (rate & IEEE80211_RATE_BASIC) { 2071 ratesetmismatch(ni, wh, reassoc, resp, 2072 "HT", rate); 2073 vap->iv_stats.is_ht_assoc_norate++; 2074 return; 2075 } 2076 ieee80211_ht_node_init(ni); 2077 ieee80211_ht_updatehtcap(ni, htcap); 2078 } else if (ni->ni_flags & IEEE80211_NODE_HT) 2079 ieee80211_ht_node_cleanup(ni); 2080#ifdef IEEE80211_SUPPORT_SUPERG 2081 /* Always do ff node cleanup; for A-MSDU */ 2082 ieee80211_ff_node_cleanup(ni); 2083#endif 2084 /* 2085 * Allow AMPDU operation only with unencrypted traffic 2086 * or AES-CCM; the 11n spec only specifies these ciphers 2087 * so permitting any others is undefined and can lead 2088 * to interoperability problems. 2089 */ 2090 if ((ni->ni_flags & IEEE80211_NODE_HT) && 2091 (((vap->iv_flags & IEEE80211_F_WPA) && 2092 rsnparms.rsn_ucastcipher != IEEE80211_CIPHER_AES_CCM) || 2093 (vap->iv_flags & (IEEE80211_F_WPA|IEEE80211_F_PRIVACY)) == IEEE80211_F_PRIVACY)) { 2094 IEEE80211_NOTE(vap, 2095 IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, ni, 2096 "disallow HT use because WEP or TKIP requested, " 2097 "capinfo 0x%x ucastcipher %d", capinfo, 2098 rsnparms.rsn_ucastcipher); 2099 ieee80211_ht_node_cleanup(ni); 2100#ifdef IEEE80211_SUPPORT_SUPERG 2101 /* Always do ff node cleanup; for A-MSDU */ 2102 ieee80211_ff_node_cleanup(ni); 2103#endif 2104 vap->iv_stats.is_ht_assoc_downgrade++; 2105 } 2106 /* 2107 * If constrained to 11n-only stations reject legacy stations. 2108 */ 2109 if ((vap->iv_flags_ht & IEEE80211_FHT_PUREN) && 2110 (ni->ni_flags & IEEE80211_NODE_HT) == 0) { 2111 htcapmismatch(ni, wh, reassoc, resp); 2112 vap->iv_stats.is_ht_assoc_nohtcap++; 2113 return; 2114 } 2115 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); 2116 ni->ni_noise = nf; 2117 ni->ni_intval = lintval; 2118 ni->ni_capinfo = capinfo; 2119 ni->ni_fhdwell = vap->iv_bss->ni_fhdwell; 2120 ni->ni_fhindex = vap->iv_bss->ni_fhindex; 2121 /* 2122 * Store the IEs. 2123 * XXX maybe better to just expand 2124 */ 2125 if (ieee80211_ies_init(&ni->ni_ies, sfrm, efrm - sfrm)) { 2126#define setie(_ie, _off) ieee80211_ies_setie(ni->ni_ies, _ie, _off) 2127 if (wpa != NULL) 2128 setie(wpa_ie, wpa - sfrm); 2129 if (rsn != NULL) 2130 setie(rsn_ie, rsn - sfrm); 2131 if (htcap != NULL) 2132 setie(htcap_ie, htcap - sfrm); 2133 if (wme != NULL) { 2134 setie(wme_ie, wme - sfrm); 2135 /* 2136 * Mark node as capable of QoS. 2137 */ 2138 ni->ni_flags |= IEEE80211_NODE_QOS; 2139 } else 2140 ni->ni_flags &= ~IEEE80211_NODE_QOS; 2141#ifdef IEEE80211_SUPPORT_SUPERG 2142 if (ath != NULL) { 2143 setie(ath_ie, ath - sfrm); 2144 /* 2145 * Parse ATH station parameters. 2146 */ 2147 ieee80211_parse_ath(ni, ni->ni_ies.ath_ie); 2148 } else 2149#endif 2150 ni->ni_ath_flags = 0; 2151#undef setie 2152 } else { 2153 ni->ni_flags &= ~IEEE80211_NODE_QOS; 2154 ni->ni_ath_flags = 0; 2155 } 2156 ieee80211_node_join(ni, resp); 2157 ieee80211_deliver_l2uf(ni); 2158 break; 2159 } 2160 2161 case IEEE80211_FC0_SUBTYPE_DEAUTH: 2162 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 2163 uint16_t reason; 2164 2165 if (vap->iv_state != IEEE80211_S_RUN || 2166 /* NB: can happen when in promiscuous mode */ 2167 !IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) { 2168 vap->iv_stats.is_rx_mgtdiscard++; 2169 break; 2170 } 2171 /* 2172 * deauth/disassoc frame format 2173 * [2] reason 2174 */ 2175 IEEE80211_VERIFY_LENGTH(efrm - frm, 2, return); 2176 reason = le16toh(*(uint16_t *)frm); 2177 if (subtype == IEEE80211_FC0_SUBTYPE_DEAUTH) { 2178 vap->iv_stats.is_rx_deauth++; 2179 IEEE80211_NODE_STAT(ni, rx_deauth); 2180 } else { 2181 vap->iv_stats.is_rx_disassoc++; 2182 IEEE80211_NODE_STAT(ni, rx_disassoc); 2183 } 2184 IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, 2185 "recv %s (reason %d)", ieee80211_mgt_subtype_name[subtype >> 2186 IEEE80211_FC0_SUBTYPE_SHIFT], reason); 2187 if (ni != vap->iv_bss) 2188 ieee80211_node_leave(ni); 2189 break; 2190 } 2191 2192 case IEEE80211_FC0_SUBTYPE_ACTION: 2193 case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: 2194 if (ni == vap->iv_bss) { 2195 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 2196 wh, NULL, "%s", "unknown node"); 2197 vap->iv_stats.is_rx_mgtdiscard++; 2198 } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && 2199 !IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2200 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 2201 wh, NULL, "%s", "not for us"); 2202 vap->iv_stats.is_rx_mgtdiscard++; 2203 } else if (vap->iv_state != IEEE80211_S_RUN) { 2204 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 2205 wh, NULL, "wrong state %s", 2206 ieee80211_state_name[vap->iv_state]); 2207 vap->iv_stats.is_rx_mgtdiscard++; 2208 } else { 2209 if (ieee80211_parse_action(ni, m0) == 0) 2210 (void)ic->ic_recv_action(ni, wh, frm, efrm); 2211 } 2212 break; 2213 2214 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2215 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: 2216 case IEEE80211_FC0_SUBTYPE_TIMING_ADV: 2217 case IEEE80211_FC0_SUBTYPE_ATIM: 2218 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 2219 wh, NULL, "%s", "not handled"); 2220 vap->iv_stats.is_rx_mgtdiscard++; 2221 break; 2222 2223 default: 2224 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 2225 wh, "mgt", "subtype 0x%x not handled", subtype); 2226 vap->iv_stats.is_rx_badsubtype++; 2227 break; 2228 } 2229} 2230 2231static void 2232hostap_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) 2233{ 2234 switch (subtype) { 2235 case IEEE80211_FC0_SUBTYPE_PS_POLL: 2236 ni->ni_vap->iv_recv_pspoll(ni, m); 2237 break; 2238 case IEEE80211_FC0_SUBTYPE_BAR: 2239 ieee80211_recv_bar(ni, m); 2240 break; 2241 } 2242} 2243 2244/* 2245 * Process a received ps-poll frame. 2246 */ 2247void 2248ieee80211_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0) 2249{ 2250 struct ieee80211vap *vap = ni->ni_vap; 2251 struct ieee80211com *ic = vap->iv_ic; 2252 struct ieee80211_frame_min *wh; 2253 struct mbuf *m; 2254 uint16_t aid; 2255 int qlen; 2256 2257 wh = mtod(m0, struct ieee80211_frame_min *); 2258 if (ni->ni_associd == 0) { 2259 IEEE80211_DISCARD(vap, 2260 IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 2261 (struct ieee80211_frame *) wh, NULL, 2262 "%s", "unassociated station"); 2263 vap->iv_stats.is_ps_unassoc++; 2264 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 2265 IEEE80211_REASON_NOT_ASSOCED); 2266 return; 2267 } 2268 2269 aid = le16toh(*(uint16_t *)wh->i_dur); 2270 if (aid != ni->ni_associd) { 2271 IEEE80211_DISCARD(vap, 2272 IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 2273 (struct ieee80211_frame *) wh, NULL, 2274 "aid mismatch: sta aid 0x%x poll aid 0x%x", 2275 ni->ni_associd, aid); 2276 vap->iv_stats.is_ps_badaid++; 2277 /* 2278 * NB: We used to deauth the station but it turns out 2279 * the Blackberry Curve 8230 (and perhaps other devices) 2280 * sometimes send the wrong AID when WME is negotiated. 2281 * Being more lenient here seems ok as we already check 2282 * the station is associated and we only return frames 2283 * queued for the station (i.e. we don't use the AID). 2284 */ 2285 return; 2286 } 2287 2288 /* Okay, take the first queued packet and put it out... */ 2289 m = ieee80211_node_psq_dequeue(ni, &qlen); 2290 if (m == NULL) { 2291 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_POWER, wh->i_addr2, 2292 "%s", "recv ps-poll, but queue empty"); 2293 ieee80211_send_nulldata(ieee80211_ref_node(ni)); 2294 vap->iv_stats.is_ps_qempty++; /* XXX node stat */ 2295 if (vap->iv_set_tim != NULL) 2296 vap->iv_set_tim(ni, 0); /* just in case */ 2297 return; 2298 } 2299 /* 2300 * If there are more packets, set the more packets bit 2301 * in the packet dispatched to the station; otherwise 2302 * turn off the TIM bit. 2303 */ 2304 if (qlen != 0) { 2305 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 2306 "recv ps-poll, send packet, %u still queued", qlen); 2307 m->m_flags |= M_MORE_DATA; 2308 } else { 2309 IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, 2310 "%s", "recv ps-poll, send packet, queue empty"); 2311 if (vap->iv_set_tim != NULL) 2312 vap->iv_set_tim(ni, 0); 2313 } 2314 m->m_flags |= M_PWR_SAV; /* bypass PS handling */ 2315 2316 /* 2317 * Do the right thing; if it's an encap'ed frame then 2318 * call ieee80211_parent_xmitpkt() else 2319 * call ieee80211_vap_xmitpkt(). 2320 */ 2321 if (m->m_flags & M_ENCAP) { 2322 (void) ieee80211_parent_xmitpkt(ic, m); 2323 } else { 2324 (void) ieee80211_vap_xmitpkt(vap, m); 2325 } 2326} 2327