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