Annotation of sys/net80211/ieee80211_input.c, Revision 1.1.1.1
1.1 nbrk 1: /* $NetBSD: ieee80211_input.c,v 1.24 2004/05/31 11:12:24 dyoung Exp $ */
2: /* $OpenBSD: ieee80211_input.c,v 1.63 2007/08/16 14:59:14 deraadt Exp $ */
3: /*-
4: * Copyright (c) 2001 Atsushi Onoe
5: * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
6: * Copyright (c) 2007 Damien Bergamini
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. The name of the author may not be used to endorse or promote products
18: * derived from this software without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30: */
31:
32: #include "bpfilter.h"
33:
34: #include <sys/param.h>
35: #include <sys/systm.h>
36: #include <sys/mbuf.h>
37: #include <sys/malloc.h>
38: #include <sys/kernel.h>
39: #include <sys/socket.h>
40: #include <sys/sockio.h>
41: #include <sys/endian.h>
42: #include <sys/errno.h>
43: #include <sys/proc.h>
44: #include <sys/sysctl.h>
45: #include <sys/endian.h>
46:
47: #include <net/if.h>
48: #include <net/if_dl.h>
49: #include <net/if_media.h>
50: #include <net/if_arp.h>
51: #include <net/if_llc.h>
52:
53: #if NBPFILTER > 0
54: #include <net/bpf.h>
55: #endif
56:
57: #ifdef INET
58: #include <netinet/in.h>
59: #include <netinet/if_ether.h>
60: #endif
61:
62: #include <net80211/ieee80211_var.h>
63:
64: #include <dev/rndvar.h>
65:
66:
67: int ieee80211_setup_rates(struct ieee80211com *, struct ieee80211_node *,
68: const u_int8_t *, const u_int8_t *, int);
69: void ieee80211_auth_open(struct ieee80211com *,
70: const struct ieee80211_frame *, struct ieee80211_node *, int,
71: u_int32_t, u_int16_t, u_int16_t);
72: int ieee80211_parse_edca_params_body(struct ieee80211com *,
73: const u_int8_t *);
74: int ieee80211_parse_edca_params(struct ieee80211com *, const u_int8_t *);
75: int ieee80211_parse_wmm_params(struct ieee80211com *, const u_int8_t *);
76: enum ieee80211_cipher ieee80211_parse_rsn_cipher(const u_int8_t[]);
77: enum ieee80211_akm ieee80211_parse_rsn_akm(const u_int8_t[]);
78: int ieee80211_parse_rsn_body(struct ieee80211com *,
79: struct ieee80211_node *, const u_int8_t *, u_int);
80: int ieee80211_parse_rsn(struct ieee80211com *, struct ieee80211_node *,
81: const u_int8_t *);
82: int ieee80211_parse_wpa1(struct ieee80211com *, struct ieee80211_node *,
83: const u_int8_t *);
84: void ieee80211_recv_pspoll(struct ieee80211com *, struct mbuf *, int,
85: u_int32_t);
86: int ieee80211_do_slow_print(struct ieee80211com *, int *);
87: void ieee80211_recv_probe_resp(struct ieee80211com *, struct mbuf *,
88: struct ieee80211_node *, int, u_int32_t);
89: void ieee80211_recv_probe_req(struct ieee80211com *, struct mbuf *,
90: struct ieee80211_node *, int, u_int32_t);
91: void ieee80211_recv_auth(struct ieee80211com *, struct mbuf *,
92: struct ieee80211_node *, int, u_int32_t);
93: void ieee80211_recv_assoc_req(struct ieee80211com *, struct mbuf *,
94: struct ieee80211_node *, int, u_int32_t);
95: void ieee80211_recv_assoc_resp(struct ieee80211com *, struct mbuf *,
96: struct ieee80211_node *, int, u_int32_t);
97: void ieee80211_recv_deauth(struct ieee80211com *, struct mbuf *,
98: struct ieee80211_node *, int, u_int32_t);
99: void ieee80211_recv_disassoc(struct ieee80211com *, struct mbuf *,
100: struct ieee80211_node *, int, u_int32_t);
101: void ieee80211_recv_4way_msg1(struct ieee80211com *,
102: const struct ieee80211_eapol_key *, struct ieee80211_node *);
103: void ieee80211_recv_4way_msg2(struct ieee80211com *,
104: const struct ieee80211_eapol_key *, struct ieee80211_node *);
105: void ieee80211_recv_4way_msg3(struct ieee80211com *,
106: const struct ieee80211_eapol_key *, struct ieee80211_node *);
107: void ieee80211_recv_4way_msg4(struct ieee80211com *,
108: const struct ieee80211_eapol_key *, struct ieee80211_node *);
109: void ieee80211_recv_rsn_group_msg1(struct ieee80211com *,
110: const struct ieee80211_eapol_key *, struct ieee80211_node *);
111: void ieee80211_recv_wpa_group_msg1(struct ieee80211com *,
112: struct ieee80211_eapol_key *, struct ieee80211_node *);
113: void ieee80211_recv_group_msg2(struct ieee80211com *,
114: const struct ieee80211_eapol_key *, struct ieee80211_node *);
115: void ieee80211_recv_eapol_key_req(struct ieee80211com *,
116: const struct ieee80211_eapol_key *, struct ieee80211_node *);
117:
118: /*
119: * Process a received frame. The node associated with the sender
120: * should be supplied. If nothing was found in the node table then
121: * the caller is assumed to supply a reference to ic_bss instead.
122: * The RSSI and a timestamp are also supplied. The RSSI data is used
123: * during AP scanning to select a AP to associate with; it can have
124: * any units so long as values have consistent units and higher values
125: * mean ``better signal''. The receive timestamp is currently not used
126: * by the 802.11 layer.
127: */
128: void
129: ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
130: int rssi, u_int32_t rstamp)
131: {
132: struct ieee80211com *ic = (void *)ifp;
133: struct ieee80211_frame *wh;
134: struct ether_header *eh;
135: struct mbuf *m1;
136: int error, hdrlen, len;
137: u_int8_t dir, type, subtype;
138: u_int16_t orxseq, nrxseq;
139:
140: if (ni == NULL)
141: panic("null mode");
142:
143: /* trim CRC here so WEP can find its own CRC at the end of packet. */
144: if (m->m_flags & M_HASFCS) {
145: m_adj(m, -IEEE80211_CRC_LEN);
146: m->m_flags &= ~M_HASFCS;
147: }
148:
149: /*
150: * In monitor mode, send everything directly to bpf.
151: * XXX may want to include the CRC
152: */
153: if (ic->ic_opmode == IEEE80211_M_MONITOR)
154: goto out;
155:
156: /* do not process frames w/o i_addr2 any further */
157: if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
158: IEEE80211_DPRINTF2(("%s: frame too short (1), len %u\n",
159: __func__, m->m_pkthdr.len));
160: ic->ic_stats.is_rx_tooshort++;
161: goto out;
162: }
163:
164: wh = mtod(m, struct ieee80211_frame *);
165: if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
166: IEEE80211_FC0_VERSION_0) {
167: IEEE80211_DPRINTF(("%s: packet with wrong version: %x\n",
168: __func__, wh->i_fc[0]));
169: ic->ic_stats.is_rx_badversion++;
170: goto err;
171: }
172:
173: dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
174: type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
175:
176: /*
177: * NB: We are not yet prepared to handle control frames,
178: * but permitting drivers to send them to us allows
179: * them to go through bpf tapping at the 802.11 layer.
180: */
181: if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
182: IEEE80211_DPRINTF2(("%s: frame too short (2), len %u\n",
183: __func__, m->m_pkthdr.len));
184: ic->ic_stats.is_rx_tooshort++;
185: goto out;
186: }
187: if (ic->ic_state != IEEE80211_S_SCAN) {
188: ni->ni_rssi = rssi;
189: ni->ni_rstamp = rstamp;
190: if (type == IEEE80211_FC0_TYPE_DATA &&
191: (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)) {
192: struct ieee80211_qosframe *qwh =
193: (struct ieee80211_qosframe *)wh;
194: int tid = qwh->i_qos[0] & IEEE80211_QOS_TID;
195: orxseq = ni->ni_qos_rxseqs[tid];
196: nrxseq = ni->ni_qos_rxseqs[tid] =
197: letoh16(*(u_int16_t *)qwh->i_seq) >>
198: IEEE80211_SEQ_SEQ_SHIFT;
199: } else {
200: orxseq = ni->ni_rxseq;
201: nrxseq = ni->ni_rxseq =
202: letoh16(*(u_int16_t *)wh->i_seq) >>
203: IEEE80211_SEQ_SEQ_SHIFT;
204: }
205: /* TODO: fragment */
206: if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
207: orxseq == nrxseq) {
208: /* duplicate, silently discarded */
209: ic->ic_stats.is_rx_dup++; /* XXX per-station stat */
210: goto out;
211: }
212: ni->ni_inact = 0;
213: }
214:
215: if (ic->ic_set_tim != NULL &&
216: (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) &&
217: ni->ni_pwrsave == 0) {
218: /* turn on power save mode */
219:
220: if (ifp->if_flags & IFF_DEBUG)
221: printf("%s: power save mode on for %s\n",
222: ifp->if_xname, ether_sprintf(wh->i_addr2));
223:
224: ni->ni_pwrsave = IEEE80211_PS_SLEEP;
225: }
226: if (ic->ic_set_tim != NULL &&
227: !(wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) &&
228: ni->ni_pwrsave != 0) {
229: /* turn off power save mode, dequeue stored packets */
230:
231: ni->ni_pwrsave = 0;
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 (ic->ic_state != IEEE80211_S_SCAN &&
255: !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
256: /* Source address is not our BSS. */
257: IEEE80211_DPRINTF(
258: ("%s: discard frame from SA %s\n",
259: __func__, ether_sprintf(wh->i_addr2)));
260: ic->ic_stats.is_rx_wrongbss++;
261: goto out;
262: }
263: if ((ifp->if_flags & IFF_SIMPLEX) &&
264: IEEE80211_IS_MULTICAST(wh->i_addr1) &&
265: IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
266: /*
267: * In IEEE802.11 network, multicast packet
268: * sent from me is broadcasted from AP.
269: * It should be silently discarded for
270: * SIMPLEX interface.
271: */
272: ic->ic_stats.is_rx_mcastecho++;
273: goto out;
274: }
275: break;
276: case IEEE80211_M_IBSS:
277: case IEEE80211_M_AHDEMO:
278: if (dir != IEEE80211_FC1_DIR_NODS) {
279: ic->ic_stats.is_rx_wrongdir++;
280: goto out;
281: }
282: if (ic->ic_state != IEEE80211_S_SCAN &&
283: !IEEE80211_ADDR_EQ(wh->i_addr3,
284: ic->ic_bss->ni_bssid) &&
285: !IEEE80211_ADDR_EQ(wh->i_addr3,
286: etherbroadcastaddr)) {
287: /* Destination is not our BSS or broadcast. */
288: IEEE80211_DPRINTF2(
289: ("%s: discard data frame to DA %s\n",
290: __func__, ether_sprintf(wh->i_addr3)));
291: ic->ic_stats.is_rx_wrongbss++;
292: goto out;
293: }
294: break;
295: case IEEE80211_M_HOSTAP:
296: if (dir != IEEE80211_FC1_DIR_TODS) {
297: ic->ic_stats.is_rx_wrongdir++;
298: goto out;
299: }
300: if (ic->ic_state != IEEE80211_S_SCAN &&
301: !IEEE80211_ADDR_EQ(wh->i_addr1,
302: ic->ic_bss->ni_bssid) &&
303: !IEEE80211_ADDR_EQ(wh->i_addr1,
304: etherbroadcastaddr)) {
305: /* BSS is not us or broadcast. */
306: IEEE80211_DPRINTF2(
307: ("%s: discard data frame to BSS %s\n",
308: __func__, ether_sprintf(wh->i_addr1)));
309: ic->ic_stats.is_rx_wrongbss++;
310: goto out;
311: }
312: /* check if source STA is associated */
313: if (ni == ic->ic_bss) {
314: IEEE80211_DPRINTF(("%s: "
315: "data from unknown src %s\n", __func__,
316: ether_sprintf(wh->i_addr2)));
317: /* NB: caller deals with reference */
318: ni = ieee80211_dup_bss(ic, wh->i_addr2);
319: if (ni != NULL) {
320: IEEE80211_SEND_MGMT(ic, ni,
321: IEEE80211_FC0_SUBTYPE_DEAUTH,
322: IEEE80211_REASON_NOT_AUTHED);
323: }
324: ic->ic_stats.is_rx_notassoc++;
325: goto err;
326: }
327: if (ni->ni_associd == 0) {
328: IEEE80211_DPRINTF(("%s: "
329: "data from unassoc src %s\n", __func__,
330: ether_sprintf(wh->i_addr2)));
331: IEEE80211_SEND_MGMT(ic, ni,
332: IEEE80211_FC0_SUBTYPE_DISASSOC,
333: IEEE80211_REASON_NOT_ASSOCED);
334: ic->ic_stats.is_rx_notassoc++;
335: goto err;
336: }
337: break;
338: case IEEE80211_M_MONITOR:
339: /* can't get there */
340: goto out;
341: }
342: if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)
343: hdrlen = sizeof(struct ieee80211_qosframe);
344: else
345: hdrlen = sizeof(struct ieee80211_frame);
346: if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
347: if (ic->ic_flags & IEEE80211_F_WEPON) {
348: m = ieee80211_wep_crypt(ifp, m, 0);
349: if (m == NULL) {
350: ic->ic_stats.is_rx_wepfail++;
351: goto err;
352: }
353: wh = mtod(m, struct ieee80211_frame *);
354: } else {
355: ic->ic_stats.is_rx_nowep++;
356: goto out;
357: }
358: }
359: #if NBPFILTER > 0
360: /* copy to listener after decrypt */
361: if (ic->ic_rawbpf)
362: bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);
363: #endif
364: m = ieee80211_decap(ifp, m, hdrlen);
365: if (m == NULL) {
366: IEEE80211_DPRINTF(("%s: "
367: "decapsulation error for src %s\n",
368: __func__, ether_sprintf(wh->i_addr2)));
369: ic->ic_stats.is_rx_decap++;
370: goto err;
371: }
372: eh = mtod(m, struct ether_header *);
373: #if 0
374: if (!ni->ni_port_valid &&
375: eh->ether_type != htons(ETHERTYPE_PAE)) {
376: IEEE80211_DPRINTF(("%s: port not valid: %s\n",
377: __func__, ether_sprintf(wh->i_addr2)));
378: ic->ic_stats.is_rx_unauth++;
379: goto err;
380: }
381: #endif
382: ifp->if_ipackets++;
383:
384: /* perform as a bridge within the AP */
385: m1 = NULL;
386: if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
387: (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) {
388: if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
389: m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
390: if (m1 == NULL)
391: ifp->if_oerrors++;
392: else
393: m1->m_flags |= M_MCAST;
394: } else {
395: ni = ieee80211_find_node(ic, eh->ether_dhost);
396: if (ni != NULL) {
397: if (ni->ni_associd != 0) {
398: m1 = m;
399: m = NULL;
400: }
401: }
402: }
403: if (m1 != NULL) {
404: len = m1->m_pkthdr.len;
405: IFQ_ENQUEUE(&ifp->if_snd, m1, NULL, error);
406: if (error)
407: ifp->if_oerrors++;
408: else {
409: if (m != NULL)
410: ifp->if_omcasts++;
411: ifp->if_obytes += len;
412: }
413: }
414: }
415: if (m != NULL) {
416: #if NBPFILTER > 0
417: /*
418: * If we forward packet into transmitter of the AP,
419: * we don't need to duplicate for DLT_EN10MB.
420: */
421: if (ifp->if_bpf && m1 == NULL)
422: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
423: #endif
424: ether_input_mbuf(ifp, m);
425: }
426: return;
427:
428: case IEEE80211_FC0_TYPE_MGT:
429: if (dir != IEEE80211_FC1_DIR_NODS) {
430: ic->ic_stats.is_rx_wrongdir++;
431: goto err;
432: }
433: if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
434: ic->ic_stats.is_rx_ahdemo_mgt++;
435: goto out;
436: }
437: subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
438:
439: /* drop frames without interest */
440: if (ic->ic_state == IEEE80211_S_SCAN) {
441: if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
442: subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
443: ic->ic_stats.is_rx_mgtdiscard++;
444: goto out;
445: }
446: }
447:
448: if (ifp->if_flags & IFF_DEBUG) {
449: /* avoid to print too many frames */
450: int doprint = 0;
451:
452: switch (subtype) {
453: case IEEE80211_FC0_SUBTYPE_BEACON:
454: if (ic->ic_state == IEEE80211_S_SCAN)
455: doprint = 1;
456: break;
457: case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
458: if (ic->ic_opmode == IEEE80211_M_IBSS)
459: doprint = 1;
460: break;
461: default:
462: doprint = 1;
463: break;
464: }
465: #ifdef IEEE80211_DEBUG
466: doprint += ieee80211_debug;
467: #endif
468: if (doprint)
469: printf("%s: received %s from %s rssi %d mode %s\n",
470: ifp->if_xname,
471: ieee80211_mgt_subtype_name[subtype
472: >> IEEE80211_FC0_SUBTYPE_SHIFT],
473: ether_sprintf(wh->i_addr2), rssi,
474: ieee80211_phymode_name[ieee80211_chan2mode(ic,
475: ic->ic_bss->ni_chan)]);
476: }
477: #if NBPFILTER > 0
478: if (ic->ic_rawbpf)
479: bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);
480: /*
481: * Drop mbuf if it was filtered by bpf. Normally, this is
482: * done in ether_input() but IEEE 802.11 management frames
483: * are a special case.
484: */
485: if (m->m_flags & M_FILDROP) {
486: m_freem(m);
487: return;
488: }
489: #endif
490: (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
491: m_freem(m);
492: return;
493:
494: case IEEE80211_FC0_TYPE_CTL:
495: ic->ic_stats.is_rx_ctl++;
496: if (ic->ic_opmode != IEEE80211_M_HOSTAP)
497: goto out;
498: subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
499: if (subtype == IEEE80211_FC0_SUBTYPE_PS_POLL) {
500: /* XXX statistic */
501: /* Dump out a single packet from the host */
502: if (ifp->if_flags & IFF_DEBUG)
503: printf("%s: got power save probe from %s\n",
504: ifp->if_xname,
505: ether_sprintf(wh->i_addr2));
506: ieee80211_recv_pspoll(ic, m, rssi, rstamp);
507: }
508: goto out;
509:
510: default:
511: IEEE80211_DPRINTF(("%s: bad packet type %x\n", __func__, type));
512: /* should not come here */
513: break;
514: }
515: err:
516: ifp->if_ierrors++;
517: out:
518: if (m != NULL) {
519: #if NBPFILTER > 0
520: if (ic->ic_rawbpf)
521: bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);
522: #endif
523: m_freem(m);
524: }
525: }
526:
527: struct mbuf *
528: ieee80211_decap(struct ifnet *ifp, struct mbuf *m, int hdrlen)
529: {
530: struct ieee80211_frame wh;
531: struct ether_header *eh;
532: struct llc *llc;
533:
534: if (m->m_len < hdrlen + sizeof(*llc)) {
535: m = m_pullup(m, hdrlen + sizeof(*llc));
536: if (m == NULL)
537: return NULL;
538: }
539: memcpy(&wh, mtod(m, caddr_t), sizeof(wh));
540: llc = (struct llc *)(mtod(m, caddr_t) + hdrlen);
541: if (llc->llc_dsap == LLC_SNAP_LSAP &&
542: llc->llc_ssap == LLC_SNAP_LSAP &&
543: llc->llc_control == LLC_UI &&
544: llc->llc_snap.org_code[0] == 0 &&
545: llc->llc_snap.org_code[1] == 0 &&
546: llc->llc_snap.org_code[2] == 0) {
547: m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh));
548: llc = NULL;
549: } else {
550: m_adj(m, hdrlen - sizeof(*eh));
551: }
552: eh = mtod(m, struct ether_header *);
553: switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
554: case IEEE80211_FC1_DIR_NODS:
555: IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
556: IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
557: break;
558: case IEEE80211_FC1_DIR_TODS:
559: IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
560: IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
561: break;
562: case IEEE80211_FC1_DIR_FROMDS:
563: IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
564: IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
565: break;
566: case IEEE80211_FC1_DIR_DSTODS:
567: /* not yet supported */
568: IEEE80211_DPRINTF(("%s: discard DS to DS frame\n", __func__));
569: m_freem(m);
570: return NULL;
571: }
572: if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) {
573: struct mbuf *n, *n0, **np;
574: caddr_t newdata;
575: int off, pktlen;
576:
577: n0 = NULL;
578: np = &n0;
579: off = 0;
580: pktlen = m->m_pkthdr.len;
581: while (pktlen > off) {
582: if (n0 == NULL) {
583: MGETHDR(n, M_DONTWAIT, MT_DATA);
584: if (n == NULL) {
585: m_freem(m);
586: return NULL;
587: }
588: M_DUP_PKTHDR(n, m);
589: n->m_len = MHLEN;
590: } else {
591: MGET(n, M_DONTWAIT, MT_DATA);
592: if (n == NULL) {
593: m_freem(m);
594: m_freem(n0);
595: return NULL;
596: }
597: n->m_len = MLEN;
598: }
599: if (pktlen - off >= MINCLSIZE) {
600: MCLGET(n, M_DONTWAIT);
601: if (n->m_flags & M_EXT)
602: n->m_len = n->m_ext.ext_size;
603: }
604: if (n0 == NULL) {
605: newdata =
606: (caddr_t)ALIGN(n->m_data + sizeof(*eh)) -
607: sizeof(*eh);
608: n->m_len -= newdata - n->m_data;
609: n->m_data = newdata;
610: }
611: if (n->m_len > pktlen - off)
612: n->m_len = pktlen - off;
613: m_copydata(m, off, n->m_len, mtod(n, caddr_t));
614: off += n->m_len;
615: *np = n;
616: np = &n->m_next;
617: }
618: m_freem(m);
619: m = n0;
620: }
621: if (llc != NULL) {
622: eh = mtod(m, struct ether_header *);
623: eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh));
624: }
625: return m;
626: }
627:
628: /*
629: * Install received rate set information in the node's state block.
630: */
631: int
632: ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
633: const u_int8_t *rates, const u_int8_t *xrates, int flags)
634: {
635: struct ieee80211_rateset *rs = &ni->ni_rates;
636:
637: memset(rs, 0, sizeof(*rs));
638: rs->rs_nrates = rates[1];
639: memcpy(rs->rs_rates, rates + 2, rs->rs_nrates);
640: if (xrates != NULL) {
641: u_int8_t nxrates;
642: /*
643: * Tack on 11g extended supported rate element.
644: */
645: nxrates = xrates[1];
646: if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
647: nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
648: IEEE80211_DPRINTF(("%s: extended rate set too large;"
649: " only using %u of %u rates\n",
650: __func__, nxrates, xrates[1]));
651: ic->ic_stats.is_rx_rstoobig++;
652: }
653: memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
654: rs->rs_nrates += nxrates;
655: }
656: return ieee80211_fix_rate(ic, ni, flags);
657: }
658:
659: /* Verify the existence and length of __elem or get out. */
660: #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
661: if ((__elem) == NULL) { \
662: IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \
663: __func__, ieee80211_mgt_subtype_name[ \
664: (wh->i_fc[0] & \
665: IEEE80211_FC0_SUBTYPE_MASK) >> \
666: IEEE80211_FC0_SUBTYPE_SHIFT])); \
667: ic->ic_stats.is_rx_elem_missing++; \
668: return; \
669: } \
670: if ((__elem)[1] > (__maxlen)) { \
671: IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s " \
672: "frame from %s\n", __func__, (__elem)[1], \
673: ieee80211_mgt_subtype_name[(wh->i_fc[0] & \
674: IEEE80211_FC0_SUBTYPE_MASK) >> \
675: IEEE80211_FC0_SUBTYPE_SHIFT], \
676: ether_sprintf((u_int8_t *)wh->i_addr2))); \
677: ic->ic_stats.is_rx_elem_toobig++; \
678: return; \
679: } \
680: } while (0)
681:
682: #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
683: if ((_len) < (_minlen)) { \
684: IEEE80211_DPRINTF(("%s: %s frame too short from %s\n", \
685: __func__, \
686: ieee80211_mgt_subtype_name[(wh->i_fc[0] & \
687: IEEE80211_FC0_SUBTYPE_MASK) >> \
688: IEEE80211_FC0_SUBTYPE_SHIFT], \
689: ether_sprintf((u_int8_t *)wh->i_addr2))); \
690: ic->ic_stats.is_rx_elem_toosmall++; \
691: return; \
692: } \
693: } while (0)
694:
695: #ifdef IEEE80211_DEBUG
696: void
697: ieee80211_ssid_mismatch(struct ieee80211com *, const char *,
698: const u_int8_t[IEEE80211_ADDR_LEN], const u_int8_t *);
699: void
700: ieee80211_ssid_mismatch(struct ieee80211com *ic, const char *tag,
701: const u_int8_t mac[IEEE80211_ADDR_LEN], const u_int8_t *ssid)
702: {
703: printf("[%s] %s req ssid mismatch: ",
704: ether_sprintf((u_int8_t *)mac), tag);
705: ieee80211_print_essid(ssid + 2, ssid[1]);
706: printf("\n");
707: }
708:
709: #define IEEE80211_VERIFY_SSID(_ni, _ssid, _packet_type) do { \
710: if ((_ssid)[1] != 0 && \
711: ((_ssid)[1] != (_ni)->ni_esslen || \
712: memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
713: if (ieee80211_debug) \
714: ieee80211_ssid_mismatch(ic, _packet_type, \
715: wh->i_addr2, _ssid); \
716: ic->ic_stats.is_rx_ssidmismatch++; \
717: return; \
718: } \
719: } while (0)
720: #else /* !IEEE80211_DEBUG */
721: #define IEEE80211_VERIFY_SSID(_ni, _ssid, _packet_type) do { \
722: if ((_ssid)[1] != 0 && \
723: ((_ssid)[1] != (_ni)->ni_esslen || \
724: memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
725: ic->ic_stats.is_rx_ssidmismatch++; \
726: return; \
727: } \
728: } while (0)
729: #endif /* !IEEE80211_DEBUG */
730:
731: void
732: ieee80211_auth_open(struct ieee80211com *ic, const struct ieee80211_frame *wh,
733: struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq,
734: u_int16_t status)
735: {
736: struct ifnet *ifp = &ic->ic_if;
737: switch (ic->ic_opmode) {
738: case IEEE80211_M_IBSS:
739: if (ic->ic_state != IEEE80211_S_RUN ||
740: seq != IEEE80211_AUTH_OPEN_REQUEST) {
741: IEEE80211_DPRINTF(("%s: discard auth from %s; "
742: "state %u, seq %u\n", __func__,
743: ether_sprintf((u_int8_t *)wh->i_addr2),
744: ic->ic_state, seq));
745: ic->ic_stats.is_rx_bad_auth++;
746: return;
747: }
748: ieee80211_new_state(ic, IEEE80211_S_AUTH,
749: wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
750: break;
751:
752: case IEEE80211_M_AHDEMO:
753: /* should not come here */
754: break;
755:
756: case IEEE80211_M_HOSTAP:
757: if (ic->ic_state != IEEE80211_S_RUN ||
758: seq != IEEE80211_AUTH_OPEN_REQUEST) {
759: IEEE80211_DPRINTF(("%s: discard auth from %s; "
760: "state %u, seq %u\n", __func__,
761: ether_sprintf((u_int8_t *)wh->i_addr2),
762: ic->ic_state, seq));
763: ic->ic_stats.is_rx_bad_auth++;
764: return;
765: }
766: if (ni == ic->ic_bss) {
767: ni = ieee80211_alloc_node(ic, wh->i_addr2);
768: if (ni == NULL) {
769: ic->ic_stats.is_rx_nodealloc++;
770: return;
771: }
772: IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
773: ni->ni_rssi = rssi;
774: ni->ni_rstamp = rstamp;
775: ni->ni_chan = ic->ic_bss->ni_chan;
776: }
777: IEEE80211_SEND_MGMT(ic, ni,
778: IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
779: if (ifp->if_flags & IFF_DEBUG)
780: printf("%s: station %s %s authenticated (open)\n",
781: ifp->if_xname,
782: ether_sprintf((u_int8_t *)ni->ni_macaddr),
783: ni->ni_state != IEEE80211_STA_CACHE ?
784: "newly" : "already");
785: ieee80211_node_newstate(ni, IEEE80211_STA_AUTH);
786: break;
787:
788: case IEEE80211_M_STA:
789: if (ic->ic_state != IEEE80211_S_AUTH ||
790: seq != IEEE80211_AUTH_OPEN_RESPONSE) {
791: ic->ic_stats.is_rx_bad_auth++;
792: IEEE80211_DPRINTF(("%s: discard auth from %s; "
793: "state %u, seq %u\n", __func__,
794: ether_sprintf((u_int8_t *)wh->i_addr2),
795: ic->ic_state, seq));
796: return;
797: }
798: if (status != 0) {
799: if (ifp->if_flags & IFF_DEBUG)
800: printf("%s: open authentication failed "
801: "(reason %d) for %s\n", ifp->if_xname,
802: status,
803: ether_sprintf((u_int8_t *)wh->i_addr3));
804: if (ni != ic->ic_bss)
805: ni->ni_fails++;
806: ic->ic_stats.is_rx_auth_fail++;
807: return;
808: }
809: ieee80211_new_state(ic, IEEE80211_S_ASSOC,
810: wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
811: break;
812: case IEEE80211_M_MONITOR:
813: break;
814: }
815: }
816:
817: /* unaligned little endian access */
818: #define LE_READ_2(p) \
819: ((u_int16_t) \
820: ((((const u_int8_t *)(p))[0]) | \
821: (((const u_int8_t *)(p))[1] << 8)))
822: #define LE_READ_4(p) \
823: ((u_int32_t) \
824: ((((const u_int8_t *)(p))[0]) | \
825: (((const u_int8_t *)(p))[1] << 8) | \
826: (((const u_int8_t *)(p))[2] << 16) | \
827: (((const u_int8_t *)(p))[3] << 24)))
828:
829: /*
830: * Parse an EDCA Parameter Set element (see 7.3.2.27).
831: */
832: int
833: ieee80211_parse_edca_params_body(struct ieee80211com *ic, const u_int8_t *frm)
834: {
835: u_int updtcount;
836: int aci;
837:
838: /*
839: * Check if EDCA parameters have changed XXX if we miss more than
840: * 15 consecutive beacons, we might not detect changes to EDCA
841: * parameters due to wraparound of the 4-bit Update Count field.
842: */
843: updtcount = frm[0] & 0xf;
844: if (updtcount == ic->ic_edca_updtcount)
845: return 0; /* no changes to EDCA parameters, ignore */
846: ic->ic_edca_updtcount = updtcount;
847:
848: frm += 2; /* skip QoS Info & Reserved fields */
849:
850: /* parse AC Parameter Records */
851: for (aci = 0; aci < EDCA_NUM_AC; aci++) {
852: struct ieee80211_edca_ac_params *ac = &ic->ic_edca_ac[aci];
853:
854: ac->ac_acm = (frm[0] >> 4) & 0x1;
855: ac->ac_aifsn = frm[0] & 0xf;
856: ac->ac_ecwmin = frm[1] & 0xf;
857: ac->ac_ecwmax = frm[1] >> 4;
858: ac->ac_txoplimit = LE_READ_2(frm + 2);
859: frm += 4;
860: }
861: /* give drivers a chance to update their settings */
862: if ((ic->ic_flags & IEEE80211_F_QOS) && ic->ic_updateedca != NULL)
863: (*ic->ic_updateedca)(ic);
864:
865: return 0;
866: }
867:
868: int
869: ieee80211_parse_edca_params(struct ieee80211com *ic, const u_int8_t *frm)
870: {
871: /* check IE length */
872: if (frm[1] < 18) {
873: IEEE80211_DPRINTF(("%s: invalid EDCA parameter set IE;"
874: " length %u, expecting 18\n", __func__, frm[1]));
875: ic->ic_stats.is_rx_elem_toosmall++;
876: return IEEE80211_REASON_IE_INVALID;
877: }
878: return ieee80211_parse_edca_params_body(ic, frm + 2);
879: }
880:
881: int
882: ieee80211_parse_wmm_params(struct ieee80211com *ic, const u_int8_t *frm)
883: {
884: /* check IE length */
885: if (frm[1] < 24) {
886: IEEE80211_DPRINTF(("%s: invalid WMM parameter set IE;"
887: " length %u, expecting 24\n", __func__, frm[1]));
888: ic->ic_stats.is_rx_elem_toosmall++;
889: return IEEE80211_REASON_IE_INVALID;
890: }
891: return ieee80211_parse_edca_params_body(ic, frm + 8);
892: }
893:
894: enum ieee80211_cipher
895: ieee80211_parse_rsn_cipher(const u_int8_t selector[4])
896: {
897: /* from IEEE Std 802.11i-2004 - Table 20da */
898: if (memcmp(selector, MICROSOFT_OUI, 3) == 0 || /* WPA1 */
899: memcmp(selector, IEEE80211_OUI, 3) == 0) { /* RSN (aka WPA2) */
900: switch (selector[3]) {
901: case 0: /* use group cipher suite */
902: return IEEE80211_CIPHER_USEGROUP;
903: case 1: /* WEP-40 */
904: return IEEE80211_CIPHER_WEP40;
905: case 2: /* TKIP */
906: return IEEE80211_CIPHER_TKIP;
907: case 4: /* CCMP (RSNA default) */
908: return IEEE80211_CIPHER_CCMP;
909: case 5: /* WEP-104 */
910: return IEEE80211_CIPHER_WEP104;
911: }
912: }
913: return IEEE80211_CIPHER_NONE; /* ignore unknown ciphers */
914: }
915:
916: enum ieee80211_akm
917: ieee80211_parse_rsn_akm(const u_int8_t selector[4])
918: {
919: /* from IEEE Std 802.11i-2004 - Table 20dc */
920: if (memcmp(selector, MICROSOFT_OUI, 3) == 0 || /* WPA1 */
921: memcmp(selector, IEEE80211_OUI, 3) == 0) { /* RSN (aka WPA2) */
922: switch (selector[3]) {
923: case 1: /* IEEE 802.1X (RSNA default) */
924: return IEEE80211_AKM_IEEE8021X;
925: case 2: /* PSK */
926: return IEEE80211_AKM_PSK;
927: }
928: }
929: return IEEE80211_AKM_NONE; /* ignore unknown AKMs */
930: }
931:
932: /*
933: * Parse an RSN element (see 7.3.2.25).
934: */
935: int
936: ieee80211_parse_rsn_body(struct ieee80211com *ic, struct ieee80211_node *ni,
937: const u_int8_t *frm, u_int len)
938: {
939: const u_int8_t *efrm;
940: u_int16_t m, n, s;
941: u_int16_t rsncaps;
942: enum ieee80211_cipher group_cipher;
943: u_int akmset, pairwise_cipherset;
944:
945: efrm = frm + len;
946:
947: /* check Version field */
948: if (LE_READ_2(frm) != 1)
949: return IEEE80211_REASON_RSN_IE_VER_UNSUP;
950: frm += 2;
951:
952: /* all fields after the Version field are optional */
953:
954: /* if Cipher Suite missing, default to CCMP */
955: ni->ni_group_cipher = IEEE80211_CIPHER_CCMP;
956: ni->ni_pairwise_cipherset = IEEE80211_CIPHER_CCMP;
957: /* if AKM Suite missing, default to 802.1X */
958: ni->ni_akmset = IEEE80211_AKM_IEEE8021X;
959:
960: /* read Group Cipher Suite field */
961: if (frm + 4 > efrm)
962: return 0;
963: group_cipher = ieee80211_parse_rsn_cipher(frm);
964: if (group_cipher == IEEE80211_CIPHER_USEGROUP)
965: return IEEE80211_REASON_BAD_GROUP_CIPHER;
966: frm += 4;
967:
968: /* read Pairwise Cipher Suite Count field */
969: if (frm + 2 > efrm)
970: return 0;
971: m = LE_READ_2(frm);
972: frm += 2;
973:
974: /* read Pairwise Cipher Suite List */
975: if (frm + m * 4 > efrm)
976: return IEEE80211_REASON_IE_INVALID;
977: pairwise_cipherset = IEEE80211_CIPHER_NONE;
978: while (m-- > 0) {
979: pairwise_cipherset |= ieee80211_parse_rsn_cipher(frm);
980: frm += 4;
981: }
982: if (pairwise_cipherset & IEEE80211_CIPHER_USEGROUP) {
983: if (pairwise_cipherset != IEEE80211_CIPHER_USEGROUP)
984: return IEEE80211_REASON_BAD_PAIRWISE_CIPHER;
985: if (group_cipher == IEEE80211_CIPHER_CCMP)
986: return IEEE80211_REASON_BAD_PAIRWISE_CIPHER;
987: }
988:
989: /* read AKM Suite List Count field */
990: if (frm + 2 > efrm)
991: return 0;
992: n = LE_READ_2(frm);
993: frm += 2;
994:
995: /* read AKM Suite List */
996: if (frm + n * 4 > efrm)
997: return IEEE80211_REASON_IE_INVALID;
998: akmset = IEEE80211_AKM_NONE;
999: while (n-- > 0) {
1000: akmset |= ieee80211_parse_rsn_akm(frm);
1001: frm += 4;
1002: }
1003:
1004: /* read RSN Capabilities field */
1005: if (frm + 2 > efrm)
1006: return 0;
1007: rsncaps = LE_READ_2(frm);
1008: frm += 2;
1009:
1010: /* read PMKID Count field */
1011: if (frm + 2 > efrm)
1012: return 0;
1013: s = LE_READ_2(frm);
1014: frm += 2;
1015:
1016: /* read PMKID List */
1017: if (frm + s * IEEE80211_PMKID_LEN > efrm)
1018: return IEEE80211_REASON_IE_INVALID;
1019: while (s-- > 0) {
1020: /* ignore PMKIDs for now */
1021: frm += IEEE80211_PMKID_LEN;
1022: }
1023:
1024: ni->ni_group_cipher = group_cipher;
1025: ni->ni_pairwise_cipherset = pairwise_cipherset;
1026: ni->ni_akmset = akmset;
1027: ni->ni_rsncaps = rsncaps;
1028:
1029: return 0;
1030: }
1031:
1032: int
1033: ieee80211_parse_rsn(struct ieee80211com *ic, struct ieee80211_node *ni,
1034: const u_int8_t *frm)
1035: {
1036: /* check IE length */
1037: if (frm[1] < 2) {
1038: IEEE80211_DPRINTF(("%s: invalid RSN/WPA2 IE;"
1039: " length %u, expecting at least 2\n", __func__, frm[1]));
1040: ic->ic_stats.is_rx_elem_toosmall++;
1041: return IEEE80211_REASON_IE_INVALID;
1042: }
1043: return ieee80211_parse_rsn_body(ic, ni, frm + 2, frm[1] - 2);
1044: }
1045:
1046: int
1047: ieee80211_parse_wpa1(struct ieee80211com *ic, struct ieee80211_node *ni,
1048: const u_int8_t *frm)
1049: {
1050: /* check IE length */
1051: if (frm[1] < 6) {
1052: IEEE80211_DPRINTF(("%s: invalid WPA1 IE;"
1053: " length %u, expecting at least 6\n", __func__, frm[1]));
1054: ic->ic_stats.is_rx_elem_toosmall++;
1055: return IEEE80211_REASON_IE_INVALID;
1056: }
1057: return ieee80211_parse_rsn_body(ic, ni, frm + 6, frm[1] - 4);
1058: }
1059:
1060: /*-
1061: * Beacon/Probe response frame format:
1062: * [8] Timestamp
1063: * [2] Beacon interval
1064: * [2] Capability
1065: * [tlv] Service Set Identifier (SSID)
1066: * [tlv] Supported rates
1067: * [tlv*] Frequency-Hopping (FH) Parameter Set
1068: * [tlv*] DS Parameter Set (802.11g)
1069: * [tlv] ERP Information (802.11g)
1070: * [tlv] Extended Supported Rates (802.11g)
1071: * [tlv] RSN (802.11i)
1072: * [tlv] EDCA Parameter Set (802.11e)
1073: * [tlv] QoS Capability (Beacon only, 802.11e)
1074: */
1075: void
1076: ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m0,
1077: struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
1078: {
1079: #define ISPROBE(_wh) (((_wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == \
1080: IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1081:
1082: const struct ieee80211_frame *wh;
1083: const u_int8_t *frm, *efrm;
1084: const u_int8_t *tstamp, *ssid, *rates, *xrates, *edca, *wmm;
1085: const u_int8_t *rsn, *wpa;
1086: u_int16_t capinfo, bintval, fhdwell;
1087: u_int8_t chan, bchan, fhindex, erp;
1088: int is_new;
1089:
1090: /*
1091: * We process beacon/probe response frames for:
1092: * o station mode: to collect state
1093: * updates such as 802.11g slot time and for passive
1094: * scanning of APs
1095: * o adhoc mode: to discover neighbors
1096: * o hostap mode: for passive scanning of neighbor APs
1097: * o when scanning
1098: * In other words, in all modes other than monitor (which
1099: * does not process incoming packets) and adhoc-demo (which
1100: * does not use management frames at all).
1101: */
1102: #ifdef DIAGNOSTIC
1103: if (ic->ic_opmode != IEEE80211_M_STA &&
1104: ic->ic_opmode != IEEE80211_M_IBSS &&
1105: ic->ic_opmode != IEEE80211_M_HOSTAP &&
1106: ic->ic_state != IEEE80211_S_SCAN) {
1107: panic("%s: impossible operating mode", __func__);
1108: }
1109: #endif
1110: wh = mtod(m0, struct ieee80211_frame *);
1111: frm = (const u_int8_t *)&wh[1];
1112: efrm = mtod(m0, u_int8_t *) + m0->m_len;
1113:
1114: IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
1115: tstamp = frm; frm += 8;
1116: bintval = LE_READ_2(frm); frm += 2;
1117: capinfo = LE_READ_2(frm); frm += 2;
1118: ssid = rates = xrates = edca = wmm = rsn = wpa = NULL;
1119: bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1120: chan = bchan;
1121: fhdwell = 0;
1122: fhindex = 0;
1123: erp = 0;
1124: while (frm + 2 <= efrm) {
1125: if (frm + 2 + frm[1] > efrm) {
1126: ic->ic_stats.is_rx_elem_toosmall++;
1127: return;
1128: }
1129: switch (frm[0]) {
1130: case IEEE80211_ELEMID_SSID:
1131: ssid = frm;
1132: break;
1133: case IEEE80211_ELEMID_RATES:
1134: rates = frm;
1135: break;
1136: case IEEE80211_ELEMID_FHPARMS:
1137: if (ic->ic_phytype != IEEE80211_T_FH)
1138: break;
1139: if (frm[1] < 5) {
1140: ic->ic_stats.is_rx_elem_toosmall++;
1141: break;
1142: }
1143: fhdwell = LE_READ_2(frm + 2);
1144: chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
1145: fhindex = frm[6];
1146: break;
1147: case IEEE80211_ELEMID_DSPARMS:
1148: if (ic->ic_phytype == IEEE80211_T_FH)
1149: break;
1150: if (frm[1] < 1) {
1151: ic->ic_stats.is_rx_elem_toosmall++;
1152: break;
1153: }
1154: chan = frm[2];
1155: break;
1156: case IEEE80211_ELEMID_TIM:
1157: break;
1158: case IEEE80211_ELEMID_IBSSPARMS:
1159: break;
1160: case IEEE80211_ELEMID_XRATES:
1161: xrates = frm;
1162: break;
1163: case IEEE80211_ELEMID_ERP:
1164: if (frm[1] < 1) {
1165: ic->ic_stats.is_rx_elem_toosmall++;
1166: break;
1167: }
1168: erp = frm[2];
1169: break;
1170: case IEEE80211_ELEMID_RSN:
1171: rsn = frm;
1172: break;
1173: case IEEE80211_ELEMID_EDCAPARMS:
1174: edca = frm;
1175: break;
1176: case IEEE80211_ELEMID_QOS_CAP:
1177: break;
1178: case IEEE80211_ELEMID_VENDOR:
1179: if (frm[1] < 4) {
1180: ic->ic_stats.is_rx_elem_toosmall++;
1181: break;
1182: }
1183: if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
1184: if (frm[5] == 1)
1185: wpa = frm;
1186: else if (frm[1] >= 5 &&
1187: frm[5] == 2 && frm[6] == 1)
1188: wmm = frm;
1189: }
1190: break;
1191: default:
1192: IEEE80211_DPRINTF2(("%s: element id %u/len %u "
1193: "ignored\n", __func__, *frm, frm[1]));
1194: ic->ic_stats.is_rx_elem_unknown++;
1195: break;
1196: }
1197: frm += 2 + frm[1];
1198: }
1199: IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1200: IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1201:
1202: if (
1203: #if IEEE80211_CHAN_MAX < 255
1204: chan > IEEE80211_CHAN_MAX ||
1205: #endif
1206: isclr(ic->ic_chan_active, chan)) {
1207: IEEE80211_DPRINTF(("%s: ignore %s with invalid channel "
1208: "%u\n", __func__, ISPROBE(wh) ?
1209: "probe response" : "beacon", chan));
1210: ic->ic_stats.is_rx_badchan++;
1211: return;
1212: }
1213: if (!(ic->ic_caps & IEEE80211_C_SCANALL) &&
1214: (chan != bchan && ic->ic_phytype != IEEE80211_T_FH)) {
1215: /*
1216: * Frame was received on a channel different from the
1217: * one indicated in the DS params element id;
1218: * silently discard it.
1219: *
1220: * NB: this can happen due to signal leakage.
1221: * But we should take it for FH phy because
1222: * the rssi value should be correct even for
1223: * different hop pattern in FH.
1224: */
1225: IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked "
1226: "for channel %u\n", __func__, ISPROBE(wh) ?
1227: "probe response" : "beacon", bchan, chan));
1228: ic->ic_stats.is_rx_chanmismatch++;
1229: return;
1230: }
1231: /*
1232: * Use mac, channel and rssi so we collect only the
1233: * best potential AP with the equal bssid while scanning.
1234: * Collecting all potential APs may result in bloat of
1235: * the node tree. This call will return NULL if the node
1236: * for this APs does not exist or if the new node is the
1237: * potential better one.
1238: */
1239: if ((ni = ieee80211_find_node_for_beacon(ic, wh->i_addr2,
1240: &ic->ic_channels[chan], ssid, rssi)) != NULL)
1241: return;
1242:
1243: #ifdef IEEE80211_DEBUG
1244: if (ieee80211_debug &&
1245: (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) {
1246: printf("%s: %s%s on chan %u (bss chan %u) ",
1247: __func__, (ni == NULL ? "new " : ""),
1248: ISPROBE(wh) ? "probe response" : "beacon",
1249: chan, bchan);
1250: ieee80211_print_essid(ssid + 2, ssid[1]);
1251: printf(" from %s\n", ether_sprintf((u_int8_t *)wh->i_addr2));
1252: printf("%s: caps 0x%x bintval %u erp 0x%x\n",
1253: __func__, capinfo, bintval, erp);
1254: }
1255: #endif
1256:
1257: if ((ni = ieee80211_find_node(ic, wh->i_addr2)) == NULL) {
1258: ni = ieee80211_alloc_node(ic, wh->i_addr2);
1259: if (ni == NULL)
1260: return;
1261: is_new = 1;
1262: } else
1263: is_new = 0;
1264:
1265: /*
1266: * When operating in station mode, check for state updates
1267: * while we're associated. We consider only 11g stuff right
1268: * now.
1269: */
1270: if (ic->ic_opmode == IEEE80211_M_STA &&
1271: ic->ic_state == IEEE80211_S_ASSOC &&
1272: ni->ni_state == IEEE80211_STA_BSS) {
1273: /*
1274: * Check if protection mode has changed since last
1275: * beacon.
1276: */
1277: if (ni->ni_erp != erp) {
1278: IEEE80211_DPRINTF((
1279: "[%s] erp change: was 0x%x, now 0x%x\n",
1280: ether_sprintf((u_int8_t *)wh->i_addr2),
1281: ni->ni_erp, erp));
1282: if (ic->ic_curmode == IEEE80211_MODE_11G &&
1283: (erp & IEEE80211_ERP_USE_PROTECTION))
1284: ic->ic_flags |= IEEE80211_F_USEPROT;
1285: else
1286: ic->ic_flags &= ~IEEE80211_F_USEPROT;
1287: ic->ic_bss->ni_erp = erp;
1288: }
1289: /*
1290: * Check if AP short slot time setting has changed
1291: * since last beacon and give the driver a chance to
1292: * update the hardware.
1293: */
1294: if ((ni->ni_capinfo ^ capinfo) &
1295: IEEE80211_CAPINFO_SHORT_SLOTTIME) {
1296: ieee80211_set_shortslottime(ic,
1297: ic->ic_curmode == IEEE80211_MODE_11A ||
1298: (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1299: }
1300: }
1301: if (ni->ni_flags & IEEE80211_NODE_QOS) {
1302: if (edca != NULL)
1303: ieee80211_parse_edca_params(ic, edca);
1304: else if (wmm != NULL)
1305: ieee80211_parse_wmm_params(ic, edca);
1306: }
1307: if (ssid[1] != 0 && ni->ni_esslen == 0) {
1308: /*
1309: * Update ESSID at probe response to adopt hidden AP by
1310: * Lucent/Cisco, which announces null ESSID in beacon.
1311: */
1312: ni->ni_esslen = ssid[1];
1313: memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1314: memcpy(ni->ni_essid, ssid + 2, ssid[1]);
1315: }
1316: IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
1317: ni->ni_rssi = rssi;
1318: ni->ni_rstamp = rstamp;
1319: memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp));
1320: ni->ni_intval = bintval;
1321: ni->ni_capinfo = capinfo;
1322: /* XXX validate channel # */
1323: ni->ni_chan = &ic->ic_channels[chan];
1324: ni->ni_fhdwell = fhdwell;
1325: ni->ni_fhindex = fhindex;
1326: ni->ni_erp = erp;
1327: /* NB: must be after ni_chan is setup */
1328: ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
1329:
1330: /*
1331: * When scanning we record results (nodes) with a zero
1332: * refcnt. Otherwise we want to hold the reference for
1333: * ibss neighbors so the nodes don't get released prematurely.
1334: * Anything else can be discarded (XXX and should be handled
1335: * above so we don't do so much work).
1336: */
1337: if (ic->ic_opmode == IEEE80211_M_IBSS || (is_new && ISPROBE(wh))) {
1338: /*
1339: * Fake an association so the driver can setup it's
1340: * private state. The rate set has been setup above;
1341: * there is no handshake as in ap/station operation.
1342: */
1343: if (ic->ic_newassoc)
1344: (*ic->ic_newassoc)(ic, ni, 1);
1345: }
1346: #undef ISPROBE
1347: }
1348:
1349: /*-
1350: * Probe request frame format:
1351: * [tlv] SSID
1352: * [tlv] Supported rates
1353: * [tlv] Extended Supported Rates (802.11g)
1354: */
1355: void
1356: ieee80211_recv_probe_req(struct ieee80211com *ic, struct mbuf *m0,
1357: struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
1358: {
1359: const struct ieee80211_frame *wh;
1360: const u_int8_t *frm, *efrm;
1361: const u_int8_t *ssid, *rates, *xrates;
1362: u_int8_t rate;
1363:
1364: if (ic->ic_opmode == IEEE80211_M_STA ||
1365: ic->ic_state != IEEE80211_S_RUN)
1366: return;
1367:
1368: wh = mtod(m0, struct ieee80211_frame *);
1369: frm = (const u_int8_t *)&wh[1];
1370: efrm = mtod(m0, u_int8_t *) + m0->m_len;
1371:
1372: ssid = rates = xrates = NULL;
1373: while (frm + 2 <= efrm) {
1374: if (frm + 2 + frm[1] > efrm) {
1375: ic->ic_stats.is_rx_elem_toosmall++;
1376: return;
1377: }
1378: switch (frm[0]) {
1379: case IEEE80211_ELEMID_SSID:
1380: ssid = frm;
1381: break;
1382: case IEEE80211_ELEMID_RATES:
1383: rates = frm;
1384: break;
1385: case IEEE80211_ELEMID_XRATES:
1386: xrates = frm;
1387: break;
1388: }
1389: frm += 2 + frm[1];
1390: }
1391: IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1392: IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1393: IEEE80211_VERIFY_SSID(ic->ic_bss, ssid, "probe");
1394: if ((ic->ic_flags & IEEE80211_F_HIDENWID) && ssid[1] == 0) {
1395: IEEE80211_DPRINTF(("%s: no ssid "
1396: "with ssid suppression enabled", __func__));
1397: ic->ic_stats.is_rx_ssidmismatch++;
1398: return;
1399: }
1400:
1401: if (ni == ic->ic_bss) {
1402: ni = ieee80211_dup_bss(ic, wh->i_addr2);
1403: if (ni == NULL)
1404: return;
1405: IEEE80211_DPRINTF(("%s: new probe req from %s\n",
1406: __func__, ether_sprintf((u_int8_t *)wh->i_addr2)));
1407: }
1408: ni->ni_rssi = rssi;
1409: ni->ni_rstamp = rstamp;
1410: rate = ieee80211_setup_rates(ic, ni, rates, xrates,
1411: IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
1412: IEEE80211_F_DODEL);
1413: if (rate & IEEE80211_RATE_BASIC) {
1414: IEEE80211_DPRINTF(("%s: rate mismatch for %s\n",
1415: __func__, ether_sprintf((u_int8_t *)wh->i_addr2)));
1416: } else {
1417: IEEE80211_SEND_MGMT(ic, ni,
1418: IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
1419: }
1420: }
1421:
1422: /*-
1423: * Authentication frame format:
1424: * [2] Authentication algorithm number
1425: * [2] Authentication transaction sequence number
1426: * [2] Status code
1427: */
1428: void
1429: ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m0,
1430: struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
1431: {
1432: const struct ieee80211_frame *wh;
1433: const u_int8_t *frm, *efrm;
1434: u_int16_t algo, seq, status;
1435:
1436: wh = mtod(m0, struct ieee80211_frame *);
1437: frm = (const u_int8_t *)&wh[1];
1438: efrm = mtod(m0, u_int8_t *) + m0->m_len;
1439:
1440: IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
1441: algo = LE_READ_2(frm); frm += 2;
1442: seq = LE_READ_2(frm); frm += 2;
1443: status = LE_READ_2(frm); frm += 2;
1444: IEEE80211_DPRINTF(("%s: auth %d seq %d from %s\n",
1445: __func__, algo, seq, ether_sprintf((u_int8_t *)wh->i_addr2)));
1446:
1447: if (algo == IEEE80211_AUTH_ALG_OPEN)
1448: ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq, status);
1449: else {
1450: IEEE80211_DPRINTF(("%s: unsupported authentication "
1451: "algorithm %d from %s\n",
1452: __func__, algo, ether_sprintf((u_int8_t *)wh->i_addr2)));
1453: ic->ic_stats.is_rx_auth_unsupported++;
1454: if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1455: /* XXX hack to workaround calling convention */
1456: IEEE80211_SEND_MGMT(ic, ni,
1457: IEEE80211_FC0_SUBTYPE_AUTH,
1458: (seq+1) | (IEEE80211_STATUS_ALG<<16));
1459: }
1460: }
1461: }
1462:
1463: /*-
1464: * (Re)Association request frame format:
1465: * [2] Capability information
1466: * [2] Listen interval
1467: * [6*] Current AP address (Reassociation only)
1468: * [tlv] SSID
1469: * [tlv] Supported rates
1470: * [tlv] Extended Supported Rates (802.11g)
1471: * [tlv] RSN (802.11i)
1472: * [tlv] QoS Capability (802.11e)
1473: */
1474: void
1475: ieee80211_recv_assoc_req(struct ieee80211com *ic, struct mbuf *m0,
1476: struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
1477: {
1478: #define ISREASSOC(_wh) (((_wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == \
1479: IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
1480:
1481: const struct ieee80211_frame *wh;
1482: const u_int8_t *frm, *efrm;
1483: const u_int8_t *ssid, *rates, *xrates, *rsn, *wpa;
1484: u_int16_t capinfo, bintval;
1485: int reassoc, resp, reason = 0;
1486: u_int8_t rate;
1487:
1488: if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
1489: ic->ic_state != IEEE80211_S_RUN)
1490: return;
1491:
1492: wh = mtod(m0, struct ieee80211_frame *);
1493: frm = (const u_int8_t *)&wh[1];
1494: efrm = mtod(m0, u_int8_t *) + m0->m_len;
1495:
1496: if (ISREASSOC(wh)) {
1497: reassoc = 1;
1498: resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
1499: } else {
1500: reassoc = 0;
1501: resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
1502: }
1503:
1504: IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4));
1505: if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
1506: IEEE80211_DPRINTF(("%s: ignore other bss from %s\n",
1507: __func__, ether_sprintf((u_int8_t *)wh->i_addr2)));
1508: ic->ic_stats.is_rx_assoc_bss++;
1509: return;
1510: }
1511: capinfo = LE_READ_2(frm); frm += 2;
1512: bintval = LE_READ_2(frm); frm += 2;
1513: if (reassoc)
1514: frm += IEEE80211_ADDR_LEN; /* skip current AP address */
1515: ssid = rates = xrates = rsn = wpa = NULL;
1516: while (frm + 2 <= efrm) {
1517: if (frm + 2 + frm[1] > efrm) {
1518: ic->ic_stats.is_rx_elem_toosmall++;
1519: return;
1520: }
1521: switch (frm[0]) {
1522: case IEEE80211_ELEMID_SSID:
1523: ssid = frm;
1524: break;
1525: case IEEE80211_ELEMID_RATES:
1526: rates = frm;
1527: break;
1528: case IEEE80211_ELEMID_XRATES:
1529: xrates = frm;
1530: break;
1531: case IEEE80211_ELEMID_RSN:
1532: rsn = frm;
1533: break;
1534: case IEEE80211_ELEMID_QOS_CAP:
1535: break;
1536: case IEEE80211_ELEMID_VENDOR:
1537: if (frm[1] < 4) {
1538: ic->ic_stats.is_rx_elem_toosmall++;
1539: break;
1540: }
1541: if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
1542: if (frm[5] == 1)
1543: wpa = frm;
1544: }
1545: break;
1546: }
1547: frm += 2 + frm[1];
1548: }
1549: IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1550: IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1551: IEEE80211_VERIFY_SSID(ic->ic_bss, ssid,
1552: reassoc ? "reassoc" : "assoc");
1553: if (ni->ni_state != IEEE80211_STA_AUTH &&
1554: ni->ni_state != IEEE80211_STA_ASSOC) {
1555: IEEE80211_DPRINTF(
1556: ("%s: deny %sassoc from %s, not authenticated\n",
1557: __func__, reassoc ? "re" : "",
1558: ether_sprintf((u_int8_t *)wh->i_addr2)));
1559: ni = ieee80211_dup_bss(ic, wh->i_addr2);
1560: if (ni != NULL) {
1561: IEEE80211_SEND_MGMT(ic, ni,
1562: IEEE80211_FC0_SUBTYPE_DEAUTH,
1563: IEEE80211_REASON_ASSOC_NOT_AUTHED);
1564: }
1565: ic->ic_stats.is_rx_assoc_notauth++;
1566: return;
1567: }
1568: if (rsn != NULL)
1569: reason = ieee80211_parse_rsn(ic, ni, rsn);
1570: else if (wpa != NULL)
1571: reason = ieee80211_parse_wpa1(ic, ni, wpa);
1572: if (reason != 0) {
1573: IEEE80211_DPRINTF(("%s: invalid RSN IE for %s\n",
1574: __func__, ether_sprintf((u_int8_t *)wh->i_addr2)));
1575: IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
1576: reason);
1577: ieee80211_node_leave(ic, ni);
1578: ic->ic_stats.is_rx_assoc_badrsnie++;
1579: return;
1580: }
1581: if (!(capinfo & IEEE80211_CAPINFO_ESS)) {
1582: IEEE80211_DPRINTF(("%s: capinfo mismatch for %s\n",
1583: __func__, ether_sprintf((u_int8_t *)wh->i_addr2)));
1584: IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_CAPINFO);
1585: ieee80211_node_leave(ic, ni);
1586: ic->ic_stats.is_rx_assoc_capmismatch++;
1587: return;
1588: }
1589: rate = ieee80211_setup_rates(ic, ni, rates, xrates,
1590: IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
1591: IEEE80211_F_DODEL);
1592: if (rate & IEEE80211_RATE_BASIC) {
1593: IEEE80211_DPRINTF(("%s: rate mismatch for %s\n",
1594: __func__, ether_sprintf((u_int8_t *)wh->i_addr2)));
1595: IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_BASIC_RATE);
1596: ieee80211_node_leave(ic, ni);
1597: ic->ic_stats.is_rx_assoc_norate++;
1598: return;
1599: }
1600: ni->ni_rssi = rssi;
1601: ni->ni_rstamp = rstamp;
1602: ni->ni_intval = bintval;
1603: ni->ni_capinfo = capinfo;
1604: ni->ni_chan = ic->ic_bss->ni_chan;
1605: ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
1606: ni->ni_fhindex = ic->ic_bss->ni_fhindex;
1607:
1608: ieee80211_node_join(ic, ni, resp);
1609: #undef ISREASSOC
1610: }
1611:
1612: /*-
1613: * (Re)Association response frame format:
1614: * [2] Capability information
1615: * [2] Status code
1616: * [2] Association ID (AID)
1617: * [tlv] Supported rates
1618: * [tlv] Extended Supported Rates (802.11g)
1619: * [tlv] EDCA Parameter Set (802.11e)
1620: */
1621: void
1622: ieee80211_recv_assoc_resp(struct ieee80211com *ic, struct mbuf *m0,
1623: struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
1624: {
1625: #define ISREASSOC(_wh) (((_wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == \
1626: IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
1627:
1628: struct ifnet *ifp = &ic->ic_if;
1629: const struct ieee80211_frame *wh;
1630: const u_int8_t *frm, *efrm;
1631: const u_int8_t *rates, *xrates, *edca, *wmm;
1632: u_int16_t capinfo, status, associd;
1633: u_int8_t rate;
1634:
1635: if (ic->ic_opmode != IEEE80211_M_STA ||
1636: ic->ic_state != IEEE80211_S_ASSOC) {
1637: ic->ic_stats.is_rx_mgtdiscard++;
1638: return;
1639: }
1640:
1641: wh = mtod(m0, struct ieee80211_frame *);
1642: frm = (const u_int8_t *)&wh[1];
1643: efrm = mtod(m0, u_int8_t *) + m0->m_len;
1644:
1645: IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
1646: ni = ic->ic_bss;
1647: capinfo = LE_READ_2(frm); frm += 2;
1648: status = LE_READ_2(frm); frm += 2;
1649: if (status != 0) {
1650: if (ifp->if_flags & IFF_DEBUG)
1651: printf("%s: %sassociation failed (reason %d)"
1652: " for %s\n", ifp->if_xname,
1653: ISREASSOC(wh) ? "re" : "",
1654: status, ether_sprintf((u_int8_t *)wh->i_addr3));
1655: if (ni != ic->ic_bss)
1656: ni->ni_fails++;
1657: ic->ic_stats.is_rx_auth_fail++;
1658: return;
1659: }
1660: associd = LE_READ_2(frm); frm += 2;
1661:
1662: rates = xrates = edca = wmm = NULL;
1663: while (frm + 2 <= efrm) {
1664: if (frm + 2 + frm[1] > efrm) {
1665: ic->ic_stats.is_rx_elem_toosmall++;
1666: return;
1667: }
1668: switch (frm[0]) {
1669: case IEEE80211_ELEMID_RATES:
1670: rates = frm;
1671: break;
1672: case IEEE80211_ELEMID_XRATES:
1673: xrates = frm;
1674: break;
1675: case IEEE80211_ELEMID_EDCAPARMS:
1676: edca = frm;
1677: break;
1678: case IEEE80211_ELEMID_VENDOR:
1679: if (frm[1] < 4) {
1680: ic->ic_stats.is_rx_elem_toosmall++;
1681: break;
1682: }
1683: if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
1684: if (frm[1] >= 5 && frm[5] == 2 && frm[6] == 1)
1685: wmm = frm;
1686: }
1687: break;
1688: }
1689: frm += 2 + frm[1];
1690: }
1691:
1692: IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1693: rate = ieee80211_setup_rates(ic, ni, rates, xrates,
1694: IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
1695: IEEE80211_F_DODEL);
1696: if (rate & IEEE80211_RATE_BASIC) {
1697: IEEE80211_DPRINTF(("%s: rate mismatch for %s\n",
1698: __func__, ether_sprintf((u_int8_t *)wh->i_addr2)));
1699: ic->ic_stats.is_rx_assoc_norate++;
1700: return;
1701: }
1702: ni->ni_capinfo = capinfo;
1703: ni->ni_associd = associd;
1704: if (edca != NULL || wmm != NULL) {
1705: /* force update of EDCA parameters */
1706: ic->ic_edca_updtcount = -1;
1707:
1708: if ((edca != NULL &&
1709: ieee80211_parse_edca_params(ic, edca) == 0) ||
1710: (wmm != NULL &&
1711: ieee80211_parse_wmm_params(ic, wmm) == 0))
1712: ni->ni_flags |= IEEE80211_NODE_QOS;
1713: else /* for Reassociation */
1714: ni->ni_flags &= ~IEEE80211_NODE_QOS;
1715: }
1716: /*
1717: * Configure state now that we are associated.
1718: */
1719: if (ic->ic_curmode == IEEE80211_MODE_11A ||
1720: (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
1721: ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
1722: else
1723: ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
1724:
1725: ieee80211_set_shortslottime(ic,
1726: ic->ic_curmode == IEEE80211_MODE_11A ||
1727: (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1728: /*
1729: * Honor ERP protection.
1730: */
1731: if (ic->ic_curmode == IEEE80211_MODE_11G &&
1732: (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
1733: ic->ic_flags |= IEEE80211_F_USEPROT;
1734: else
1735: ic->ic_flags &= ~IEEE80211_F_USEPROT;
1736:
1737: ieee80211_new_state(ic, IEEE80211_S_RUN,
1738: wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1739: #undef ISREASSOC
1740: }
1741:
1742: /*-
1743: * Deauthentication frame format:
1744: * [2] Reason code
1745: */
1746: void
1747: ieee80211_recv_deauth(struct ieee80211com *ic, struct mbuf *m0,
1748: struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
1749: {
1750: struct ifnet *ifp = &ic->ic_if;
1751: const struct ieee80211_frame *wh;
1752: const u_int8_t *frm, *efrm;
1753: u_int16_t reason;
1754:
1755: wh = mtod(m0, struct ieee80211_frame *);
1756: frm = (const u_int8_t *)&wh[1];
1757: efrm = mtod(m0, u_int8_t *) + m0->m_len;
1758:
1759: IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1760: reason = LE_READ_2(frm);
1761: ic->ic_stats.is_rx_deauth++;
1762: switch (ic->ic_opmode) {
1763: case IEEE80211_M_STA:
1764: ieee80211_new_state(ic, IEEE80211_S_AUTH,
1765: wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1766: break;
1767: case IEEE80211_M_HOSTAP:
1768: if (ni != ic->ic_bss) {
1769: if (ifp->if_flags & IFF_DEBUG)
1770: printf("%s: station %s deauthenticated "
1771: "by peer (reason %d)\n",
1772: ifp->if_xname,
1773: ether_sprintf(ni->ni_macaddr),
1774: reason);
1775: ieee80211_node_leave(ic, ni);
1776: }
1777: break;
1778: default:
1779: break;
1780: }
1781: }
1782:
1783: /*-
1784: * Disassociation frame format:
1785: * [2] Reason code
1786: */
1787: void
1788: ieee80211_recv_disassoc(struct ieee80211com *ic, struct mbuf *m0,
1789: struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
1790: {
1791: struct ifnet *ifp = &ic->ic_if;
1792: const struct ieee80211_frame *wh;
1793: const u_int8_t *frm, *efrm;
1794: u_int16_t reason;
1795:
1796: wh = mtod(m0, struct ieee80211_frame *);
1797: frm = (const u_int8_t *)&wh[1];
1798: efrm = mtod(m0, u_int8_t *) + m0->m_len;
1799:
1800: IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1801: reason = LE_READ_2(frm);
1802: ic->ic_stats.is_rx_disassoc++;
1803: switch (ic->ic_opmode) {
1804: case IEEE80211_M_STA:
1805: ieee80211_new_state(ic, IEEE80211_S_ASSOC,
1806: wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1807: break;
1808: case IEEE80211_M_HOSTAP:
1809: if (ni != ic->ic_bss) {
1810: if (ifp->if_flags & IFF_DEBUG)
1811: printf("%s: station %s disassociated "
1812: "by peer (reason %d)\n",
1813: ifp->if_xname,
1814: ether_sprintf(ni->ni_macaddr),
1815: reason);
1816: ieee80211_node_leave(ic, ni);
1817: }
1818: break;
1819: default:
1820: break;
1821: }
1822: }
1823:
1824: void
1825: ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
1826: struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
1827: {
1828: switch (subtype) {
1829: case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1830: case IEEE80211_FC0_SUBTYPE_BEACON:
1831: ieee80211_recv_probe_resp(ic, m0, ni, rssi, rstamp);
1832: break;
1833: case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
1834: ieee80211_recv_probe_req(ic, m0, ni, rssi, rstamp);
1835: break;
1836: case IEEE80211_FC0_SUBTYPE_AUTH:
1837: ieee80211_recv_auth(ic, m0, ni, rssi, rstamp);
1838: break;
1839: case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1840: case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
1841: ieee80211_recv_assoc_req(ic, m0, ni, rssi, rstamp);
1842: break;
1843: case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
1844: case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
1845: ieee80211_recv_assoc_resp(ic, m0, ni, rssi, rstamp);
1846: break;
1847: case IEEE80211_FC0_SUBTYPE_DEAUTH:
1848: ieee80211_recv_deauth(ic, m0, ni, rssi, rstamp);
1849: break;
1850: case IEEE80211_FC0_SUBTYPE_DISASSOC:
1851: ieee80211_recv_disassoc(ic, m0, ni, rssi, rstamp);
1852: break;
1853: default:
1854: IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not "
1855: "handled\n", __func__, subtype));
1856: ic->ic_stats.is_rx_badsubtype++;
1857: break;
1858: }
1859: }
1860: #undef IEEE80211_VERIFY_LENGTH
1861: #undef IEEE80211_VERIFY_ELEMENT
1862: #undef IEEE80211_VERIFY_SSID
1863:
1864: /* unaligned big endian access */
1865: #define BE_READ_2(p) \
1866: ((u_int16_t)(p)[0] << 8 | (u_int16_t)(p)[1])
1867:
1868: #define BE_READ_8(p) \
1869: ((u_int64_t)(p)[0] << 56 | (u_int64_t)(p)[1] << 48 | \
1870: (u_int64_t)(p)[2] << 40 | (u_int64_t)(p)[3] << 32 | \
1871: (u_int64_t)(p)[4] << 24 | (u_int64_t)(p)[5] << 16 | \
1872: (u_int64_t)(p)[6] << 8 | (u_int64_t)(p)[7])
1873:
1874: #define BE_WRITE_2(p, v) do { \
1875: (p)[0] = (v) >> 8; \
1876: (p)[1] = (v) & 0xff; \
1877: } while (0)
1878:
1879: /* unaligned little endian access */
1880: #define LE_READ_8(p) \
1881: ((u_int64_t)(p)[7] << 56 | (u_int64_t)(p)[6] << 48 | \
1882: (u_int64_t)(p)[5] << 40 | (u_int64_t)(p)[4] << 32 | \
1883: (u_int64_t)(p)[3] << 24 | (u_int64_t)(p)[2] << 16 | \
1884: (u_int64_t)(p)[1] << 8 | (u_int64_t)(p)[0])
1885:
1886: /*
1887: * 4-Way Handshake Message 1 is sent by the authenticator to the supplicant
1888: * (see 8.5.3.1).
1889: */
1890: void
1891: ieee80211_recv_4way_msg1(struct ieee80211com *ic,
1892: const struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
1893: {
1894: u_int8_t snonce[EAPOL_KEY_NONCE_LEN];
1895: const u_int8_t *frm, *efrm;
1896: const u_int8_t *pmkid;
1897: const u_int8_t *pmk;
1898: size_t pmk_len;
1899:
1900: if (ic->ic_opmode != IEEE80211_M_STA &&
1901: ic->ic_opmode != IEEE80211_M_IBSS)
1902: return;
1903:
1904: if (ni->ni_replaycnt_ok &&
1905: BE_READ_8(key->replaycnt) <= ni->ni_replaycnt)
1906: return;
1907:
1908: /* save authenticator's nonce (ANonce) */
1909: memcpy(ni->ni_nonce, key->nonce, EAPOL_KEY_NONCE_LEN);
1910:
1911: /* parse key data field (shall contain an encapsulated PMKID) */
1912: frm = (const u_int8_t *)&key[1];
1913: efrm = frm + BE_READ_2(key->paylen);
1914:
1915: pmkid = NULL;
1916: while (frm + 2 <= efrm) {
1917: if (frm + 2 + frm[1] > efrm)
1918: break;
1919: switch (frm[0]) {
1920: case IEEE80211_ELEMID_VENDOR:
1921: if (frm[1] < 4)
1922: break;
1923: if (memcmp(&frm[2], IEEE80211_OUI, 3) == 0) {
1924: switch (frm[5]) {
1925: case IEEE80211_KDE_PMKID:
1926: pmkid = frm;
1927: break;
1928: }
1929: }
1930: break;
1931: }
1932: frm += 2 + frm[1];
1933: }
1934: /* check that the PMKID KDE is valid */
1935: if (pmkid != NULL && pmkid[1] - 4 < 16)
1936: return;
1937:
1938: /* update the last seen value of the key replay counter field */
1939: ni->ni_replaycnt = BE_READ_8(key->replaycnt);
1940: /* do not set ni_replaycnt_ok since the frame contains no MIC */
1941:
1942: /* generate a new nonce (SNonce) */
1943: get_random_bytes(snonce, EAPOL_KEY_NONCE_LEN);
1944:
1945: if (ni->ni_akm == IEEE80211_AKM_IEEE8021X) {
1946: /* XXX find the PMK in the PMKSA cache using the PMKID */
1947: } else {
1948: /* XXX the PMK is the PSK */
1949: }
1950:
1951: /* derive PTK from PMK */
1952: ieee80211_derive_ptk(pmk, pmk_len, ni->ni_macaddr, ic->ic_myaddr,
1953: ni->ni_nonce, snonce, (u_int8_t *)&ni->ni_ptk, sizeof(ni->ni_ptk));
1954: ni->ni_ptk_ok = 1;
1955:
1956: if (ic->ic_if.if_flags & IFF_DEBUG)
1957: printf("%s: received msg %d/%d of the %s handshake from %s\n",
1958: ic->ic_if.if_xname, 1, 4, "4-way",
1959: ether_sprintf(ni->ni_macaddr));
1960:
1961: /* send message 2 to authenticator */
1962: ieee80211_send_4way_msg2(ic, ni, snonce);
1963: }
1964:
1965: /*
1966: * 4-Way Handshake Message 2 is sent by the supplicant to the authenticator
1967: * (see 8.5.3.2).
1968: */
1969: void
1970: ieee80211_recv_4way_msg2(struct ieee80211com *ic,
1971: const struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
1972: {
1973: const u_int8_t *frm, *efrm;
1974: const u_int8_t *rsn;
1975: const u_int8_t *pmk;
1976: size_t pmk_len;
1977:
1978: if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
1979: ic->ic_opmode != IEEE80211_M_IBSS)
1980: return;
1981:
1982: if (BE_READ_8(key->replaycnt) != ni->ni_replaycnt)
1983: return;
1984:
1985: /* derive PTK from PMK */
1986: ieee80211_derive_ptk(pmk, pmk_len, ic->ic_myaddr, ni->ni_macaddr,
1987: ni->ni_nonce, key->nonce, (u_int8_t *)&ni->ni_ptk,
1988: sizeof(ni->ni_ptk));
1989: ni->ni_ptk_ok = 1;
1990:
1991: /* parse key data field (shall contain an RSN IE) */
1992: frm = (const u_int8_t *)&key[1];
1993: efrm = frm + BE_READ_2(key->paylen);
1994:
1995: rsn = NULL;
1996: while (frm + 2 <= efrm) {
1997: if (frm + 2 + frm[1] > efrm)
1998: break;
1999: switch (frm[0]) {
2000: case IEEE80211_ELEMID_RSN:
2001: rsn = frm;
2002: break;
2003: case IEEE80211_ELEMID_VENDOR:
2004: if (frm[1] < 4)
2005: break;
2006: if (memcmp(&frm[2], MICROSOFT_OUI, 3) == 0) {
2007: switch (frm[5]) {
2008: case 1: /* WPA */
2009: rsn = frm;
2010: break;
2011: }
2012: }
2013: }
2014: frm += 2 + frm[1];
2015: }
2016: if (rsn == NULL)
2017: return;
2018:
2019: /*
2020: * The RSN IE must match bit-wise with what the STA included in its
2021: * (Re)Association Request.
2022: */
2023: if (ni->ni_rsnie == NULL || rsn[1] != ni->ni_rsnie[1] ||
2024: memcmp(rsn, ni->ni_rsnie, 2 + rsn[1]) != 0)
2025: return;
2026:
2027: if (ic->ic_if.if_flags & IFF_DEBUG)
2028: printf("%s: received msg %d/%d of the %s handshake from %s\n",
2029: ic->ic_if.if_xname, 2, 4, "4-way",
2030: ether_sprintf(ni->ni_macaddr));
2031:
2032: /* send message 3 to supplicant */
2033: ieee80211_send_4way_msg3(ic, ni);
2034: }
2035:
2036: /*
2037: * 4-Way Handshake Message 3 is sent by the authenticator to the supplicant
2038: * (see 8.5.3.3).
2039: */
2040: void
2041: ieee80211_recv_4way_msg3(struct ieee80211com *ic,
2042: const struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
2043: {
2044: struct ieee80211_key *k;
2045: const u_int8_t *frm, *efrm;
2046: const u_int8_t *rsn1, *rsn2, *gtk;
2047:
2048: if (ic->ic_opmode != IEEE80211_M_STA &&
2049: ic->ic_opmode != IEEE80211_M_IBSS)
2050: return;
2051:
2052: if (BE_READ_8(key->replaycnt) <= ni->ni_replaycnt)
2053: return;
2054:
2055: /* check that ANonce matches the one received in message 1 */
2056: if (memcmp(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN) != 0)
2057: return;
2058:
2059: /* parse key data field */
2060: frm = (const u_int8_t *)&key[1];
2061: efrm = frm + BE_READ_2(key->paylen);
2062:
2063: rsn1 = rsn2 = gtk = NULL;
2064: while (frm + 2 <= efrm) {
2065: if (frm + 2 + frm[1] > efrm)
2066: break;
2067: switch (frm[0]) {
2068: case IEEE80211_ELEMID_RSN:
2069: if (rsn1 == NULL)
2070: rsn1 = frm;
2071: else if (rsn2 == NULL)
2072: rsn2 = frm;
2073: /* ignore if more than two RSN IEs */
2074: break;
2075: case IEEE80211_ELEMID_VENDOR:
2076: if (frm[1] < 4)
2077: break;
2078: if (memcmp(&frm[2], IEEE80211_OUI, 3) == 0) {
2079: switch (frm[5]) {
2080: case IEEE80211_KDE_GTK:
2081: gtk = frm;
2082: break;
2083: }
2084: } else if (memcmp(&frm[2], MICROSOFT_OUI, 3) == 0) {
2085: switch (frm[5]) {
2086: case 1: /* WPA */
2087: rsn1 = frm;
2088: break;
2089: }
2090: }
2091: break;
2092: }
2093: frm += 2 + frm[1];
2094: }
2095: /* first WPA/RSN IE is mandatory */
2096: if (rsn1 == NULL)
2097: return;
2098: /* key data must be encrypted if GTK is included */
2099: if (gtk != NULL && !(BE_READ_2(key->info) & EAPOL_KEY_ENCRYPTED))
2100: return;
2101:
2102: /*
2103: * Check that first RSN IE is identical to the one received in
2104: * the beacon or probe response frame.
2105: */
2106: if (ni->ni_rsnie == NULL || rsn1[1] != ni->ni_rsnie[1] ||
2107: memcmp(rsn1, ni->ni_rsnie, 2 + rsn1[1]) != 0)
2108: return;
2109:
2110: /* update the last seen value of the key replay counter field */
2111: ni->ni_replaycnt = BE_READ_8(key->replaycnt);
2112: ni->ni_replaycnt_ok = 1;
2113:
2114: /*
2115: * If a second RSN information element is present, use its pairwise
2116: * cipher suite or deauthenticate.
2117: */
2118: if (rsn2 != NULL) {
2119: /* XXX ieee80211_parse_rsn(rsn2); */
2120: }
2121:
2122: /* install the PTK */
2123: k = &ni->ni_pairwise_key;
2124: memset(k, 0, sizeof(*k));
2125: k->k_cipher = ni->ni_pairwise_cipher;
2126: k->k_flags = IEEE80211_KEY_TX;
2127: k->k_len = BE_READ_2(key->keylen);
2128: /* check that key length matches pairwise cipher */
2129: if (k->k_len != ieee80211_cipher_keylen(k->k_cipher))
2130: return;
2131: memcpy(k->k_key, ni->ni_ptk.tk, k->k_len);
2132: if (ic->ic_set_key != NULL && (*ic->ic_set_key)(ic, ni, k) != 0)
2133: return;
2134:
2135: if (gtk != NULL) {
2136: u_int8_t kid;
2137:
2138: /* check that the GTK KDE is valid */
2139: if (gtk[1] - 4 < 2)
2140: return;
2141:
2142: /* install the GTK */
2143: kid = gtk[6] & 3;
2144: k = &ic->ic_nw_keys[kid];
2145: memset(k, 0, sizeof(*k));
2146: k->k_id = kid;
2147: k->k_cipher = ni->ni_group_cipher;
2148: k->k_flags = IEEE80211_KEY_GROUP;
2149: if (gtk[6] & (1 << 2)) /* Tx bit */
2150: k->k_flags |= IEEE80211_KEY_TX;
2151: k->k_len = gtk[1] - 6;
2152: /* check that key length matches group cipher */
2153: if (k->k_len != ieee80211_cipher_keylen(k->k_cipher))
2154: return; /* XXX PTK already installed! */
2155: memcpy(k->k_key, >k[8], k->k_len);
2156: k->k_rsc = LE_READ_8(key->rsc);
2157: if (ic->ic_set_key != NULL &&
2158: (*ic->ic_set_key)(ic, ni, k) != 0)
2159: return;
2160: }
2161:
2162: /* mark the PAE port as valid */
2163: ni->ni_port_valid = 1;
2164:
2165: if (ic->ic_if.if_flags & IFF_DEBUG)
2166: printf("%s: received msg %d/%d of the %s handshake from %s\n",
2167: ic->ic_if.if_xname, 3, 4, "4-way",
2168: ether_sprintf(ni->ni_macaddr));
2169:
2170: /* send message 4 to authenticator */
2171: ieee80211_send_4way_msg4(ic, ni);
2172: }
2173:
2174: /*
2175: * 4-Way Handshake Message 4 is sent by the supplicant to the authenticator
2176: * (see 8.5.3.4).
2177: */
2178: void
2179: ieee80211_recv_4way_msg4(struct ieee80211com *ic,
2180: const struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
2181: {
2182: struct ieee80211_key *k;
2183:
2184: if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
2185: ic->ic_opmode != IEEE80211_M_IBSS)
2186: return;
2187:
2188: if (BE_READ_8(key->replaycnt) != ni->ni_replaycnt)
2189: return;
2190:
2191: /* empty key data field */
2192:
2193: /* install the PTK */
2194: k = &ni->ni_pairwise_key;
2195: memset(k, 0, sizeof(*k));
2196: k->k_cipher = ni->ni_pairwise_cipher;
2197: k->k_flags = IEEE80211_KEY_TX;
2198: k->k_len = ieee80211_cipher_keylen(k->k_cipher);
2199: memcpy(k->k_key, ni->ni_ptk.tk, k->k_len);
2200: if (ic->ic_set_key != NULL && (*ic->ic_set_key)(ic, ni, k) != 0)
2201: return;
2202:
2203: if (ic->ic_opmode == IEEE80211_M_IBSS) {
2204: if (++ni->ni_key_count == 2)
2205: ni->ni_port_valid = 1;
2206: } else
2207: ni->ni_port_valid = 1;
2208:
2209: /* increment the 64-bit Key Replay Counter */
2210: ni->ni_replaycnt++;
2211:
2212: if (ic->ic_if.if_flags & IFF_DEBUG)
2213: printf("%s: received msg %d/%d of the %s handshake from %s\n",
2214: ic->ic_if.if_xname, 4, 4, "4-way",
2215: ether_sprintf(ni->ni_macaddr));
2216: }
2217:
2218: /*
2219: * Group Key Handshake Message 1 is sent by the authenticator to the
2220: * supplicant (see 8.5.4.1).
2221: */
2222: void
2223: ieee80211_recv_rsn_group_msg1(struct ieee80211com *ic,
2224: const struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
2225: {
2226: struct ieee80211_key *k;
2227: const u_int8_t *frm, *efrm;
2228: const u_int8_t *gtk;
2229: u_int8_t kid;
2230:
2231: if (ic->ic_opmode != IEEE80211_M_STA &&
2232: ic->ic_opmode != IEEE80211_M_IBSS)
2233: return;
2234:
2235: if (BE_READ_8(key->replaycnt) <= ni->ni_replaycnt)
2236: return;
2237:
2238: /* parse key data field (shall contain a GTK KDE) */
2239: frm = (const u_int8_t *)&key[1];
2240: efrm = frm + BE_READ_2(key->paylen);
2241:
2242: gtk = NULL;
2243: while (frm + 2 <= efrm) {
2244: if (frm + 2 + frm[1] > efrm)
2245: break;
2246: switch (frm[0]) {
2247: case IEEE80211_ELEMID_VENDOR:
2248: if (frm[1] < 4)
2249: break;
2250: if (memcmp(&frm[2], IEEE80211_OUI, 3) == 0) {
2251: switch (frm[5]) {
2252: case IEEE80211_KDE_GTK:
2253: gtk = frm;
2254: break;
2255: }
2256: }
2257: break;
2258: }
2259: frm += 2 + frm[1];
2260: }
2261: if (gtk == NULL || !(BE_READ_2(key->info) & EAPOL_KEY_ENCRYPTED))
2262: return;
2263:
2264: /* check that the GTK KDE is valid */
2265: if (gtk[1] - 4 < 2)
2266: return;
2267:
2268: /* install the GTK */
2269: kid = gtk[6] & 3;
2270: k = &ic->ic_nw_keys[kid];
2271: memset(k, 0, sizeof(*k));
2272: k->k_id = kid;
2273: k->k_cipher = ni->ni_group_cipher;
2274: k->k_flags = IEEE80211_KEY_GROUP;
2275: if (gtk[6] & (1 << 2)) /* Tx bit */
2276: k->k_flags |= IEEE80211_KEY_TX;
2277: k->k_len = gtk[1] - 6;
2278: /* check that key length matches group cipher */
2279: if (k->k_len != ieee80211_cipher_keylen(k->k_cipher))
2280: return;
2281: memcpy(k->k_key, >k[8], k->k_len);
2282: k->k_rsc = LE_READ_8(key->rsc);
2283: if (ic->ic_set_key != NULL && (*ic->ic_set_key)(ic, ni, k) != 0)
2284: return;
2285:
2286: /* update the last seen value of the key replay counter field */
2287: ni->ni_replaycnt = BE_READ_8(key->replaycnt);
2288:
2289: if (ic->ic_if.if_flags & IFF_DEBUG)
2290: printf("%s: received msg %d/%d of the %s handshake from %s\n",
2291: ic->ic_if.if_xname, 1, 2, "group key",
2292: ether_sprintf(ni->ni_macaddr));
2293:
2294: /* send message 2 to authenticator */
2295: ieee80211_send_group_msg2(ic, ni, k);
2296: }
2297:
2298: void
2299: ieee80211_recv_wpa_group_msg1(struct ieee80211com *ic,
2300: struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
2301: {
2302: struct ieee80211_key *k;
2303: u_int16_t info;
2304: u_int8_t kid;
2305:
2306: if (ic->ic_opmode != IEEE80211_M_STA &&
2307: ic->ic_opmode != IEEE80211_M_IBSS)
2308: return;
2309:
2310: if (BE_READ_8(key->replaycnt) <= ni->ni_replaycnt)
2311: return;
2312:
2313: /*
2314: * EAPOL-Key data field is encrypted even though WPA1 doesn't set
2315: * the ENCRYPTED bit in the info field.
2316: */
2317: if (!ni->ni_ptk_ok ||
2318: ieee80211_eapol_key_decrypt(key, ni->ni_ptk.kek) != 0)
2319: return;
2320:
2321: info = BE_READ_2(key->info);
2322:
2323: /* install the GTK */
2324: kid = (info >> EAPOL_KEY_WPA_KID_SHIFT) & 3;
2325: k = &ic->ic_nw_keys[kid];
2326: memset(k, 0, sizeof(*k));
2327: k->k_id = kid;
2328: k->k_cipher = ni->ni_group_cipher;
2329: k->k_flags = IEEE80211_KEY_GROUP;
2330: if (info & EAPOL_KEY_WPA_TX)
2331: k->k_flags |= IEEE80211_KEY_TX;
2332: k->k_len = BE_READ_2(key->keylen);
2333: /* check that key length matches group cipher */
2334: if (k->k_len != ieee80211_cipher_keylen(k->k_cipher))
2335: return;
2336: memcpy(k->k_key, (u_int8_t *)&key[1], k->k_len);
2337: k->k_rsc = LE_READ_8(key->rsc);
2338: if (ic->ic_set_key != NULL && (*ic->ic_set_key)(ic, ni, k) != 0)
2339: return;
2340:
2341: /* update the last seen value of the key replay counter field */
2342: ni->ni_replaycnt = BE_READ_8(key->replaycnt);
2343:
2344: if (ic->ic_if.if_flags & IFF_DEBUG)
2345: printf("%s: received msg %d/%d of the %s handshake from %s\n",
2346: ic->ic_if.if_xname, 1, 2, "group key",
2347: ether_sprintf(ni->ni_macaddr));
2348:
2349: /* send message 2 to authenticator */
2350: ieee80211_send_group_msg2(ic, ni, k);
2351: }
2352:
2353: /*
2354: * Group Key Handshake Message 2 is sent by the supplicant to the
2355: * authenticator (see 8.5.4.2).
2356: */
2357: void
2358: ieee80211_recv_group_msg2(struct ieee80211com *ic,
2359: const struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
2360: {
2361: if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
2362: ic->ic_opmode != IEEE80211_M_IBSS)
2363: return;
2364:
2365: if (BE_READ_8(key->replaycnt) != ni->ni_replaycnt)
2366: return;
2367:
2368: /* empty key data field */
2369:
2370: #ifdef notyet
2371: if (--ic->ic_keydone_sta == 0) {
2372: /* install GTK */
2373: }
2374: #endif
2375: if (ic->ic_if.if_flags & IFF_DEBUG)
2376: printf("%s: received msg %d/%d of the %s handshake from %s\n",
2377: ic->ic_if.if_xname, 2, 2, "group key",
2378: ether_sprintf(ni->ni_macaddr));
2379: }
2380:
2381: /*
2382: * EAPOL-Key Request frames are sent by the supplicant to request that the
2383: * authenticator initiate either a 4-Way Handshake or Group Key Handshake
2384: * and to report a MIC failure in a TKIP MSDU.
2385: */
2386: void
2387: ieee80211_recv_eapol_key_req(struct ieee80211com *ic,
2388: const struct ieee80211_eapol_key *key, struct ieee80211_node *ni)
2389: {
2390: u_int16_t info;
2391:
2392: if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
2393: ic->ic_opmode != IEEE80211_M_IBSS)
2394: return;
2395:
2396: info = BE_READ_2(key->info);
2397:
2398: if (info & EAPOL_KEY_ERROR) {
2399: /* TKIP MIC failure */
2400:
2401: } else if (info & EAPOL_KEY_PAIRWISE) {
2402: /* initiate the 4-Way Handshake */
2403:
2404: } else {
2405: /*
2406: * Should change the GTK, initiate the 4-Way Handshake and
2407: * then execute a Group Key Handshake with all supplicants.
2408: */
2409: }
2410: }
2411:
2412: #ifdef IEEE80211_DEBUG
2413: static void
2414: ieee80211_print_eapol_key(struct ieee80211com *ic,
2415: const struct ieee80211_eapol_key *key, const struct ieee80211_node *ni)
2416: {
2417: int i;
2418: printf("%s: received EAPOL-Key frame from %s\n",
2419: ic->ic_if.if_xname, ether_sprintf((u_int8_t *)ni->ni_macaddr));
2420: printf("version=0x%02x type=0x%02x desc=0x%02x body length=%d "
2421: "data length=%d\n", key->version, key->type, key->desc,
2422: BE_READ_2(key->len), BE_READ_2(key->paylen));
2423: printf("info=%b\n", BE_READ_2(key->info),
2424: "\20\x03PAIRWISE\x06INSTALL\x07KEYACK\x08KEYMIC\x09SECURE"
2425: "\x0aERROR\x0bREQUEST\x0cENCRYPTED\x0dSMK");
2426: printf("Key Replay Counter=0x");
2427: for (i = 0; i < 8; i++)
2428: printf("%02x", key->replaycnt[i]);
2429: printf("\n");
2430: printf("Key Nonce=0x");
2431: for (i = 0; i < EAPOL_KEY_NONCE_LEN; i++)
2432: printf("%02x", key->nonce[i]);
2433: printf("\n");
2434: printf("Key IV=0x");
2435: for (i = 0; i < EAPOL_KEY_IV_LEN; i++)
2436: printf("%02x", key->iv[i]);
2437: printf("\n");
2438: printf("Key RSC=0x");
2439: for (i = 0; i < 8; i++)
2440: printf("%02x", key->rsc[i]);
2441: printf("\n");
2442: printf("Key MIC=0x");
2443: for (i = 0; i < EAPOL_KEY_MIC_LEN; i++)
2444: printf("%02x", key->mic[i]);
2445: printf("\n");
2446: }
2447: #endif
2448:
2449: /*
2450: * Process an incoming EAPOL frame. Notice that we are only interested in
2451: * EAPOL-Key frames with an IEEE 802.11 or WPA1 descriptor type.
2452: */
2453: void
2454: ieee80211_recv_eapol(struct ieee80211com *ic, struct mbuf *m0,
2455: struct ieee80211_node *ni)
2456: {
2457: struct ieee80211_eapol_key *key;
2458: u_int16_t info;
2459:
2460: if (m0->m_len < sizeof(struct ether_header) + sizeof(*key))
2461: goto out;
2462:
2463: m_adj(m0, sizeof(struct ether_header));
2464: key = mtod(m0, struct ieee80211_eapol_key *);
2465:
2466: if (key->type != EAPOL_KEY || key->desc != ni->ni_eapol_desc)
2467: goto out;
2468:
2469: /* check packet body length */
2470: if (m0->m_len < 4 + BE_READ_2(key->len))
2471: goto out;
2472:
2473: /* check key data length */
2474: if (m0->m_len < sizeof(*key) + BE_READ_2(key->paylen))
2475: goto out;
2476:
2477: #ifdef IEEE80211_DEBUG
2478: if (ieee80211_debug > 0)
2479: ieee80211_print_eapol_key(ic, key, ni);
2480: #endif
2481: info = BE_READ_2(key->info);
2482:
2483: if (info & (EAPOL_KEY_KEYMIC | EAPOL_KEY_ENCRYPTED)) {
2484: /* check that we have a valid PTK or TPTK */
2485: if (!ni->ni_ptk_ok)
2486: goto out;
2487:
2488: if (ni->ni_pairwise_cipher == IEEE80211_CIPHER_CCMP &&
2489: (info & EAPOL_KEY_VERSION_MASK) != EAPOL_KEY_DESC_V2)
2490: goto out;
2491:
2492: /* check Key MIC field using KCK */
2493: if ((info & EAPOL_KEY_KEYMIC) &&
2494: ieee80211_eapol_key_check_mic(key, ni->ni_ptk.kck) != 0)
2495: goto out;
2496:
2497: /* decrypt Key Data field using KEK */
2498: if ((info & EAPOL_KEY_ENCRYPTED) &&
2499: ieee80211_eapol_key_decrypt(key, ni->ni_ptk.kek) != 0)
2500: goto out;
2501: }
2502:
2503: /* determine message type (see 8.5.3.7) */
2504: if (info & EAPOL_KEY_REQUEST) {
2505: /* EAPOL-Key Request */
2506: ieee80211_recv_eapol_key_req(ic, key, ni);
2507:
2508: } else if (info & EAPOL_KEY_PAIRWISE) {
2509: /* 4-Way Handshake */
2510: if (info & EAPOL_KEY_KEYMIC) {
2511: if (!(info & EAPOL_KEY_KEYACK)) {
2512: if (info & EAPOL_KEY_SECURE)
2513: ieee80211_recv_4way_msg4(ic, key, ni);
2514: else
2515: ieee80211_recv_4way_msg2(ic, key, ni);
2516: } else
2517: ieee80211_recv_4way_msg3(ic, key, ni);
2518: } else
2519: ieee80211_recv_4way_msg1(ic, key, ni);
2520: } else {
2521: /* Group Key Handshake */
2522: if (!(info & EAPOL_KEY_KEYMIC))
2523: goto out;
2524: if (info & EAPOL_KEY_KEYACK) {
2525: if (key->desc == EAPOL_KEY_DESC_WPA1)
2526: ieee80211_recv_wpa_group_msg1(ic, key, ni);
2527: else
2528: ieee80211_recv_rsn_group_msg1(ic, key, ni);
2529: } else
2530: ieee80211_recv_group_msg2(ic, key, ni);
2531: }
2532: out:
2533: m_freem(m0);
2534: }
2535:
2536: void
2537: ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m0, int rssi,
2538: u_int32_t rstamp)
2539: {
2540: struct ifnet *ifp = &ic->ic_if;
2541: struct ieee80211_frame *wh;
2542: struct ieee80211_node *ni;
2543: struct mbuf *m;
2544: u_int16_t aid;
2545:
2546: if (ic->ic_set_tim == NULL) /* no powersaving functionality */
2547: return;
2548:
2549: wh = mtod(m0, struct ieee80211_frame *);
2550:
2551: if ((ni = ieee80211_find_node(ic, wh->i_addr2)) == NULL) {
2552: if (ifp->if_flags & IFF_DEBUG)
2553: printf("%s: station %s sent bogus power save poll\n",
2554: ifp->if_xname, ether_sprintf(wh->i_addr2));
2555: return;
2556: }
2557:
2558: memcpy(&aid, wh->i_dur, sizeof(wh->i_dur));
2559: if ((aid & 0xc000) != 0xc000) {
2560: if (ifp->if_flags & IFF_DEBUG)
2561: printf("%s: station %s sent bogus aid %x\n",
2562: ifp->if_xname, ether_sprintf(wh->i_addr2), aid);
2563: return;
2564: }
2565:
2566: if (aid != ni->ni_associd) {
2567: if (ifp->if_flags & IFF_DEBUG)
2568: printf("%s: station %s aid %x doesn't match pspoll "
2569: "aid %x\n", ifp->if_xname,
2570: ether_sprintf(wh->i_addr2), ni->ni_associd, aid);
2571: return;
2572: }
2573:
2574: /* Okay, take the first queued packet and put it out... */
2575:
2576: IF_DEQUEUE(&ni->ni_savedq, m);
2577: if (m == NULL) {
2578: if (ifp->if_flags & IFF_DEBUG)
2579: printf("%s: station %s sent pspoll, "
2580: "but no packets are saved\n",
2581: ifp->if_xname, ether_sprintf(wh->i_addr2));
2582: return;
2583: }
2584: wh = mtod(m, struct ieee80211_frame *);
2585:
2586: /*
2587: * If this is the last packet, turn off the TIM fields.
2588: * If there are more packets, set the more packets bit.
2589: */
2590:
2591: if (IF_IS_EMPTY(&ni->ni_savedq))
2592: (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
2593: else
2594: wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
2595:
2596: if (ifp->if_flags & IFF_DEBUG)
2597: printf("%s: enqueued power saving packet for station %s\n",
2598: ifp->if_xname, ether_sprintf(ni->ni_macaddr));
2599:
2600: IF_ENQUEUE(&ic->ic_pwrsaveq, m);
2601: (*ifp->if_start)(ifp);
2602: }
2603:
2604: int
2605: ieee80211_do_slow_print(struct ieee80211com *ic, int *did_print)
2606: {
2607: static const struct timeval merge_print_intvl = {
2608: .tv_sec = 1, .tv_usec = 0
2609: };
2610: if ((ic->ic_if.if_flags & IFF_LINK0) == 0)
2611: return 0;
2612: if (!*did_print && (ic->ic_if.if_flags & IFF_DEBUG) == 0 &&
2613: !ratecheck(&ic->ic_last_merge_print, &merge_print_intvl))
2614: return 0;
2615:
2616: *did_print = 1;
2617: return 1;
2618: }
2619:
2620: /* ieee80211_ibss_merge helps merge 802.11 ad hoc networks. The
2621: * convention, set by the Wireless Ethernet Compatibility Alliance
2622: * (WECA), is that an 802.11 station will change its BSSID to match
2623: * the "oldest" 802.11 ad hoc network, on the same channel, that
2624: * has the station's desired SSID. The "oldest" 802.11 network
2625: * sends beacons with the greatest TSF timestamp.
2626: *
2627: * Return ENETRESET if the BSSID changed, 0 otherwise.
2628: *
2629: * XXX Perhaps we should compensate for the time that elapses
2630: * between the MAC receiving the beacon and the host processing it
2631: * in ieee80211_ibss_merge.
2632: */
2633: int
2634: ieee80211_ibss_merge(struct ieee80211com *ic, struct ieee80211_node *ni,
2635: u_int64_t local_tsft)
2636: {
2637: u_int64_t beacon_tsft;
2638: int did_print = 0, sign;
2639: union {
2640: u_int64_t word;
2641: u_int8_t tstamp[8];
2642: } u;
2643:
2644: /* ensure alignment */
2645: (void)memcpy(&u, &ni->ni_tstamp[0], sizeof(u));
2646: beacon_tsft = letoh64(u.word);
2647:
2648: /* we are faster, let the other guy catch up */
2649: if (beacon_tsft < local_tsft)
2650: sign = -1;
2651: else
2652: sign = 1;
2653:
2654: if (IEEE80211_ADDR_EQ(ni->ni_bssid, ic->ic_bss->ni_bssid)) {
2655: if (!ieee80211_do_slow_print(ic, &did_print))
2656: return 0;
2657: printf("%s: tsft offset %s%llu\n", ic->ic_if.if_xname,
2658: (sign < 0) ? "-" : "",
2659: (sign < 0)
2660: ? (local_tsft - beacon_tsft)
2661: : (beacon_tsft - local_tsft));
2662: return 0;
2663: }
2664:
2665: if (sign < 0)
2666: return 0;
2667:
2668: if (ieee80211_match_bss(ic, ni) != 0)
2669: return 0;
2670:
2671: if (ieee80211_do_slow_print(ic, &did_print)) {
2672: printf("%s: ieee80211_ibss_merge: bssid mismatch %s\n",
2673: ic->ic_if.if_xname, ether_sprintf(ni->ni_bssid));
2674: printf("%s: my tsft %llu beacon tsft %llu\n",
2675: ic->ic_if.if_xname, local_tsft, beacon_tsft);
2676: printf("%s: sync TSF with %s\n",
2677: ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr));
2678: }
2679:
2680: ic->ic_flags &= ~IEEE80211_F_SIBSS;
2681:
2682: /* negotiate rates with new IBSS */
2683: ieee80211_fix_rate(ic, ni, IEEE80211_F_DOFRATE |
2684: IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2685: if (ni->ni_rates.rs_nrates == 0) {
2686: if (ieee80211_do_slow_print(ic, &did_print)) {
2687: printf("%s: rates mismatch, BSSID %s\n",
2688: ic->ic_if.if_xname, ether_sprintf(ni->ni_bssid));
2689: }
2690: return 0;
2691: }
2692:
2693: if (ieee80211_do_slow_print(ic, &did_print)) {
2694: printf("%s: sync BSSID %s -> ",
2695: ic->ic_if.if_xname, ether_sprintf(ic->ic_bss->ni_bssid));
2696: printf("%s ", ether_sprintf(ni->ni_bssid));
2697: printf("(from %s)\n", ether_sprintf(ni->ni_macaddr));
2698: }
2699:
2700: ieee80211_node_newstate(ni, IEEE80211_STA_BSS);
2701: (*ic->ic_node_copy)(ic, ic->ic_bss, ni);
2702:
2703: return ENETRESET;
2704: }
CVSweb