ieee80211_input.c revision 1.25 1 /* $NetBSD: ieee80211_input.c,v 1.25 2004/07/23 06:44:55 mycroft Exp $ */
2 /*-
3 * Copyright (c) 2001 Atsushi Onoe
4 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * Alternatively, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") version 2 as published by the Free
20 * Software Foundation.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 #ifdef __FreeBSD__
36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.20 2004/04/02 23:35:24 sam Exp $");
37 #else
38 __KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.25 2004/07/23 06:44:55 mycroft Exp $");
39 #endif
40
41 #include "opt_inet.h"
42
43 #ifdef __NetBSD__
44 #include "bpfilter.h"
45 #endif /* __NetBSD__ */
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/mbuf.h>
50 #include <sys/malloc.h>
51 #include <sys/kernel.h>
52 #include <sys/socket.h>
53 #include <sys/sockio.h>
54 #include <sys/endian.h>
55 #include <sys/errno.h>
56 #ifdef __FreeBSD__
57 #include <sys/bus.h>
58 #endif
59 #include <sys/proc.h>
60 #include <sys/sysctl.h>
61
62 #ifdef __FreeBSD__
63 #include <machine/atomic.h>
64 #endif
65
66 #include <net/if.h>
67 #include <net/if_dl.h>
68 #include <net/if_media.h>
69 #include <net/if_arp.h>
70 #ifdef __FreeBSD__
71 #include <net/ethernet.h>
72 #else
73 #include <net/if_ether.h>
74 #endif
75 #include <net/if_llc.h>
76
77 #include <net80211/ieee80211_var.h>
78 #include <net80211/ieee80211_compat.h>
79
80 #if NBPFILTER > 0
81 #include <net/bpf.h>
82 #endif
83
84 #ifdef INET
85 #include <netinet/in.h>
86 #ifdef __FreeBSD__
87 #include <netinet/if_ether.h>
88 #else
89 #include <net/if_ether.h>
90 #endif
91 #endif
92
93 static void ieee80211_recv_pspoll(struct ieee80211com *,
94 struct mbuf *, int, u_int32_t);
95
96 /*
97 * Process a received frame. The node associated with the sender
98 * should be supplied. If nothing was found in the node table then
99 * the caller is assumed to supply a reference to ic_bss instead.
100 * The RSSI and a timestamp are also supplied. The RSSI data is used
101 * during AP scanning to select a AP to associate with; it can have
102 * any units so long as values have consistent units and higher values
103 * mean ``better signal''. The receive timestamp is currently not used
104 * by the 802.11 layer.
105 */
106 void
107 ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
108 int rssi, u_int32_t rstamp)
109 {
110 struct ieee80211com *ic = (void *)ifp;
111 struct ieee80211_frame *wh;
112 struct ether_header *eh;
113 struct mbuf *m1;
114 int len;
115 u_int8_t dir, type, subtype;
116 u_int8_t *bssid;
117 u_int16_t rxseq;
118 ALTQ_DECL(struct altq_pktattr pktattr;)
119
120 IASSERT(ni != NULL, ("null node"));
121
122 /* trim CRC here so WEP can find its own CRC at the end of packet. */
123 if (m->m_flags & M_HASFCS) {
124 m_adj(m, -IEEE80211_CRC_LEN);
125 m->m_flags &= ~M_HASFCS;
126 }
127
128 /*
129 * In monitor mode, send everything directly to bpf.
130 * Also do not process frames w/o i_addr2 any further.
131 * XXX may want to include the CRC
132 */
133 if (ic->ic_opmode == IEEE80211_M_MONITOR ||
134 m->m_pkthdr.len < sizeof(struct ieee80211_frame_min))
135 goto out;
136
137 wh = mtod(m, struct ieee80211_frame *);
138 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
139 IEEE80211_FC0_VERSION_0) {
140 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
141 ("receive packet with wrong version: %x\n",
142 wh->i_fc[0]));
143 ic->ic_stats.is_rx_badversion++;
144 goto err;
145 }
146
147 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
148 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
149 /*
150 * NB: We are not yet prepared to handle control frames,
151 * but permitting drivers to send them to us allows
152 * them to go through bpf tapping at the 802.11 layer.
153 */
154 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
155 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
156 ("%s: frame too short, len %u\n",
157 __func__, m->m_pkthdr.len));
158 ic->ic_stats.is_rx_tooshort++;
159 goto out;
160 }
161 if (ic->ic_state != IEEE80211_S_SCAN) {
162 switch (ic->ic_opmode) {
163 case IEEE80211_M_STA:
164 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
165 /* not interested in */
166 IEEE80211_DPRINTF(ic, IEEE80211_MSG_INPUT,
167 ("%s: discard frame from "
168 "bss %s\n", __func__,
169 ether_sprintf(wh->i_addr2)));
170 ic->ic_stats.is_rx_wrongbss++;
171 goto out;
172 }
173 break;
174 case IEEE80211_M_IBSS:
175 case IEEE80211_M_AHDEMO:
176 case IEEE80211_M_HOSTAP:
177 if (dir == IEEE80211_FC1_DIR_NODS)
178 bssid = wh->i_addr3;
179 else
180 bssid = wh->i_addr1;
181 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) &&
182 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr) &&
183 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
184 IEEE80211_FC0_TYPE_DATA) {
185 /* not interested in */
186 IEEE80211_DPRINTF(ic, IEEE80211_MSG_INPUT,
187 ("%s: discard data frame from bss %s\n",
188 __func__, ether_sprintf(bssid)));
189 ic->ic_stats.is_rx_wrongbss++;
190 goto out;
191 }
192 break;
193 case IEEE80211_M_MONITOR:
194 goto out;
195 default:
196 /* XXX catch bad values */
197 break;
198 }
199 ni->ni_rssi = rssi;
200 ni->ni_rstamp = rstamp;
201 rxseq = ni->ni_rxseq;
202 ni->ni_rxseq =
203 le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
204 /* TODO: fragment */
205 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
206 rxseq == ni->ni_rxseq) {
207 /* duplicate, silently discarded */
208 ic->ic_stats.is_rx_dup++; /* XXX per-station stat */
209 goto out;
210 }
211 ni->ni_inact = 0;
212 }
213
214 if (ic->ic_set_tim != NULL &&
215 (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT)
216 && ni->ni_pwrsave == 0) {
217 /* turn on power save mode */
218
219 if (ifp->if_flags & IFF_DEBUG)
220 printf("%s: power save mode on for %s\n",
221 ifp->if_xname, ether_sprintf(wh->i_addr2));
222
223 ni->ni_pwrsave = IEEE80211_PS_SLEEP;
224 }
225 if (ic->ic_set_tim != NULL &&
226 (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) == 0 &&
227 ni->ni_pwrsave != 0) {
228 /* turn off power save mode, dequeue stored packets */
229
230 ni->ni_pwrsave = 0;
231 if (ic->ic_set_tim)
232 ic->ic_set_tim(ic, ni->ni_associd, 0);
233
234 if (ifp->if_flags & IFF_DEBUG)
235 printf("%s: power save mode off for %s\n",
236 ifp->if_xname, ether_sprintf(wh->i_addr2));
237
238 while (!IF_IS_EMPTY(&ni->ni_savedq)) {
239 struct mbuf *m;
240 IF_DEQUEUE(&ni->ni_savedq, m);
241 IF_ENQUEUE(&ic->ic_pwrsaveq, m);
242 (*ifp->if_start)(ifp);
243 }
244 }
245
246 switch (type) {
247 case IEEE80211_FC0_TYPE_DATA:
248 switch (ic->ic_opmode) {
249 case IEEE80211_M_STA:
250 if (dir != IEEE80211_FC1_DIR_FROMDS) {
251 ic->ic_stats.is_rx_wrongdir++;
252 goto out;
253 }
254 if ((ifp->if_flags & IFF_SIMPLEX) &&
255 IEEE80211_IS_MULTICAST(wh->i_addr1) &&
256 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
257 /*
258 * In IEEE802.11 network, multicast packet
259 * sent from me is broadcasted from AP.
260 * It should be silently discarded for
261 * SIMPLEX interface.
262 */
263 ic->ic_stats.is_rx_mcastecho++;
264 goto out;
265 }
266 break;
267 case IEEE80211_M_IBSS:
268 case IEEE80211_M_AHDEMO:
269 if (dir != IEEE80211_FC1_DIR_NODS) {
270 ic->ic_stats.is_rx_wrongdir++;
271 goto out;
272 }
273 break;
274 case IEEE80211_M_HOSTAP:
275 if (dir != IEEE80211_FC1_DIR_TODS) {
276 ic->ic_stats.is_rx_wrongdir++;
277 goto out;
278 }
279 /* check if source STA is associated */
280 if (ni == ic->ic_bss) {
281 IEEE80211_DPRINTF(ic, IEEE80211_MSG_INPUT,
282 ("%s: data from unknown src %s\n",
283 __func__, ether_sprintf(wh->i_addr2)));
284 /* NB: caller deals with reference */
285 ni = ieee80211_dup_bss(ic, wh->i_addr2);
286 if (ni != NULL) {
287 IEEE80211_SEND_MGMT(ic, ni,
288 IEEE80211_FC0_SUBTYPE_DEAUTH,
289 IEEE80211_REASON_NOT_AUTHED);
290 ieee80211_free_node(ic, ni);
291 }
292 ic->ic_stats.is_rx_notassoc++;
293 goto err;
294 }
295 if (ni->ni_associd == 0) {
296 IEEE80211_DPRINTF(ic, IEEE80211_MSG_INPUT,
297 ("%s: data from unassoc src %s\n",
298 __func__, ether_sprintf(wh->i_addr2)));
299 IEEE80211_SEND_MGMT(ic, ni,
300 IEEE80211_FC0_SUBTYPE_DISASSOC,
301 IEEE80211_REASON_NOT_ASSOCED);
302 ieee80211_unref_node(&ni);
303 ic->ic_stats.is_rx_notassoc++;
304 goto err;
305 }
306 break;
307 case IEEE80211_M_MONITOR:
308 break;
309 }
310 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
311 if (ic->ic_flags & IEEE80211_F_WEPON) {
312 m = ieee80211_wep_crypt(ifp, m, 0);
313 if (m == NULL) {
314 ic->ic_stats.is_rx_wepfail++;
315 goto err;
316 }
317 wh = mtod(m, struct ieee80211_frame *);
318 } else {
319 ic->ic_stats.is_rx_nowep++;
320 goto out;
321 }
322 }
323 #if NBPFILTER > 0
324 /* copy to listener after decrypt */
325 if (ic->ic_rawbpf)
326 bpf_mtap(ic->ic_rawbpf, m);
327 #endif
328 m = ieee80211_decap(ifp, m);
329 if (m == NULL) {
330 IEEE80211_DPRINTF(ic, IEEE80211_MSG_INPUT,
331 ("%s: decapsulation error for src %s\n",
332 __func__, ether_sprintf(wh->i_addr2)));
333 ic->ic_stats.is_rx_decap++;
334 goto err;
335 }
336 ifp->if_ipackets++;
337
338 /* perform as a bridge within the AP */
339 m1 = NULL;
340 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
341 eh = mtod(m, struct ether_header *);
342 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
343 m1 = m_copypacket(m, M_DONTWAIT);
344 if (m1 == NULL)
345 ifp->if_oerrors++;
346 else
347 m1->m_flags |= M_MCAST;
348 } else {
349 ni = ieee80211_find_node(ic, eh->ether_dhost);
350 if (ni != NULL) {
351 if (ni->ni_associd != 0) {
352 m1 = m;
353 m = NULL;
354 }
355 ieee80211_free_node(ic, ni);
356 }
357 }
358 if (m1 != NULL) {
359 #ifdef ALTQ
360 if (ALTQ_IS_ENABLED(&ifp->if_snd))
361 altq_etherclassify(&ifp->if_snd, m1,
362 &pktattr);
363 #endif
364 len = m1->m_pkthdr.len;
365 IF_ENQUEUE(&ifp->if_snd, m1);
366 if (m != NULL)
367 ifp->if_omcasts++;
368 ifp->if_obytes += len;
369 }
370 }
371 if (m != NULL) {
372 #if NBPFILTER > 0
373 /*
374 * If we forward packet into transmitter of the AP,
375 * we don't need to duplicate for DLT_EN10MB.
376 */
377 if (ifp->if_bpf && m1 == NULL)
378 bpf_mtap(ifp->if_bpf, m);
379 #endif
380 (*ifp->if_input)(ifp, m);
381 }
382 return;
383
384 case IEEE80211_FC0_TYPE_MGT:
385 if (dir != IEEE80211_FC1_DIR_NODS) {
386 ic->ic_stats.is_rx_wrongdir++;
387 goto err;
388 }
389 if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
390 ic->ic_stats.is_rx_ahdemo_mgt++;
391 goto out;
392 }
393 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
394
395 /* drop frames without interest */
396 if (ic->ic_state == IEEE80211_S_SCAN) {
397 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
398 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
399 ic->ic_stats.is_rx_mgtdiscard++;
400 goto out;
401 }
402 } else {
403 if (ic->ic_opmode != IEEE80211_M_IBSS &&
404 subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
405 ic->ic_stats.is_rx_mgtdiscard++;
406 goto out;
407 }
408 }
409
410 if (ifp->if_flags & IFF_DEBUG) {
411 /* avoid to print too many frames */
412 int doprint = 0;
413
414 switch (subtype) {
415 case IEEE80211_FC0_SUBTYPE_BEACON:
416 if (ic->ic_state == IEEE80211_S_SCAN)
417 doprint = 1;
418 break;
419 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
420 if (ic->ic_opmode == IEEE80211_M_IBSS)
421 doprint = 1;
422 break;
423 default:
424 doprint = 1;
425 break;
426 }
427 #ifdef IEEE80211_DEBUG
428 doprint += ieee80211_debug;
429 #endif
430 if (doprint)
431 if_printf(ifp, "received %s from %s rssi %d\n",
432 ieee80211_mgt_subtype_name[subtype
433 >> IEEE80211_FC0_SUBTYPE_SHIFT],
434 ether_sprintf(wh->i_addr2), rssi);
435 }
436 #if NBPFILTER > 0
437 if (ic->ic_rawbpf)
438 bpf_mtap(ic->ic_rawbpf, m);
439 #endif
440 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
441 m_freem(m);
442 return;
443
444 case IEEE80211_FC0_TYPE_CTL:
445 ic->ic_stats.is_rx_ctl++;
446 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
447 goto out;
448 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
449 if (subtype == IEEE80211_FC0_SUBTYPE_PS_POLL) {
450 /* XXX statistic */
451 /* Dump out a single packet from the host */
452 if (ifp->if_flags & IFF_DEBUG)
453 printf("%s: got power save probe from %s\n",
454 ifp->if_xname,
455 ether_sprintf(wh->i_addr2));
456 ieee80211_recv_pspoll(ic, m, rssi, rstamp);
457 }
458 goto out;
459 default:
460 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
461 ("%s: bad frame type %x\n", __func__, type));
462 /* should not come here */
463 break;
464 }
465 err:
466 ifp->if_ierrors++;
467 out:
468 if (m != NULL) {
469 #if NBPFILTER > 0
470 if (ic->ic_rawbpf)
471 bpf_mtap(ic->ic_rawbpf, m);
472 #endif
473 m_freem(m);
474 }
475 }
476
477 struct mbuf *
478 ieee80211_decap(struct ifnet *ifp, struct mbuf *m)
479 {
480 struct ether_header *eh;
481 struct ieee80211_frame wh;
482 struct llc *llc;
483
484 if (m->m_len < sizeof(wh) + sizeof(*llc)) {
485 m = m_pullup(m, sizeof(wh) + sizeof(*llc));
486 if (m == NULL)
487 return NULL;
488 }
489 memcpy(&wh, mtod(m, caddr_t), sizeof(wh));
490 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh));
491 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
492 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
493 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
494 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh));
495 llc = NULL;
496 } else {
497 m_adj(m, sizeof(wh) - sizeof(*eh));
498 }
499 eh = mtod(m, struct ether_header *);
500 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
501 case IEEE80211_FC1_DIR_NODS:
502 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
503 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
504 break;
505 case IEEE80211_FC1_DIR_TODS:
506 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
507 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
508 break;
509 case IEEE80211_FC1_DIR_FROMDS:
510 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
511 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
512 break;
513 case IEEE80211_FC1_DIR_DSTODS:
514 /* not yet supported */
515 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
516 ("%s: discard DS to DS frame\n", __func__));
517 m_freem(m);
518 return NULL;
519 }
520 #ifdef ALIGNED_POINTER
521 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) {
522 struct mbuf *n, *n0, **np;
523 caddr_t newdata;
524 int off, pktlen;
525
526 n0 = NULL;
527 np = &n0;
528 off = 0;
529 pktlen = m->m_pkthdr.len;
530 while (pktlen > off) {
531 if (n0 == NULL) {
532 MGETHDR(n, M_DONTWAIT, MT_DATA);
533 if (n == NULL) {
534 m_freem(m);
535 return NULL;
536 }
537 #ifdef __FreeBSD__
538 M_MOVE_PKTHDR(n, m);
539 #else
540 M_COPY_PKTHDR(n, m);
541 #endif
542 n->m_len = MHLEN;
543 } else {
544 MGET(n, M_DONTWAIT, MT_DATA);
545 if (n == NULL) {
546 m_freem(m);
547 m_freem(n0);
548 return NULL;
549 }
550 n->m_len = MLEN;
551 }
552 if (pktlen - off >= MINCLSIZE) {
553 MCLGET(n, M_DONTWAIT);
554 if (n->m_flags & M_EXT)
555 n->m_len = n->m_ext.ext_size;
556 }
557 if (n0 == NULL) {
558 newdata =
559 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) -
560 sizeof(*eh);
561 n->m_len -= newdata - n->m_data;
562 n->m_data = newdata;
563 }
564 if (n->m_len > pktlen - off)
565 n->m_len = pktlen - off;
566 m_copydata(m, off, n->m_len, mtod(n, caddr_t));
567 off += n->m_len;
568 *np = n;
569 np = &n->m_next;
570 }
571 m_freem(m);
572 m = n0;
573 }
574 #endif /* ALIGNED_POINTER */
575 if (llc != NULL) {
576 eh = mtod(m, struct ether_header *);
577 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh));
578 }
579 return m;
580 }
581
582 /*
583 * Install received rate set information in the node's state block.
584 */
585 static int
586 ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
587 u_int8_t *rates, u_int8_t *xrates, int flags)
588 {
589 struct ieee80211_rateset *rs = &ni->ni_rates;
590
591 memset(rs, 0, sizeof(*rs));
592 rs->rs_nrates = rates[1];
593 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates);
594 if (xrates != NULL) {
595 u_int8_t nxrates;
596 /*
597 * Tack on 11g extended supported rate element.
598 */
599 nxrates = xrates[1];
600 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
601 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
602 IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE,
603 ("%s: extended rate set too large;"
604 " only using %u of %u rates\n",
605 __func__, nxrates, xrates[1]));
606 ic->ic_stats.is_rx_rstoobig++;
607 }
608 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
609 rs->rs_nrates += nxrates;
610 }
611 return ieee80211_fix_rate(ic, ni, flags);
612 }
613
614 /* Verify the existence and length of __elem or get out. */
615 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
616 if ((__elem) == NULL) { \
617 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ELEMID, \
618 ("%s: no " #__elem "in %s frame\n", \
619 __func__, ieee80211_mgt_subtype_name[subtype >> \
620 IEEE80211_FC0_SUBTYPE_SHIFT])); \
621 ic->ic_stats.is_rx_elem_missing++; \
622 return; \
623 } \
624 if ((__elem)[1] > (__maxlen)) { \
625 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ELEMID, \
626 ("%s: bad " #__elem " len %d in %s frame from %s\n",\
627 __func__, (__elem)[1], \
628 ieee80211_mgt_subtype_name[subtype >> \
629 IEEE80211_FC0_SUBTYPE_SHIFT], \
630 ether_sprintf(wh->i_addr2))); \
631 ic->ic_stats.is_rx_elem_toobig++; \
632 return; \
633 } \
634 } while (0)
635
636 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
637 if ((_len) < (_minlen)) { \
638 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ELEMID, \
639 ("%s: %s frame too short from %s\n", \
640 __func__, \
641 ieee80211_mgt_subtype_name[subtype >> \
642 IEEE80211_FC0_SUBTYPE_SHIFT], \
643 ether_sprintf(wh->i_addr2))); \
644 ic->ic_stats.is_rx_elem_toosmall++; \
645 return; \
646 } \
647 } while (0)
648
649 static void
650 ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh,
651 struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq,
652 u_int16_t status)
653 {
654 struct ifnet *ifp = &ic->ic_if;
655 int allocbs;
656 switch (ic->ic_opmode) {
657 case IEEE80211_M_IBSS:
658 if (ic->ic_state != IEEE80211_S_RUN ||
659 seq != IEEE80211_AUTH_OPEN_REQUEST) {
660 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
661 ("%s: discard auth from %s; state %u, seq %u\n",
662 __func__, ether_sprintf(wh->i_addr2),
663 ic->ic_state, seq));
664 ic->ic_stats.is_rx_bad_auth++;
665 return;
666 }
667 ieee80211_new_state(ic, IEEE80211_S_AUTH,
668 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
669 break;
670
671 case IEEE80211_M_AHDEMO:
672 /* should not come here */
673 break;
674
675 case IEEE80211_M_HOSTAP:
676 if (ic->ic_state != IEEE80211_S_RUN ||
677 seq != IEEE80211_AUTH_OPEN_REQUEST) {
678 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
679 ("%s: discard auth from %s; state %u, seq %u\n",
680 __func__, ether_sprintf(wh->i_addr2),
681 ic->ic_state, seq));
682 ic->ic_stats.is_rx_bad_auth++;
683 return;
684 }
685 if (ni == ic->ic_bss) {
686 ni = ieee80211_alloc_node(ic, wh->i_addr2);
687 if (ni == NULL) {
688 ic->ic_stats.is_rx_nodealloc++;
689 return;
690 }
691 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
692 ni->ni_rssi = rssi;
693 ni->ni_rstamp = rstamp;
694 ni->ni_chan = ic->ic_bss->ni_chan;
695 allocbs = 1;
696 } else
697 allocbs = 0;
698 IEEE80211_SEND_MGMT(ic, ni,
699 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
700 if (ifp->if_flags & IFF_DEBUG)
701 if_printf(ifp, "station %s %s authenticated (open)\n",
702 ether_sprintf(ni->ni_macaddr),
703 (allocbs ? "newly" : "already"));
704 break;
705 case IEEE80211_M_STA:
706 if (ic->ic_state != IEEE80211_S_AUTH ||
707 seq != IEEE80211_AUTH_OPEN_RESPONSE) {
708 ic->ic_stats.is_rx_bad_auth++;
709 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
710 ("%s: discard auth from %s; state %u, seq %u\n",
711 __func__, ether_sprintf(wh->i_addr2),
712 ic->ic_state, seq));
713 return;
714 }
715 if (status != 0) {
716 if_printf(&ic->ic_if,
717 "open authentication failed (reason %d) for %s\n",
718 status,
719 ether_sprintf(wh->i_addr3));
720 if (ni != ic->ic_bss)
721 ni->ni_fails++;
722 ic->ic_stats.is_rx_auth_fail++;
723 return;
724 }
725 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
726 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
727 break;
728 case IEEE80211_M_MONITOR:
729 break;
730 }
731 }
732
733 /* TBD send appropriate responses on error? */
734 static void
735 ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh,
736 u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi,
737 u_int32_t rstamp, u_int16_t seq, u_int16_t status)
738 {
739 u_int8_t *challenge = NULL;
740 int allocbs, i;
741
742 if ((ic->ic_flags & IEEE80211_F_WEPON) == 0) {
743 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
744 ("%s: WEP is off\n", __func__));
745 return;
746 }
747
748 if (frm + 1 < efrm) {
749 if (frm[1] + 2 > efrm - frm) {
750 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
751 ("%s: elt %d %d bytes too long\n", __func__,
752 frm[0], (frm[1] + 2) - (int)(efrm - frm)));
753 ic->ic_stats.is_rx_bad_auth++;
754 return;
755 }
756 if (*frm == IEEE80211_ELEMID_CHALLENGE)
757 challenge = frm;
758 frm += frm[1] + 2;
759 }
760 switch (seq) {
761 case IEEE80211_AUTH_SHARED_CHALLENGE:
762 case IEEE80211_AUTH_SHARED_RESPONSE:
763 if (challenge == NULL) {
764 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
765 ("%s: no challenge sent\n", __func__));
766 ic->ic_stats.is_rx_bad_auth++;
767 return;
768 }
769 if (challenge[1] != IEEE80211_CHALLENGE_LEN) {
770 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
771 ("%s: bad challenge len %d\n",
772 __func__, challenge[1]));
773 ic->ic_stats.is_rx_bad_auth++;
774 return;
775 }
776 default:
777 break;
778 }
779 switch (ic->ic_opmode) {
780 case IEEE80211_M_MONITOR:
781 case IEEE80211_M_AHDEMO:
782 case IEEE80211_M_IBSS:
783 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
784 ("%s: unexpected operating mode\n", __func__));
785 return;
786 case IEEE80211_M_HOSTAP:
787 if (ic->ic_state != IEEE80211_S_RUN) {
788 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
789 ("%s: not running\n", __func__));
790 return;
791 }
792 switch (seq) {
793 case IEEE80211_AUTH_SHARED_REQUEST:
794 if (ni == ic->ic_bss) {
795 ni = ieee80211_alloc_node(ic, wh->i_addr2);
796 if (ni == NULL) {
797 ic->ic_stats.is_rx_nodealloc++;
798 return;
799 }
800 IEEE80211_ADDR_COPY(ni->ni_bssid,
801 ic->ic_bss->ni_bssid);
802 ni->ni_rssi = rssi;
803 ni->ni_rstamp = rstamp;
804 ni->ni_chan = ic->ic_bss->ni_chan;
805 allocbs = 1;
806 } else
807 allocbs = 0;
808 if (ni->ni_challenge == NULL)
809 ni->ni_challenge = (u_int32_t*)malloc(
810 IEEE80211_CHALLENGE_LEN, M_DEVBUF,
811 M_NOWAIT);
812 if (ni->ni_challenge == NULL) {
813 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
814 ("%s: challenge alloc failed\n",
815 __func__));
816 /* XXX statistic */
817 return;
818 }
819 for (i = IEEE80211_CHALLENGE_LEN / sizeof(u_int32_t);
820 --i >= 0; )
821 ni->ni_challenge[i] = arc4random();
822 IEEE80211_DPRINTF(ic,
823 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
824 ("shared key %sauth request from station %s\n",
825 (allocbs ? "" : "re"),
826 ether_sprintf(ni->ni_macaddr)));
827 break;
828 case IEEE80211_AUTH_SHARED_RESPONSE:
829 if (ni == ic->ic_bss) {
830 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
831 ("%s: unknown STA\n", __func__));
832 return;
833 }
834 if (ni->ni_challenge == NULL) {
835 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
836 ("%s: no challenge recorded\n",
837 __func__));
838 ic->ic_stats.is_rx_bad_auth++;
839 return;
840 }
841 if (memcmp(ni->ni_challenge, &challenge[2],
842 challenge[1]) != 0) {
843 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
844 ("%s: challenge mismatch\n", __func__));
845 ic->ic_stats.is_rx_auth_fail++;
846 return;
847 }
848 IEEE80211_DPRINTF(ic,
849 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
850 ("station %s authenticated (shared key)\n",
851 ether_sprintf(ni->ni_macaddr)));
852 break;
853 default:
854 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
855 ("%s: bad shared key auth seq %d from %s\n",
856 __func__, seq, ether_sprintf(wh->i_addr2)));
857 ic->ic_stats.is_rx_bad_auth++;
858 return;
859 }
860 IEEE80211_SEND_MGMT(ic, ni,
861 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
862 break;
863
864 case IEEE80211_M_STA:
865 if (ic->ic_state != IEEE80211_S_AUTH)
866 return;
867 switch (seq) {
868 case IEEE80211_AUTH_SHARED_PASS:
869 if (ni->ni_challenge != NULL) {
870 FREE(ni->ni_challenge, M_DEVBUF);
871 ni->ni_challenge = NULL;
872 }
873 if (status != 0) {
874 IEEE80211_DPRINTF(ic,
875 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
876 ("%s: auth failed (reason %d) for %s\n",
877 __func__, status,
878 ether_sprintf(wh->i_addr3)));
879 if (ni != ic->ic_bss)
880 ni->ni_fails++;
881 ic->ic_stats.is_rx_auth_fail++;
882 return;
883 }
884 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
885 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
886 break;
887 case IEEE80211_AUTH_SHARED_CHALLENGE:
888 if (ni->ni_challenge == NULL)
889 ni->ni_challenge = (u_int32_t*)malloc(
890 challenge[1], M_DEVBUF, M_NOWAIT);
891 if (ni->ni_challenge == NULL) {
892 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
893 ("%s: challenge alloc failed\n", __func__));
894 /* XXX statistic */
895 return;
896 }
897 memcpy(ni->ni_challenge, &challenge[2], challenge[1]);
898 IEEE80211_SEND_MGMT(ic, ni,
899 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
900 break;
901 default:
902 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
903 ("%s: bad seq %d from %s\n", __func__, seq,
904 ether_sprintf(wh->i_addr2)));
905 ic->ic_stats.is_rx_bad_auth++;
906 return;
907 }
908 break;
909 }
910 }
911
912 void
913 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
914 struct ieee80211_node *ni,
915 int subtype, int rssi, u_int32_t rstamp)
916 {
917 struct ifnet *ifp = &ic->ic_if;
918 struct ieee80211_frame *wh;
919 u_int8_t *frm, *efrm;
920 u_int8_t *ssid, *rates, *xrates;
921 int reassoc, resp, newassoc, allocbs;
922
923 wh = mtod(m0, struct ieee80211_frame *);
924 frm = (u_int8_t *)&wh[1];
925 efrm = mtod(m0, u_int8_t *) + m0->m_len;
926 switch (subtype) {
927 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
928 case IEEE80211_FC0_SUBTYPE_BEACON: {
929 u_int8_t *tstamp, *bintval, *capinfo, *country;
930 u_int8_t chan, bchan, fhindex, erp;
931 u_int16_t fhdwell;
932 int isprobe;
933
934 if (ic->ic_opmode != IEEE80211_M_IBSS &&
935 ic->ic_state != IEEE80211_S_SCAN) {
936 /* XXX: may be useful for background scan */
937 return;
938 }
939 isprobe = (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP);
940
941 /*
942 * beacon/probe response frame format
943 * [8] time stamp
944 * [2] beacon interval
945 * [2] capability information
946 * [tlv] ssid
947 * [tlv] supported rates
948 * [tlv] country information
949 * [tlv] parameter set (FH/DS)
950 * [tlv] erp information
951 * [tlv] extended supported rates
952 */
953 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
954 tstamp = frm; frm += 8;
955 bintval = frm; frm += 2;
956 capinfo = frm; frm += 2;
957 ssid = rates = xrates = country = NULL;
958 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
959 chan = bchan;
960 fhdwell = 0;
961 fhindex = 0;
962 erp = 0;
963 while (frm < efrm) {
964 switch (*frm) {
965 case IEEE80211_ELEMID_SSID:
966 ssid = frm;
967 break;
968 case IEEE80211_ELEMID_RATES:
969 rates = frm;
970 break;
971 case IEEE80211_ELEMID_COUNTRY:
972 country = frm;
973 break;
974 case IEEE80211_ELEMID_FHPARMS:
975 if (ic->ic_phytype == IEEE80211_T_FH) {
976 fhdwell = (frm[3] << 8) | frm[2];
977 chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
978 fhindex = frm[6];
979 }
980 break;
981 case IEEE80211_ELEMID_DSPARMS:
982 /*
983 * XXX hack this since depending on phytype
984 * is problematic for multi-mode devices.
985 */
986 if (ic->ic_phytype != IEEE80211_T_FH)
987 chan = frm[2];
988 break;
989 case IEEE80211_ELEMID_TIM:
990 break;
991 case IEEE80211_ELEMID_IBSSPARMS:
992 break;
993 case IEEE80211_ELEMID_XRATES:
994 xrates = frm;
995 break;
996 case IEEE80211_ELEMID_ERP:
997 if (frm[1] != 1) {
998 IEEE80211_DPRINTF(ic,
999 IEEE80211_MSG_ELEMID,
1000 ("%s: invalid ERP element; "
1001 "length %u, expecting 1\n",
1002 __func__, frm[1]));
1003 ic->ic_stats.is_rx_elem_toobig++;
1004 break;
1005 }
1006 erp = frm[2];
1007 break;
1008 default:
1009 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ELEMID,
1010 ("%s: element id %u/len %u ignored\n",
1011 __func__, *frm, frm[1]));
1012 ic->ic_stats.is_rx_elem_unknown++;
1013 break;
1014 }
1015 frm += frm[1] + 2;
1016 }
1017 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1018 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1019 if (
1020 #if IEEE80211_CHAN_MAX < 255
1021 chan > IEEE80211_CHAN_MAX ||
1022 #endif
1023 isclr(ic->ic_chan_active, chan)) {
1024 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ELEMID,
1025 ("%s: ignore %s with invalid channel %u\n",
1026 __func__,
1027 isprobe ? "probe response" : "beacon",
1028 chan));
1029 ic->ic_stats.is_rx_badchan++;
1030 return;
1031 }
1032 if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) {
1033 /*
1034 * Frame was received on a channel different from the
1035 * one indicated in the DS params element id;
1036 * silently discard it.
1037 *
1038 * NB: this can happen due to signal leakage.
1039 * But we should take it for FH phy because
1040 * the rssi value should be correct even for
1041 * different hop pattern in FH.
1042 */
1043 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ELEMID,
1044 ("%s: ignore %s on channel %u marked "
1045 "for channel %u\n", __func__,
1046 isprobe ? "probe response" : "beacon",
1047 bchan, chan));
1048 ic->ic_stats.is_rx_chanmismatch++;
1049 return;
1050 }
1051
1052 /*
1053 * Use mac and channel for lookup so we collect all
1054 * potential AP's when scanning. Otherwise we may
1055 * see the same AP on multiple channels and will only
1056 * record the last one. We could filter APs here based
1057 * on rssi, etc. but leave that to the end of the scan
1058 * so we can keep the selection criteria in one spot.
1059 * This may result in a bloat of the scanned AP list but
1060 * it shouldn't be too much.
1061 */
1062 ni = ieee80211_lookup_node(ic, wh->i_addr2,
1063 &ic->ic_channels[chan]);
1064 #ifdef IEEE80211_DEBUG
1065 if (ieee80211_debug &&
1066 (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) {
1067 printf("%s: %s%s on chan %u (bss chan %u) ",
1068 __func__, (ni == NULL ? "new " : ""),
1069 isprobe ? "probe response" : "beacon",
1070 chan, bchan);
1071 ieee80211_print_essid(ssid + 2, ssid[1]);
1072 printf(" from %s\n", ether_sprintf(wh->i_addr2));
1073 printf("%s: caps 0x%x bintval %u erp 0x%x\n",
1074 __func__, le16toh(*(u_int16_t *)capinfo),
1075 le16toh(*(u_int16_t *)bintval), erp);
1076 if (country) {
1077 int i;
1078 printf("%s: country info", __func__);
1079 for (i = 0; i < country[1]; i++)
1080 printf(" %02x", country[i+2]);
1081 printf("\n");
1082 }
1083 }
1084 #endif
1085 if (ni == NULL) {
1086 ni = ieee80211_alloc_node(ic, wh->i_addr2);
1087 if (ni == NULL)
1088 return;
1089 ni->ni_esslen = ssid[1];
1090 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1091 memcpy(ni->ni_essid, ssid + 2, ssid[1]);
1092 allocbs = 1;
1093 } else if (ssid[1] != 0 && (isprobe || ni->ni_esslen == 0)) {
1094 /*
1095 * Update ESSID at probe response to adopt hidden AP by
1096 * Lucent/Cisco, which announces null ESSID in beacon.
1097 */
1098 ni->ni_esslen = ssid[1];
1099 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1100 memcpy(ni->ni_essid, ssid + 2, ssid[1]);
1101 allocbs = 0;
1102 } else
1103 allocbs = 0;
1104 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
1105 ni->ni_rssi = rssi;
1106 ni->ni_rstamp = rstamp;
1107 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp));
1108 ni->ni_intval = le16toh(*(u_int16_t *)bintval);
1109 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo);
1110 /* XXX validate channel # */
1111 ni->ni_chan = &ic->ic_channels[chan];
1112 ni->ni_fhdwell = fhdwell;
1113 ni->ni_fhindex = fhindex;
1114 ni->ni_erp = erp;
1115 /* NB: must be after ni_chan is setup */
1116 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
1117 /*
1118 * When scanning we record results (nodes) with a zero
1119 * refcnt. Otherwise we want to hold the reference for
1120 * ibss neighbors so the nodes don't get released prematurely.
1121 * Anything else can be discarded (XXX and should be handled
1122 * above so we don't do so much work).
1123 */
1124 if (ic->ic_state == IEEE80211_S_SCAN)
1125 ieee80211_unref_node(&ni); /* NB: do not free */
1126 else if (ic->ic_opmode == IEEE80211_M_IBSS &&
1127 allocbs && isprobe) {
1128 /*
1129 * Fake an association so the driver can setup it's
1130 * private state. The rate set has been setup above;
1131 * there is no handshake as in ap/station operation.
1132 */
1133 if (ic->ic_newassoc)
1134 (*ic->ic_newassoc)(ic, ni, 1);
1135 /* NB: hold reference */
1136 } else {
1137 /* XXX optimize to avoid work done above */
1138 ieee80211_free_node(ic, ni);
1139 }
1140 break;
1141 }
1142
1143 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: {
1144 u_int8_t rate;
1145
1146 if (ic->ic_opmode == IEEE80211_M_STA)
1147 return;
1148 if (ic->ic_state != IEEE80211_S_RUN)
1149 return;
1150
1151 /*
1152 * prreq frame format
1153 * [tlv] ssid
1154 * [tlv] supported rates
1155 * [tlv] extended supported rates
1156 */
1157 ssid = rates = xrates = NULL;
1158 while (frm < efrm) {
1159 switch (*frm) {
1160 case IEEE80211_ELEMID_SSID:
1161 ssid = frm;
1162 break;
1163 case IEEE80211_ELEMID_RATES:
1164 rates = frm;
1165 break;
1166 case IEEE80211_ELEMID_XRATES:
1167 xrates = frm;
1168 break;
1169 }
1170 frm += frm[1] + 2;
1171 }
1172 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1173 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1174 if (ssid[1] != 0 &&
1175 (ssid[1] != ic->ic_bss->ni_esslen ||
1176 memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) {
1177 #ifdef IEEE80211_DEBUG
1178 if (ieee80211_debug) {
1179 printf("%s: ssid mismatch ", __func__);
1180 ieee80211_print_essid(ssid + 2, ssid[1]);
1181 printf(" from %s\n", ether_sprintf(wh->i_addr2));
1182 }
1183 #endif
1184 ic->ic_stats.is_rx_ssidmismatch++;
1185 return;
1186 }
1187
1188 if (ni == ic->ic_bss) {
1189 ni = ieee80211_dup_bss(ic, wh->i_addr2);
1190 if (ni == NULL)
1191 return;
1192 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1193 ("%s: new probe req from %s\n",
1194 __func__, ether_sprintf(wh->i_addr2)));
1195 allocbs = 1;
1196 } else
1197 allocbs = 0;
1198 ni->ni_rssi = rssi;
1199 ni->ni_rstamp = rstamp;
1200 rate = ieee80211_setup_rates(ic, ni, rates, xrates,
1201 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
1202 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1203 if (rate & IEEE80211_RATE_BASIC) {
1204 IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE,
1205 ("%s: rate negotiation failed: %s\n",
1206 __func__,ether_sprintf(wh->i_addr2)));
1207 } else {
1208 IEEE80211_SEND_MGMT(ic, ni,
1209 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
1210 }
1211 if (allocbs)
1212 ieee80211_free_node(ic, ni);
1213 break;
1214 }
1215
1216 case IEEE80211_FC0_SUBTYPE_AUTH: {
1217 u_int16_t algo, seq, status;
1218 /*
1219 * auth frame format
1220 * [2] algorithm
1221 * [2] sequence
1222 * [2] status
1223 * [tlv*] challenge
1224 */
1225 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
1226 algo = le16toh(*(u_int16_t *)frm);
1227 seq = le16toh(*(u_int16_t *)(frm + 2));
1228 status = le16toh(*(u_int16_t *)(frm + 4));
1229 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
1230 ("%s: algorithm %d seq %d from %s\n",
1231 __func__, algo, seq, ether_sprintf(wh->i_addr2)));
1232
1233 if (algo == IEEE80211_AUTH_ALG_SHARED)
1234 ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi,
1235 rstamp, seq, status);
1236 else if (algo == IEEE80211_AUTH_ALG_OPEN)
1237 ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq,
1238 status);
1239 else {
1240 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1241 ("%s: unsupported auth algorithm %d from %s\n",
1242 __func__, algo, ether_sprintf(wh->i_addr2)));
1243 ic->ic_stats.is_rx_auth_unsupported++;
1244 return;
1245 }
1246 break;
1247 }
1248
1249 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1250 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
1251 u_int16_t capinfo, bintval;
1252
1253 if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
1254 (ic->ic_state != IEEE80211_S_RUN))
1255 return;
1256
1257 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
1258 reassoc = 1;
1259 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
1260 } else {
1261 reassoc = 0;
1262 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
1263 }
1264 /*
1265 * asreq frame format
1266 * [2] capability information
1267 * [2] listen interval
1268 * [6*] current AP address (reassoc only)
1269 * [tlv] ssid
1270 * [tlv] supported rates
1271 * [tlv] extended supported rates
1272 */
1273 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4));
1274 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
1275 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1276 ("%s: ignore assoc request with bss %s not "
1277 "our own\n",
1278 __func__, ether_sprintf(wh->i_addr2)));
1279 ic->ic_stats.is_rx_assoc_bss++;
1280 return;
1281 }
1282 capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
1283 bintval = le16toh(*(u_int16_t *)frm); frm += 2;
1284 if (reassoc)
1285 frm += 6; /* ignore current AP info */
1286 ssid = rates = xrates = NULL;
1287 while (frm < efrm) {
1288 switch (*frm) {
1289 case IEEE80211_ELEMID_SSID:
1290 ssid = frm;
1291 break;
1292 case IEEE80211_ELEMID_RATES:
1293 rates = frm;
1294 break;
1295 case IEEE80211_ELEMID_XRATES:
1296 xrates = frm;
1297 break;
1298 }
1299 frm += frm[1] + 2;
1300 }
1301 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1302 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1303 if (ssid[1] != ic->ic_bss->ni_esslen ||
1304 memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) {
1305 #ifdef IEEE80211_DEBUG
1306 if (ieee80211_debug) {
1307 printf("%s: ssid mismatch ", __func__);
1308 ieee80211_print_essid(ssid + 2, ssid[1]);
1309 printf(" from %s\n", ether_sprintf(wh->i_addr2));
1310 }
1311 #endif
1312 ic->ic_stats.is_rx_ssidmismatch++;
1313 return;
1314 }
1315 if (ni == ic->ic_bss) {
1316 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1317 ("%s: deny %sassoc from %s, not authenticated\n",
1318 __func__, reassoc ? "re" : "",
1319 ether_sprintf(wh->i_addr2)));
1320 ni = ieee80211_dup_bss(ic, wh->i_addr2);
1321 if (ni != NULL) {
1322 IEEE80211_SEND_MGMT(ic, ni,
1323 IEEE80211_FC0_SUBTYPE_DEAUTH,
1324 IEEE80211_REASON_ASSOC_NOT_AUTHED);
1325 ieee80211_free_node(ic, ni);
1326 }
1327 ic->ic_stats.is_rx_assoc_notauth++;
1328 return;
1329 }
1330 /* discard challenge after association */
1331 if (ni->ni_challenge != NULL) {
1332 FREE(ni->ni_challenge, M_DEVBUF);
1333 ni->ni_challenge = NULL;
1334 }
1335 /* XXX per-node cipher suite */
1336 /* XXX some stations use the privacy bit for handling APs
1337 that suport both encrypted and unencrypted traffic */
1338 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 ||
1339 (capinfo & IEEE80211_CAPINFO_PRIVACY) !=
1340 ((ic->ic_flags & IEEE80211_F_WEPON) ?
1341 IEEE80211_CAPINFO_PRIVACY : 0)) {
1342 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1343 ("%s: capability mismatch %x for %s\n",
1344 __func__, capinfo, ether_sprintf(wh->i_addr2)));
1345 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap);
1346 ni->ni_associd = 0;
1347 IEEE80211_SEND_MGMT(ic, ni, resp,
1348 IEEE80211_STATUS_CAPINFO);
1349 ic->ic_stats.is_rx_assoc_capmismatch++;
1350 return;
1351 }
1352 ieee80211_setup_rates(ic, ni, rates, xrates,
1353 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
1354 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1355 if (ni->ni_rates.rs_nrates == 0) {
1356 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1357 ("%s: rate mismatch for %s\n",
1358 __func__, ether_sprintf(wh->i_addr2)));
1359 IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap);
1360 ni->ni_associd = 0;
1361 IEEE80211_SEND_MGMT(ic, ni, resp,
1362 IEEE80211_STATUS_BASIC_RATE);
1363 ic->ic_stats.is_rx_assoc_norate++;
1364 return;
1365 }
1366 ni->ni_rssi = rssi;
1367 ni->ni_rstamp = rstamp;
1368 ni->ni_intval = bintval;
1369 ni->ni_capinfo = capinfo;
1370 ni->ni_chan = ic->ic_bss->ni_chan;
1371 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
1372 ni->ni_fhindex = ic->ic_bss->ni_fhindex;
1373 if (ni->ni_associd == 0) {
1374 u_int16_t aid;
1375
1376 /*
1377 * It would be clever to search the bitmap
1378 * more efficiently, but this will do for now.
1379 */
1380 for (aid = 1; aid < ic->ic_max_aid; aid++) {
1381 if (!IEEE80211_AID_ISSET(aid,
1382 ic->ic_aid_bitmap))
1383 break;
1384 }
1385
1386 if (ic->ic_bss->ni_associd >= ic->ic_max_aid) {
1387 IEEE80211_SEND_MGMT(ic, ni, resp,
1388 IEEE80211_REASON_ASSOC_TOOMANY);
1389 return;
1390 } else {
1391 ni->ni_associd = aid | 0xc000;
1392 IEEE80211_AID_SET(ni->ni_associd,
1393 ic->ic_aid_bitmap);
1394 newassoc = 1;
1395 }
1396 } else
1397 newassoc = 0;
1398 /* XXX for 11g must turn off short slot time if long
1399 slot time sta associates */
1400 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
1401 if (ifp->if_flags & IFF_DEBUG)
1402 if_printf(ifp, "station %s %s associated at aid %d\n",
1403 (newassoc ? "newly" : "already"),
1404 ether_sprintf(ni->ni_macaddr),
1405 ni->ni_associd & ~0xc000);
1406 /* give driver a chance to setup state like ni_txrate */
1407 if (ic->ic_newassoc)
1408 (*ic->ic_newassoc)(ic, ni, newassoc);
1409 break;
1410 }
1411
1412 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
1413 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
1414 u_int16_t status;
1415
1416 if (ic->ic_opmode != IEEE80211_M_STA ||
1417 ic->ic_state != IEEE80211_S_ASSOC)
1418 return;
1419
1420 /*
1421 * asresp frame format
1422 * [2] capability information
1423 * [2] status
1424 * [2] association ID
1425 * [tlv] supported rates
1426 * [tlv] extended supported rates
1427 */
1428 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
1429 ni = ic->ic_bss;
1430 ni->ni_capinfo = le16toh(*(u_int16_t *)frm);
1431 frm += 2;
1432
1433 status = le16toh(*(u_int16_t *)frm);
1434 frm += 2;
1435 if (status != 0) {
1436 if (ifp->if_flags & IFF_DEBUG)
1437 if_printf(ifp,
1438 "association failed (reason %d) for %s\n",
1439 status, ether_sprintf(wh->i_addr3));
1440 if (ni != ic->ic_bss)
1441 ni->ni_fails++;
1442 ic->ic_stats.is_rx_auth_fail++;
1443 return;
1444 }
1445 ni->ni_associd = le16toh(*(u_int16_t *)frm);
1446 frm += 2;
1447
1448 rates = xrates = NULL;
1449 while (frm < efrm) {
1450 switch (*frm) {
1451 case IEEE80211_ELEMID_RATES:
1452 rates = frm;
1453 break;
1454 case IEEE80211_ELEMID_XRATES:
1455 xrates = frm;
1456 break;
1457 }
1458 frm += frm[1] + 2;
1459 }
1460
1461 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1462 ieee80211_setup_rates(ic, ni, rates, xrates,
1463 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
1464 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1465 if (ni->ni_rates.rs_nrates != 0)
1466 ieee80211_new_state(ic, IEEE80211_S_RUN,
1467 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1468 break;
1469 }
1470
1471 case IEEE80211_FC0_SUBTYPE_DEAUTH: {
1472 u_int16_t reason;
1473 /*
1474 * deauth frame format
1475 * [2] reason
1476 */
1477 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1478 reason = le16toh(*(u_int16_t *)frm);
1479 ic->ic_stats.is_rx_deauth++;
1480 switch (ic->ic_opmode) {
1481 case IEEE80211_M_STA:
1482 ieee80211_new_state(ic, IEEE80211_S_AUTH,
1483 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1484 break;
1485 case IEEE80211_M_HOSTAP:
1486 if (ni != ic->ic_bss) {
1487 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
1488 ("station %s deauthenticated by "
1489 "peer (reason %d)\n",
1490 ether_sprintf(ni->ni_macaddr), reason));
1491 /* node will be free'd on return */
1492 ieee80211_unref_node(&ni);
1493 }
1494 break;
1495 default:
1496 break;
1497 }
1498 break;
1499 }
1500
1501 case IEEE80211_FC0_SUBTYPE_DISASSOC: {
1502 u_int16_t reason;
1503 /*
1504 * disassoc frame format
1505 * [2] reason
1506 */
1507 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1508 reason = le16toh(*(u_int16_t *)frm);
1509 ic->ic_stats.is_rx_disassoc++;
1510 switch (ic->ic_opmode) {
1511 case IEEE80211_M_STA:
1512 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
1513 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1514 break;
1515 case IEEE80211_M_HOSTAP:
1516 if (ni != ic->ic_bss) {
1517 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1518 ("station %s disassociated by "
1519 "peer (reason %d)\n",
1520 ether_sprintf(ni->ni_macaddr), reason));
1521 IEEE80211_AID_CLR(ni->ni_associd,
1522 ic->ic_aid_bitmap);
1523 ni->ni_associd = 0;
1524 /* XXX node reclaimed how? */
1525 }
1526 break;
1527 default:
1528 break;
1529 }
1530 break;
1531 }
1532 default:
1533 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1534 ("%s: mgmt frame with subtype 0x%x not handled\n",
1535 __func__, subtype));
1536 ic->ic_stats.is_rx_badsubtype++;
1537 break;
1538 }
1539 }
1540
1541 static void
1542 ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m0, int rssi,
1543 u_int32_t rstamp)
1544 {
1545 struct ifnet *ifp = &ic->ic_if;
1546 struct ieee80211_frame *wh;
1547 struct ieee80211_node *ni;
1548 struct mbuf *m;
1549 u_int16_t aid;
1550
1551 if (ic->ic_set_tim == NULL) /* No powersaving functionality */
1552 return;
1553
1554 wh = mtod(m0, struct ieee80211_frame *);
1555
1556 if ((ni = ieee80211_find_node(ic, wh->i_addr2)) == NULL) {
1557 if (ifp->if_flags & IFF_DEBUG)
1558 printf("%s: station %s sent bogus power save poll\n",
1559 ifp->if_xname, ether_sprintf(wh->i_addr2));
1560 return;
1561 }
1562
1563 memcpy(&aid, wh->i_dur, sizeof(wh->i_dur));
1564 if ((aid & 0xc000) != 0xc000) {
1565 if (ifp->if_flags & IFF_DEBUG)
1566 printf("%s: station %s sent bogus aid %x\n",
1567 ifp->if_xname, ether_sprintf(wh->i_addr2), aid);
1568 return;
1569 }
1570
1571 if (aid != ni->ni_associd) {
1572 if (ifp->if_flags & IFF_DEBUG)
1573 printf("%s: station %s aid %x doesn't match pspoll "
1574 "aid %x\n",
1575 ifp->if_xname, ether_sprintf(wh->i_addr2),
1576 ni->ni_associd, aid);
1577 return;
1578 }
1579
1580 /* Okay, take the first queued packet and put it out... */
1581
1582 IF_DEQUEUE(&ni->ni_savedq, m);
1583 if (m == NULL) {
1584 if (ifp->if_flags & IFF_DEBUG)
1585 printf("%s: station %s sent pspoll, "
1586 "but no packets are saved\n",
1587 ifp->if_xname, ether_sprintf(wh->i_addr2));
1588 return;
1589 }
1590 wh = mtod(m, struct ieee80211_frame *);
1591
1592 /*
1593 * If this is the last packet, turn off the TIM fields.
1594 * If there are more packets, set the more packets bit.
1595 */
1596
1597 if (IF_IS_EMPTY(&ni->ni_savedq)) {
1598 if (ic->ic_set_tim)
1599 ic->ic_set_tim(ic, ni->ni_associd, 0);
1600 } else {
1601 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
1602 }
1603
1604 if (ifp->if_flags & IFF_DEBUG)
1605 printf("%s: enqueued power saving packet for station %s\n",
1606 ifp->if_xname, ether_sprintf(ni->ni_macaddr));
1607
1608 IF_ENQUEUE(&ic->ic_pwrsaveq, m);
1609 (*ifp->if_start)(ifp);
1610 }
1611 #undef IEEE80211_VERIFY_LENGTH
1612 #undef IEEE80211_VERIFY_ELEMENT
1613