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