ieee80211_input.c revision 127764
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002, 2003 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 127764 2004-04-02 22:50:31Z sam $");
35
36#include "opt_inet.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/mbuf.h>
41#include <sys/malloc.h>
42#include <sys/kernel.h>
43#include <sys/socket.h>
44#include <sys/sockio.h>
45#include <sys/endian.h>
46#include <sys/errno.h>
47#include <sys/bus.h>
48#include <sys/proc.h>
49#include <sys/sysctl.h>
50
51#include <machine/atomic.h>
52
53#include <net/if.h>
54#include <net/if_dl.h>
55#include <net/if_media.h>
56#include <net/if_arp.h>
57#include <net/ethernet.h>
58#include <net/if_llc.h>
59
60#include <net80211/ieee80211_var.h>
61
62#include <net/bpf.h>
63
64#ifdef INET
65#include <netinet/in.h>
66#include <netinet/if_ether.h>
67#endif
68
69/*
70 * Process a received frame.  The node associated with the sender
71 * should be supplied.  If nothing was found in the node table then
72 * the caller is assumed to supply a reference to ic_bss instead.
73 * The RSSI and a timestamp are also supplied.  The RSSI data is used
74 * during AP scanning to select a AP to associate with; it can have
75 * any units so long as values have consistent units and higher values
76 * mean ``better signal''.  The receive timestamp is currently not used
77 * by the 802.11 layer.
78 */
79void
80ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
81	int rssi, u_int32_t rstamp)
82{
83	struct ieee80211com *ic = (void *)ifp;
84	struct ieee80211_frame *wh;
85	struct ether_header *eh;
86	struct mbuf *m1;
87	int len;
88	u_int8_t dir, type, subtype;
89	u_int8_t *bssid;
90	u_int16_t rxseq;
91
92	KASSERT(ni != NULL, ("null node"));
93
94	/* trim CRC here so WEP can find its own CRC at the end of packet. */
95	if (m->m_flags & M_HASFCS) {
96		m_adj(m, -IEEE80211_CRC_LEN);
97		m->m_flags &= ~M_HASFCS;
98	}
99	KASSERT(m->m_pkthdr.len >= sizeof(struct ieee80211_frame_min),
100		("frame length too short: %u", m->m_pkthdr.len));
101
102	/*
103	 * In monitor mode, send everything directly to bpf.
104	 * XXX may want to include the CRC
105	 */
106	if (ic->ic_opmode == IEEE80211_M_MONITOR)
107		goto out;
108
109	wh = mtod(m, struct ieee80211_frame *);
110	if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
111	    IEEE80211_FC0_VERSION_0) {
112		if (ifp->if_flags & IFF_DEBUG)
113			if_printf(ifp, "receive packet with wrong version: %x\n",
114			    wh->i_fc[0]);
115		ic->ic_stats.is_rx_badversion++;
116		goto err;
117	}
118
119	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
120	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
121	/*
122	 * NB: We are not yet prepared to handle control frames,
123	 *     but permitting drivers to send them to us allows
124	 *     them to go through bpf tapping at the 802.11 layer.
125	 */
126	if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
127		/* XXX statistic */
128		IEEE80211_DPRINTF2(("%s: frame too short, len %u\n",
129			__func__, m->m_pkthdr.len));
130		ic->ic_stats.is_rx_tooshort++;
131		goto out;		/* XXX */
132	}
133	if (ic->ic_state != IEEE80211_S_SCAN) {
134		switch (ic->ic_opmode) {
135		case IEEE80211_M_STA:
136			if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
137				/* not interested in */
138				IEEE80211_DPRINTF2(("%s: discard frame from "
139					"bss %s\n", __func__,
140					ether_sprintf(wh->i_addr2)));
141				ic->ic_stats.is_rx_wrongbss++;
142				goto out;
143			}
144			break;
145		case IEEE80211_M_IBSS:
146		case IEEE80211_M_AHDEMO:
147		case IEEE80211_M_HOSTAP:
148			if (dir == IEEE80211_FC1_DIR_NODS)
149				bssid = wh->i_addr3;
150			else
151				bssid = wh->i_addr1;
152			if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) &&
153			    !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
154				/* not interested in */
155				IEEE80211_DPRINTF2(("%s: discard frame from "
156					"bss %s\n", __func__,
157					ether_sprintf(bssid)));
158				ic->ic_stats.is_rx_wrongbss++;
159				goto out;
160			}
161			break;
162		case IEEE80211_M_MONITOR:
163			goto out;
164		default:
165			/* XXX catch bad values */
166			break;
167		}
168		ni->ni_rssi = rssi;
169		ni->ni_rstamp = rstamp;
170		rxseq = ni->ni_rxseq;
171		ni->ni_rxseq =
172		    le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
173		/* TODO: fragment */
174		if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
175		    rxseq == ni->ni_rxseq) {
176			/* duplicate, silently discarded */
177			ic->ic_stats.is_rx_dup++; /* XXX per-station stat */
178			goto out;
179		}
180		ni->ni_inact = 0;
181	}
182
183	switch (type) {
184	case IEEE80211_FC0_TYPE_DATA:
185		switch (ic->ic_opmode) {
186		case IEEE80211_M_STA:
187			if (dir != IEEE80211_FC1_DIR_FROMDS) {
188				ic->ic_stats.is_rx_wrongdir++;
189				goto out;
190			}
191			if ((ifp->if_flags & IFF_SIMPLEX) &&
192			    IEEE80211_IS_MULTICAST(wh->i_addr1) &&
193			    IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
194				/*
195				 * In IEEE802.11 network, multicast packet
196				 * sent from me is broadcasted from AP.
197				 * It should be silently discarded for
198				 * SIMPLEX interface.
199				 */
200				ic->ic_stats.is_rx_mcastecho++;
201				goto out;
202			}
203			break;
204		case IEEE80211_M_IBSS:
205		case IEEE80211_M_AHDEMO:
206			if (dir != IEEE80211_FC1_DIR_NODS) {
207				ic->ic_stats.is_rx_wrongdir++;
208				goto out;
209			}
210			break;
211		case IEEE80211_M_HOSTAP:
212			if (dir != IEEE80211_FC1_DIR_TODS) {
213				ic->ic_stats.is_rx_wrongdir++;
214				goto out;
215			}
216			/* check if source STA is associated */
217			if (ni == ic->ic_bss) {
218				IEEE80211_DPRINTF(("%s: data from unknown src "
219					"%s\n", __func__,
220					ether_sprintf(wh->i_addr2)));
221				/* NB: caller deals with reference */
222				ni = ieee80211_dup_bss(ic, wh->i_addr2);
223				if (ni != NULL) {
224					IEEE80211_SEND_MGMT(ic, ni,
225					    IEEE80211_FC0_SUBTYPE_DEAUTH,
226					    IEEE80211_REASON_NOT_AUTHED);
227					ieee80211_free_node(ic, ni);
228				}
229				ic->ic_stats.is_rx_notassoc++;
230				goto err;
231			}
232			if (ni->ni_associd == 0) {
233				IEEE80211_DPRINTF(("ieee80211_input: "
234				    "data from unassoc src %s\n",
235				    ether_sprintf(wh->i_addr2)));
236				IEEE80211_SEND_MGMT(ic, ni,
237				    IEEE80211_FC0_SUBTYPE_DISASSOC,
238				    IEEE80211_REASON_NOT_ASSOCED);
239				ieee80211_unref_node(&ni);
240				ic->ic_stats.is_rx_notassoc++;
241				goto err;
242			}
243			break;
244		case IEEE80211_M_MONITOR:
245			break;
246		}
247		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
248			if (ic->ic_flags & IEEE80211_F_WEPON) {
249				m = ieee80211_wep_crypt(ifp, m, 0);
250				if (m == NULL) {
251					ic->ic_stats.is_rx_wepfail++;
252					goto err;
253				}
254				wh = mtod(m, struct ieee80211_frame *);
255			} else {
256				ic->ic_stats.is_rx_nowep++;
257				goto out;
258			}
259		}
260		/* copy to listener after decrypt */
261		if (ic->ic_rawbpf)
262			bpf_mtap(ic->ic_rawbpf, m);
263		m = ieee80211_decap(ifp, m);
264		if (m == NULL) {
265			ic->ic_stats.is_rx_decap++;
266			goto err;
267		}
268		ifp->if_ipackets++;
269
270		/* perform as a bridge within the AP */
271		m1 = NULL;
272		if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
273			eh = mtod(m, struct ether_header *);
274			if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
275				m1 = m_copypacket(m, M_DONTWAIT);
276				if (m1 == NULL)
277					ifp->if_oerrors++;
278				else
279					m1->m_flags |= M_MCAST;
280			} else {
281				ni = ieee80211_find_node(ic, eh->ether_dhost);
282				if (ni != NULL) {
283					if (ni->ni_associd != 0) {
284						m1 = m;
285						m = NULL;
286					}
287					ieee80211_free_node(ic, ni);
288				}
289			}
290			if (m1 != NULL) {
291#ifdef ALTQ
292				if (ALTQ_IS_ENABLED(&ifp->if_snd))
293					altq_etherclassify(&ifp->if_snd, m1,
294					    &pktattr);
295#endif
296				len = m1->m_pkthdr.len;
297				IF_ENQUEUE(&ifp->if_snd, m1);
298				if (m != NULL)
299					ifp->if_omcasts++;
300				ifp->if_obytes += len;
301			}
302		}
303		if (m != NULL)
304			(*ifp->if_input)(ifp, m);
305		return;
306
307	case IEEE80211_FC0_TYPE_MGT:
308		if (dir != IEEE80211_FC1_DIR_NODS) {
309			ic->ic_stats.is_rx_wrongdir++;
310			goto err;
311		}
312		if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
313			ic->ic_stats.is_rx_ahdemo_mgt++;
314			goto out;
315		}
316		subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
317
318		/* drop frames without interest */
319		if (ic->ic_state == IEEE80211_S_SCAN) {
320			if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
321			    subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
322				ic->ic_stats.is_rx_mgtdiscard++;
323				goto out;
324			}
325		} else {
326			if (ic->ic_opmode != IEEE80211_M_IBSS &&
327			    subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
328				ic->ic_stats.is_rx_mgtdiscard++;
329				goto out;
330			}
331		}
332
333		if (ifp->if_flags & IFF_DEBUG) {
334			/* avoid to print too many frames */
335			int doprint = 0;
336
337			switch (subtype) {
338			case IEEE80211_FC0_SUBTYPE_BEACON:
339				if (ic->ic_state == IEEE80211_S_SCAN)
340					doprint = 1;
341				break;
342			case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
343				if (ic->ic_opmode == IEEE80211_M_IBSS)
344					doprint = 1;
345				break;
346			default:
347				doprint = 1;
348				break;
349			}
350#ifdef IEEE80211_DEBUG
351			doprint += ieee80211_debug;
352#endif
353			if (doprint)
354				if_printf(ifp, "received %s from %s rssi %d\n",
355				    ieee80211_mgt_subtype_name[subtype
356				    >> IEEE80211_FC0_SUBTYPE_SHIFT],
357				    ether_sprintf(wh->i_addr2), rssi);
358		}
359		if (ic->ic_rawbpf)
360			bpf_mtap(ic->ic_rawbpf, m);
361		(*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
362		m_freem(m);
363		return;
364
365	case IEEE80211_FC0_TYPE_CTL:
366		ic->ic_stats.is_rx_ctl++;
367		goto out;
368	default:
369		IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, type));
370		/* should not come here */
371		break;
372	}
373  err:
374	ifp->if_ierrors++;
375  out:
376	if (m != NULL) {
377		if (ic->ic_rawbpf)
378			bpf_mtap(ic->ic_rawbpf, m);
379		m_freem(m);
380	}
381}
382
383struct mbuf *
384ieee80211_decap(struct ifnet *ifp, struct mbuf *m)
385{
386	struct ether_header *eh;
387	struct ieee80211_frame wh;
388	struct llc *llc;
389
390	if (m->m_len < sizeof(wh) + sizeof(*llc)) {
391		m = m_pullup(m, sizeof(wh) + sizeof(*llc));
392		if (m == NULL)
393			return NULL;
394	}
395	memcpy(&wh, mtod(m, caddr_t), sizeof(wh));
396	llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh));
397	if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
398	    llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
399	    llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
400		m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh));
401		llc = NULL;
402	} else {
403		m_adj(m, sizeof(wh) - sizeof(*eh));
404	}
405	eh = mtod(m, struct ether_header *);
406	switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
407	case IEEE80211_FC1_DIR_NODS:
408		IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
409		IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
410		break;
411	case IEEE80211_FC1_DIR_TODS:
412		IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
413		IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
414		break;
415	case IEEE80211_FC1_DIR_FROMDS:
416		IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
417		IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
418		break;
419	case IEEE80211_FC1_DIR_DSTODS:
420		/* not yet supported */
421		IEEE80211_DPRINTF(("%s: DS to DS\n", __func__));
422		m_freem(m);
423		return NULL;
424	}
425#ifdef ALIGNED_POINTER
426	if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) {
427		struct mbuf *n, *n0, **np;
428		caddr_t newdata;
429		int off, pktlen;
430
431		n0 = NULL;
432		np = &n0;
433		off = 0;
434		pktlen = m->m_pkthdr.len;
435		while (pktlen > off) {
436			if (n0 == NULL) {
437				MGETHDR(n, M_DONTWAIT, MT_DATA);
438				if (n == NULL) {
439					m_freem(m);
440					return NULL;
441				}
442				M_MOVE_PKTHDR(n, m);
443				n->m_len = MHLEN;
444			} else {
445				MGET(n, M_DONTWAIT, MT_DATA);
446				if (n == NULL) {
447					m_freem(m);
448					m_freem(n0);
449					return NULL;
450				}
451				n->m_len = MLEN;
452			}
453			if (pktlen - off >= MINCLSIZE) {
454				MCLGET(n, M_DONTWAIT);
455				if (n->m_flags & M_EXT)
456					n->m_len = n->m_ext.ext_size;
457			}
458			if (n0 == NULL) {
459				newdata =
460				    (caddr_t)ALIGN(n->m_data + sizeof(*eh)) -
461				    sizeof(*eh);
462				n->m_len -= newdata - n->m_data;
463				n->m_data = newdata;
464			}
465			if (n->m_len > pktlen - off)
466				n->m_len = pktlen - off;
467			m_copydata(m, off, n->m_len, mtod(n, caddr_t));
468			off += n->m_len;
469			*np = n;
470			np = &n->m_next;
471		}
472		m_freem(m);
473		m = n0;
474	}
475#endif /* ALIGNED_POINTER */
476	if (llc != NULL) {
477		eh = mtod(m, struct ether_header *);
478		eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh));
479	}
480	return m;
481}
482
483/*
484 * Install received rate set information in the node's state block.
485 */
486static int
487ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
488	u_int8_t *rates, u_int8_t *xrates, int flags)
489{
490	struct ieee80211_rateset *rs = &ni->ni_rates;
491
492	memset(rs, 0, sizeof(*rs));
493	rs->rs_nrates = rates[1];
494	memcpy(rs->rs_rates, rates + 2, rs->rs_nrates);
495	if (xrates != NULL) {
496		u_int8_t nxrates;
497		/*
498		 * Tack on 11g extended supported rate element.
499		 */
500		nxrates = xrates[1];
501		if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
502			nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
503			IEEE80211_DPRINTF(("%s: extended rate set too large;"
504				" only using %u of %u rates\n",
505				__func__, nxrates, xrates[1]));
506			ic->ic_stats.is_rx_rstoobig++;
507		}
508		memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
509		rs->rs_nrates += nxrates;
510	}
511	return ieee80211_fix_rate(ic, ni, flags);
512}
513
514/* Verify the existence and length of __elem or get out. */
515#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do {			\
516	if ((__elem) == NULL) {						\
517		IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n",	\
518			__func__, ieee80211_mgt_subtype_name[subtype >>	\
519				IEEE80211_FC0_SUBTYPE_SHIFT]));		\
520		ic->ic_stats.is_rx_elem_missing++;			\
521		return;							\
522	}								\
523	if ((__elem)[1] > (__maxlen)) {					\
524		IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s "	\
525			"frame from %s\n", __func__, (__elem)[1],	\
526			ieee80211_mgt_subtype_name[subtype >>		\
527				IEEE80211_FC0_SUBTYPE_SHIFT],		\
528			ether_sprintf(wh->i_addr2)));			\
529		ic->ic_stats.is_rx_elem_toobig++;			\
530		return;							\
531	}								\
532} while (0)
533
534#define	IEEE80211_VERIFY_LENGTH(_len, _minlen) do {			\
535	if ((_len) < (_minlen)) {					\
536		IEEE80211_DPRINTF(("%s: %s frame too short from %s\n",	\
537			__func__,					\
538			ieee80211_mgt_subtype_name[subtype >>		\
539				IEEE80211_FC0_SUBTYPE_SHIFT],		\
540			ether_sprintf(wh->i_addr2)));			\
541		ic->ic_stats.is_rx_elem_toosmall++;			\
542		return;							\
543	}								\
544} while (0)
545
546void
547ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
548	struct ieee80211_node *ni,
549	int subtype, int rssi, u_int32_t rstamp)
550{
551#define	ISPROBE(_st)	((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
552	struct ifnet *ifp = &ic->ic_if;
553	struct ieee80211_frame *wh;
554	u_int8_t *frm, *efrm;
555	u_int8_t *ssid, *rates, *xrates;
556	int reassoc, resp, newassoc, allocbs;
557
558	wh = mtod(m0, struct ieee80211_frame *);
559	frm = (u_int8_t *)&wh[1];
560	efrm = mtod(m0, u_int8_t *) + m0->m_len;
561	switch (subtype) {
562	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
563	case IEEE80211_FC0_SUBTYPE_BEACON: {
564		u_int8_t *tstamp, *bintval, *capinfo, *country;
565		u_int8_t chan, bchan, fhindex, erp;
566		u_int16_t fhdwell;
567
568		if (ic->ic_opmode != IEEE80211_M_IBSS &&
569		    ic->ic_state != IEEE80211_S_SCAN) {
570			/* XXX: may be useful for background scan */
571			return;
572		}
573
574		/*
575		 * beacon/probe response frame format
576		 *	[8] time stamp
577		 *	[2] beacon interval
578		 *	[2] capability information
579		 *	[tlv] ssid
580		 *	[tlv] supported rates
581		 *	[tlv] country information
582		 *	[tlv] parameter set (FH/DS)
583		 *	[tlv] erp information
584		 *	[tlv] extended supported rates
585		 */
586		IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
587		tstamp  = frm;	frm += 8;
588		bintval = frm;	frm += 2;
589		capinfo = frm;	frm += 2;
590		ssid = rates = xrates = country = NULL;
591		bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
592		chan = bchan;
593		fhdwell = 0;
594		fhindex = 0;
595		erp = 0;
596		while (frm < efrm) {
597			switch (*frm) {
598			case IEEE80211_ELEMID_SSID:
599				ssid = frm;
600				break;
601			case IEEE80211_ELEMID_RATES:
602				rates = frm;
603				break;
604			case IEEE80211_ELEMID_COUNTRY:
605				country = frm;
606				break;
607			case IEEE80211_ELEMID_FHPARMS:
608				if (ic->ic_phytype == IEEE80211_T_FH) {
609					fhdwell = (frm[3] << 8) | frm[2];
610					chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
611					fhindex = frm[6];
612				}
613				break;
614			case IEEE80211_ELEMID_DSPARMS:
615				/*
616				 * XXX hack this since depending on phytype
617				 * is problematic for multi-mode devices.
618				 */
619				if (ic->ic_phytype != IEEE80211_T_FH)
620					chan = frm[2];
621				break;
622			case IEEE80211_ELEMID_TIM:
623				break;
624			case IEEE80211_ELEMID_IBSSPARMS:
625				break;
626			case IEEE80211_ELEMID_XRATES:
627				xrates = frm;
628				break;
629			case IEEE80211_ELEMID_ERP:
630				if (frm[1] != 1) {
631					IEEE80211_DPRINTF(("%s: invalid ERP "
632						"element; length %u, expecting "
633						"1\n", __func__, frm[1]));
634					ic->ic_stats.is_rx_elem_toobig++;
635					break;
636				}
637				erp = frm[2];
638				break;
639			default:
640				IEEE80211_DPRINTF2(("%s: element id %u/len %u "
641					"ignored\n", __func__, *frm, frm[1]));
642				ic->ic_stats.is_rx_elem_unknown++;
643				break;
644			}
645			frm += frm[1] + 2;
646		}
647		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
648		IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
649		if (
650#if IEEE80211_CHAN_MAX < 255
651		    chan > IEEE80211_CHAN_MAX ||
652#endif
653		    isclr(ic->ic_chan_active, chan)) {
654			IEEE80211_DPRINTF(("%s: ignore %s with invalid channel "
655				"%u\n", __func__,
656				ISPROBE(subtype) ? "probe response" : "beacon",
657				chan));
658			ic->ic_stats.is_rx_badchan++;
659			return;
660		}
661		if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) {
662			/*
663			 * Frame was received on a channel different from the
664			 * one indicated in the DS params element id;
665			 * silently discard it.
666			 *
667			 * NB: this can happen due to signal leakage.
668			 *     But we should take it for FH phy because
669			 *     the rssi value should be correct even for
670			 *     different hop pattern in FH.
671			 */
672			IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked "
673				"for channel %u\n", __func__,
674				ISPROBE(subtype) ? "probe response" : "beacon",
675				bchan, chan));
676			ic->ic_stats.is_rx_chanmismatch++;
677			return;
678		}
679
680		/*
681		 * Use mac and channel for lookup so we collect all
682		 * potential AP's when scanning.  Otherwise we may
683		 * see the same AP on multiple channels and will only
684		 * record the last one.  We could filter APs here based
685		 * on rssi, etc. but leave that to the end of the scan
686		 * so we can keep the selection criteria in one spot.
687		 * This may result in a bloat of the scanned AP list but
688		 * it shouldn't be too much.
689		 */
690		ni = ieee80211_lookup_node(ic, wh->i_addr2,
691				&ic->ic_channels[chan]);
692#ifdef IEEE80211_DEBUG
693		if (ieee80211_debug &&
694		    (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) {
695			printf("%s: %s%s on chan %u (bss chan %u) ",
696			    __func__, (ni == NULL ? "new " : ""),
697			    ISPROBE(subtype) ? "probe response" : "beacon",
698			    chan, bchan);
699			ieee80211_print_essid(ssid + 2, ssid[1]);
700			printf(" from %s\n", ether_sprintf(wh->i_addr2));
701			printf("%s: caps 0x%x bintval %u erp 0x%x\n",
702				__func__, le16toh(*(u_int16_t *)capinfo),
703				le16toh(*(u_int16_t *)bintval), erp);
704			if (country)
705				printf("%s: country info %*D\n",
706					__func__, country[1], country+2, " ");
707		}
708#endif
709		if (ni == NULL) {
710			ni = ieee80211_alloc_node(ic, wh->i_addr2);
711			if (ni == NULL) {
712				ic->ic_stats.is_rx_nodealloc++;
713				return;
714			}
715			ni->ni_esslen = ssid[1];
716			memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
717			memcpy(ni->ni_essid, ssid + 2, ssid[1]);
718		} else if (ssid[1] != 0 && ISPROBE(subtype)) {
719			/*
720			 * Update ESSID at probe response to adopt hidden AP by
721			 * Lucent/Cisco, which announces null ESSID in beacon.
722			 */
723			ni->ni_esslen = ssid[1];
724			memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
725			memcpy(ni->ni_essid, ssid + 2, ssid[1]);
726		}
727		IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
728		ni->ni_rssi = rssi;
729		ni->ni_rstamp = rstamp;
730		memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp));
731		ni->ni_intval = le16toh(*(u_int16_t *)bintval);
732		ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo);
733		/* XXX validate channel # */
734		ni->ni_chan = &ic->ic_channels[chan];
735		ni->ni_fhdwell = fhdwell;
736		ni->ni_fhindex = fhindex;
737		ni->ni_erp = erp;
738		/* NB: must be after ni_chan is setup */
739		ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
740		ieee80211_unref_node(&ni);
741		break;
742	}
743
744	case IEEE80211_FC0_SUBTYPE_PROBE_REQ: {
745		u_int8_t rate;
746
747		if (ic->ic_opmode == IEEE80211_M_STA)
748			return;
749		if (ic->ic_state != IEEE80211_S_RUN)
750			return;
751
752		/*
753		 * prreq frame format
754		 *	[tlv] ssid
755		 *	[tlv] supported rates
756		 *	[tlv] extended supported rates
757		 */
758		ssid = rates = xrates = NULL;
759		while (frm < efrm) {
760			switch (*frm) {
761			case IEEE80211_ELEMID_SSID:
762				ssid = frm;
763				break;
764			case IEEE80211_ELEMID_RATES:
765				rates = frm;
766				break;
767			case IEEE80211_ELEMID_XRATES:
768				xrates = frm;
769				break;
770			}
771			frm += frm[1] + 2;
772		}
773		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
774		IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
775		if (ssid[1] != 0 &&
776		    (ssid[1] != ic->ic_bss->ni_esslen ||
777		    memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) {
778#ifdef IEEE80211_DEBUG
779			if (ieee80211_debug) {
780				printf("%s: ssid unmatch ", __func__);
781				ieee80211_print_essid(ssid + 2, ssid[1]);
782				printf(" from %s\n", ether_sprintf(wh->i_addr2));
783			}
784#endif
785			ic->ic_stats.is_rx_ssidmismatch++;
786			return;
787		}
788
789		if (ni == ic->ic_bss) {
790			ni = ieee80211_dup_bss(ic, wh->i_addr2);
791			if (ni == NULL) {
792				ic->ic_stats.is_rx_nodealloc++;
793				return;
794			}
795			IEEE80211_DPRINTF(("%s: new req from %s\n",
796				__func__, ether_sprintf(wh->i_addr2)));
797			allocbs = 1;
798		} else
799			allocbs = 0;
800		ni->ni_rssi = rssi;
801		ni->ni_rstamp = rstamp;
802		rate = ieee80211_setup_rates(ic, ni, rates, xrates,
803				IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
804				| IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
805		if (rate & IEEE80211_RATE_BASIC) {
806			IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n",
807				__func__,ether_sprintf(wh->i_addr2)));
808		} else {
809			IEEE80211_SEND_MGMT(ic, ni,
810				IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
811		}
812		if (allocbs) {
813			/* XXX just use free? */
814			if (ic->ic_opmode == IEEE80211_M_HOSTAP)
815				ieee80211_free_node(ic, ni);
816			else
817				ieee80211_unref_node(&ni);
818		}
819		break;
820	}
821
822	case IEEE80211_FC0_SUBTYPE_AUTH: {
823		u_int16_t algo, seq, status;
824		/*
825		 * auth frame format
826		 *	[2] algorithm
827		 *	[2] sequence
828		 *	[2] status
829		 *	[tlv*] challenge
830		 */
831		IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
832		algo   = le16toh(*(u_int16_t *)frm);
833		seq    = le16toh(*(u_int16_t *)(frm + 2));
834		status = le16toh(*(u_int16_t *)(frm + 4));
835		if (algo != IEEE80211_AUTH_ALG_OPEN) {
836			/* TODO: shared key auth */
837			IEEE80211_DPRINTF(("%s: unsupported auth %d from %s\n",
838				__func__, algo, ether_sprintf(wh->i_addr2)));
839			ic->ic_stats.is_rx_auth_unsupported++;
840			return;
841		}
842		switch (ic->ic_opmode) {
843		case IEEE80211_M_IBSS:
844			if (ic->ic_state != IEEE80211_S_RUN || seq != 1) {
845				IEEE80211_DPRINTF(("%s: discard auth from %s; "
846					"state %u, seq %u\n", __func__,
847					ether_sprintf(wh->i_addr2),
848					ic->ic_state, seq));
849				ic->ic_stats.is_rx_bad_auth++;
850				break;
851			}
852			ieee80211_new_state(ic, IEEE80211_S_AUTH,
853			    wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
854			break;
855
856		case IEEE80211_M_AHDEMO:
857			/* should not come here */
858			break;
859
860		case IEEE80211_M_HOSTAP:
861			if (ic->ic_state != IEEE80211_S_RUN || seq != 1) {
862				IEEE80211_DPRINTF(("%s: discard auth from %s; "
863					"state %u, seq %u\n", __func__,
864					ether_sprintf(wh->i_addr2),
865					ic->ic_state, seq));
866				ic->ic_stats.is_rx_bad_auth++;
867				break;
868			}
869			if (ni == ic->ic_bss) {
870				ni = ieee80211_alloc_node(ic, wh->i_addr2);
871				if (ni == NULL) {
872					ic->ic_stats.is_rx_nodealloc++;
873					return;
874				}
875				IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
876				ni->ni_rssi = rssi;
877				ni->ni_rstamp = rstamp;
878				ni->ni_chan = ic->ic_bss->ni_chan;
879				allocbs = 1;
880			} else
881				allocbs = 0;
882			IEEE80211_SEND_MGMT(ic, ni,
883				IEEE80211_FC0_SUBTYPE_AUTH, 2);
884			if (ifp->if_flags & IFF_DEBUG)
885				if_printf(ifp, "station %s %s authenticated\n",
886				    (allocbs ? "newly" : "already"),
887				    ether_sprintf(ni->ni_macaddr));
888			break;
889
890		case IEEE80211_M_STA:
891			if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) {
892				IEEE80211_DPRINTF(("%s: discard auth from %s; "
893					"state %u, seq %u\n", __func__,
894					ether_sprintf(wh->i_addr2),
895					ic->ic_state, seq));
896				ic->ic_stats.is_rx_bad_auth++;
897				break;
898			}
899			if (status != 0) {
900				if_printf(&ic->ic_if,
901				    "authentication failed (reason %d) for %s\n",
902				    status,
903				    ether_sprintf(wh->i_addr3));
904				if (ni != ic->ic_bss)
905					ni->ni_fails++;
906				ic->ic_stats.is_rx_auth_fail++;
907				return;
908			}
909			ieee80211_new_state(ic, IEEE80211_S_ASSOC,
910			    wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
911			break;
912		case IEEE80211_M_MONITOR:
913			break;
914		}
915		break;
916	}
917
918	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
919	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
920		u_int16_t capinfo, bintval;
921
922		if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
923		    (ic->ic_state != IEEE80211_S_RUN))
924			return;
925
926		if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
927			reassoc = 1;
928			resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
929		} else {
930			reassoc = 0;
931			resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
932		}
933		/*
934		 * asreq frame format
935		 *	[2] capability information
936		 *	[2] listen interval
937		 *	[6*] current AP address (reassoc only)
938		 *	[tlv] ssid
939		 *	[tlv] supported rates
940		 *	[tlv] extended supported rates
941		 */
942		IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4));
943		if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
944			IEEE80211_DPRINTF(("%s: ignore other bss from %s\n",
945				__func__, ether_sprintf(wh->i_addr2)));
946			ic->ic_stats.is_rx_assoc_bss++;
947			return;
948		}
949		capinfo = le16toh(*(u_int16_t *)frm);	frm += 2;
950		bintval = le16toh(*(u_int16_t *)frm);	frm += 2;
951		if (reassoc)
952			frm += 6;	/* ignore current AP info */
953		ssid = rates = xrates = NULL;
954		while (frm < efrm) {
955			switch (*frm) {
956			case IEEE80211_ELEMID_SSID:
957				ssid = frm;
958				break;
959			case IEEE80211_ELEMID_RATES:
960				rates = frm;
961				break;
962			case IEEE80211_ELEMID_XRATES:
963				xrates = frm;
964				break;
965			}
966			frm += frm[1] + 2;
967		}
968		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
969		IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
970		if (ssid[1] != ic->ic_bss->ni_esslen ||
971		    memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) {
972#ifdef IEEE80211_DEBUG
973			if (ieee80211_debug) {
974				printf("%s: ssid unmatch ", __func__);
975				ieee80211_print_essid(ssid + 2, ssid[1]);
976				printf(" from %s\n", ether_sprintf(wh->i_addr2));
977			}
978#endif
979			ic->ic_stats.is_rx_ssidmismatch++;
980			return;
981		}
982		if (ni == ic->ic_bss) {
983			IEEE80211_DPRINTF(("%s: not authenticated for %s\n",
984				__func__, ether_sprintf(wh->i_addr2)));
985			ni = ieee80211_dup_bss(ic, wh->i_addr2);
986			if (ni != NULL) {
987				IEEE80211_SEND_MGMT(ic, ni,
988				    IEEE80211_FC0_SUBTYPE_DEAUTH,
989				    IEEE80211_REASON_ASSOC_NOT_AUTHED);
990				ieee80211_free_node(ic, ni);
991			}
992			ic->ic_stats.is_rx_assoc_notauth++;
993			return;
994		}
995		/* XXX per-node cipher suite */
996		/* XXX some stations use the privacy bit for handling APs
997		       that suport both encrypted and unencrypted traffic */
998		if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 ||
999		    (capinfo & IEEE80211_CAPINFO_PRIVACY) !=
1000		    ((ic->ic_flags & IEEE80211_F_WEPON) ?
1001		     IEEE80211_CAPINFO_PRIVACY : 0)) {
1002			IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n",
1003				__func__, capinfo, ether_sprintf(wh->i_addr2)));
1004			ni->ni_associd = 0;
1005			IEEE80211_SEND_MGMT(ic, ni, resp,
1006				IEEE80211_STATUS_CAPINFO);
1007			ic->ic_stats.is_rx_assoc_capmismatch++;
1008			return;
1009		}
1010		ieee80211_setup_rates(ic, ni, rates, xrates,
1011				IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
1012				IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1013		if (ni->ni_rates.rs_nrates == 0) {
1014			IEEE80211_DPRINTF(("%s: rate unmatch for %s\n",
1015				__func__, ether_sprintf(wh->i_addr2)));
1016			ni->ni_associd = 0;
1017			IEEE80211_SEND_MGMT(ic, ni, resp,
1018				IEEE80211_STATUS_BASIC_RATE);
1019			ic->ic_stats.is_rx_assoc_norate++;
1020			return;
1021		}
1022		ni->ni_rssi = rssi;
1023		ni->ni_rstamp = rstamp;
1024		ni->ni_intval = bintval;
1025		ni->ni_capinfo = capinfo;
1026		ni->ni_chan = ic->ic_bss->ni_chan;
1027		ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
1028		ni->ni_fhindex = ic->ic_bss->ni_fhindex;
1029		if (ni->ni_associd == 0) {
1030			/* XXX handle rollover at 2007 */
1031			/* XXX guarantee uniqueness */
1032			ni->ni_associd = 0xc000 | ic->ic_bss->ni_associd++;
1033			newassoc = 1;
1034		} else
1035			newassoc = 0;
1036		/* XXX for 11g must turn off short slot time if long
1037	           slot time sta associates */
1038		IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
1039		if (ifp->if_flags & IFF_DEBUG)
1040			if_printf(ifp, "station %s %s associated\n",
1041			    (newassoc ? "newly" : "already"),
1042			    ether_sprintf(ni->ni_macaddr));
1043		/* give driver a chance to setup state like ni_txrate */
1044		if (ic->ic_newassoc)
1045			(*ic->ic_newassoc)(ic, ni, newassoc);
1046		break;
1047	}
1048
1049	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
1050	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
1051		u_int16_t status;
1052
1053		if (ic->ic_opmode != IEEE80211_M_STA ||
1054		    ic->ic_state != IEEE80211_S_ASSOC)
1055			return;
1056
1057		/*
1058		 * asresp frame format
1059		 *	[2] capability information
1060		 *	[2] status
1061		 *	[2] association ID
1062		 *	[tlv] supported rates
1063		 *	[tlv] extended supported rates
1064		 */
1065		IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
1066		ni = ic->ic_bss;
1067		ni->ni_capinfo = le16toh(*(u_int16_t *)frm);
1068		frm += 2;
1069
1070		status = le16toh(*(u_int16_t *)frm);
1071		frm += 2;
1072		if (status != 0) {
1073			if_printf(ifp, "association failed (reason %d) for %s\n",
1074			    status, ether_sprintf(wh->i_addr3));
1075			if (ni != ic->ic_bss)
1076				ni->ni_fails++;
1077			ic->ic_stats.is_rx_auth_fail++;
1078			return;
1079		}
1080		ni->ni_associd = le16toh(*(u_int16_t *)frm);
1081		frm += 2;
1082
1083		rates = xrates = NULL;
1084		while (frm < efrm) {
1085			switch (*frm) {
1086			case IEEE80211_ELEMID_RATES:
1087				rates = frm;
1088				break;
1089			case IEEE80211_ELEMID_XRATES:
1090				xrates = frm;
1091				break;
1092			}
1093			frm += frm[1] + 2;
1094		}
1095
1096		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1097		ieee80211_setup_rates(ic, ni, rates, xrates,
1098				IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
1099				IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1100		if (ni->ni_rates.rs_nrates != 0)
1101			ieee80211_new_state(ic, IEEE80211_S_RUN,
1102				wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1103		break;
1104	}
1105
1106	case IEEE80211_FC0_SUBTYPE_DEAUTH: {
1107		u_int16_t reason;
1108		/*
1109		 * deauth frame format
1110		 *	[2] reason
1111		 */
1112		IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1113		reason = le16toh(*(u_int16_t *)frm);
1114		ic->ic_stats.is_rx_deauth++;
1115		switch (ic->ic_opmode) {
1116		case IEEE80211_M_STA:
1117			ieee80211_new_state(ic, IEEE80211_S_AUTH,
1118			    wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1119			break;
1120		case IEEE80211_M_HOSTAP:
1121			if (ni != ic->ic_bss) {
1122				if (ifp->if_flags & IFF_DEBUG)
1123					if_printf(ifp, "station %s deauthenticated"
1124					    " by peer (reason %d)\n",
1125					    ether_sprintf(ni->ni_macaddr), reason);
1126				/* node will be free'd on return */
1127				ieee80211_unref_node(&ni);
1128			}
1129			break;
1130		default:
1131			break;
1132		}
1133		break;
1134	}
1135
1136	case IEEE80211_FC0_SUBTYPE_DISASSOC: {
1137		u_int16_t reason;
1138		/*
1139		 * disassoc frame format
1140		 *	[2] reason
1141		 */
1142		IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1143		reason = le16toh(*(u_int16_t *)frm);
1144		ic->ic_stats.is_rx_disassoc++;
1145		switch (ic->ic_opmode) {
1146		case IEEE80211_M_STA:
1147			ieee80211_new_state(ic, IEEE80211_S_ASSOC,
1148			    wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1149			break;
1150		case IEEE80211_M_HOSTAP:
1151			if (ni != ic->ic_bss) {
1152				if (ifp->if_flags & IFF_DEBUG)
1153					if_printf(ifp, "station %s disassociated"
1154					    " by peer (reason %d)\n",
1155					    ether_sprintf(ni->ni_macaddr), reason);
1156				ni->ni_associd = 0;
1157				/* XXX node reclaimed how? */
1158			}
1159			break;
1160		default:
1161			break;
1162		}
1163		break;
1164	}
1165	default:
1166		IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not "
1167			"handled\n", __func__, subtype));
1168		ic->ic_stats.is_rx_badsubtype++;
1169		break;
1170	}
1171#undef ISPROBE
1172}
1173#undef IEEE80211_VERIFY_LENGTH
1174#undef IEEE80211_VERIFY_ELEMENT
1175