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