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