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