Annotation of sys/net80211/ieee80211_output.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ieee80211_output.c,v 1.55 2007/08/05 21:41:11 claudio Exp $ */
2: /* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */
3:
4: /*-
5: * Copyright (c) 2001 Atsushi Onoe
6: * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
7: * Copyright (c) 2007 Damien Bergamini
8: * All rights reserved.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31: */
32:
33: #include "bpfilter.h"
34: #include "vlan.h"
35:
36: #include <sys/param.h>
37: #include <sys/systm.h>
38: #include <sys/mbuf.h>
39: #include <sys/kernel.h>
40: #include <sys/socket.h>
41: #include <sys/sockio.h>
42: #include <sys/endian.h>
43: #include <sys/errno.h>
44: #include <sys/proc.h>
45: #include <sys/sysctl.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: #include <net/bpf.h>
53:
54: #ifdef INET
55: #include <netinet/in.h>
56: #include <netinet/if_ether.h>
57: #include <netinet/in_systm.h>
58: #include <netinet/ip.h>
59: #endif
60:
61: #if NVLAN > 0
62: #include <net/if_types.h>
63: #include <net/if_vlan_var.h>
64: #endif
65:
66: #include <net80211/ieee80211_var.h>
67:
68: #include <dev/rndvar.h>
69:
70: enum ieee80211_edca_ac ieee80211_up_to_ac(struct ieee80211com *, int);
71: int ieee80211_classify(struct ieee80211com *, struct mbuf *);
72: int ieee80211_mgmt_output(struct ifnet *, struct ieee80211_node *,
73: struct mbuf *, int);
74: u_int8_t *ieee80211_add_rsn_body(u_int8_t *, struct ieee80211com *,
75: const struct ieee80211_node *, int);
76: struct mbuf *ieee80211_getmbuf(int, int, u_int);
77: struct mbuf *ieee80211_get_probe_req(struct ieee80211com *,
78: struct ieee80211_node *);
79: struct mbuf *ieee80211_get_probe_resp(struct ieee80211com *,
80: struct ieee80211_node *);
81: struct mbuf *ieee80211_get_auth(struct ieee80211com *,
82: struct ieee80211_node *, u_int16_t, u_int16_t);
83: struct mbuf *ieee80211_get_deauth(struct ieee80211com *,
84: struct ieee80211_node *, u_int16_t);
85: struct mbuf *ieee80211_get_assoc_req(struct ieee80211com *,
86: struct ieee80211_node *, int);
87: struct mbuf *ieee80211_get_assoc_resp(struct ieee80211com *,
88: struct ieee80211_node *, u_int16_t);
89: struct mbuf *ieee80211_get_disassoc(struct ieee80211com *,
90: struct ieee80211_node *, u_int16_t);
91: int ieee80211_send_eapol_key(struct ieee80211com *, struct mbuf *,
92: struct ieee80211_node *);
93: u_int8_t *ieee80211_add_gtk_kde(u_int8_t *, const struct ieee80211_key *);
94: u_int8_t *ieee80211_add_pmkid_kde(u_int8_t *, const u_int8_t *);
95: struct mbuf *ieee80211_get_eapol_key(int, int, u_int);
96:
97:
98: /*
99: * IEEE 802.11 output routine. Normally this will directly call the
100: * Ethernet output routine because 802.11 encapsulation is called
101: * later by the driver. This function can be used to send raw frames
102: * if the mbuf has been tagged with a 802.11 data link type.
103: */
104: int
105: ieee80211_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
106: struct rtentry *rt)
107: {
108: u_int dlt = 0;
109: int s, error = 0;
110: struct m_tag *mtag;
111:
112: /* Interface has to be up and running */
113: if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
114: (IFF_UP | IFF_RUNNING)) {
115: error = ENETDOWN;
116: goto bad;
117: }
118:
119: /* Try to get the DLT from a mbuf tag */
120: if ((mtag = m_tag_find(m, PACKET_TAG_DLT, NULL)) != NULL) {
121: dlt = *(u_int *)(mtag + 1);
122:
123: /* Fallback to ethernet for non-802.11 linktypes */
124: if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
125: goto fallback;
126:
127: /*
128: * Queue message on interface without adding any
129: * further headers, and start output if interface not
130: * yet active.
131: */
132: s = splnet();
133: IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
134: if (error) {
135: /* mbuf is already freed */
136: splx(s);
137: printf("%s: failed to queue raw tx frame\n",
138: ifp->if_xname);
139: return (error);
140: }
141: ifp->if_obytes += m->m_pkthdr.len;
142: if (m->m_flags & M_MCAST)
143: ifp->if_omcasts++;
144: if ((ifp->if_flags & IFF_OACTIVE) == 0)
145: (*ifp->if_start)(ifp);
146: splx(s);
147:
148: return (error);
149: }
150:
151: fallback:
152: return (ether_output(ifp, m, dst, rt));
153:
154: bad:
155: if (m)
156: m_freem(m);
157: return (error);
158: }
159:
160: /*
161: * Send a management frame to the specified node. The node pointer
162: * must have a reference as the pointer will be passed to the driver
163: * and potentially held for a long time. If the frame is successfully
164: * dispatched to the driver, then it is responsible for freeing the
165: * reference (and potentially free'ing up any associated storage).
166: */
167: int
168: ieee80211_mgmt_output(struct ifnet *ifp, struct ieee80211_node *ni,
169: struct mbuf *m, int type)
170: {
171: struct ieee80211com *ic = (void *)ifp;
172: struct ieee80211_frame *wh;
173:
174: if (ni == NULL)
175: panic("null node");
176: ni->ni_inact = 0;
177:
178: /*
179: * Yech, hack alert! We want to pass the node down to the
180: * driver's start routine. We could stick this in an m_tag
181: * and tack that on to the mbuf. However that's rather
182: * expensive to do for every frame so instead we stuff it in
183: * the rcvif field since outbound frames do not (presently)
184: * use this.
185: */
186: M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
187: if (m == NULL)
188: return ENOMEM;
189: m->m_pkthdr.rcvif = (void *)ni;
190:
191: wh = mtod(m, struct ieee80211_frame *);
192: wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | type;
193: wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
194: *(u_int16_t *)&wh->i_dur[0] = 0;
195: *(u_int16_t *)&wh->i_seq[0] =
196: htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
197: ni->ni_txseq++;
198: IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
199: IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
200: IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
201:
202: if (ifp->if_flags & IFF_DEBUG) {
203: /* avoid to print too many frames */
204: if (ic->ic_opmode == IEEE80211_M_IBSS ||
205: #ifdef IEEE80211_DEBUG
206: ieee80211_debug > 1 ||
207: #endif
208: (type & IEEE80211_FC0_SUBTYPE_MASK) !=
209: IEEE80211_FC0_SUBTYPE_PROBE_RESP)
210: printf("%s: sending %s to %s on channel %u mode %s\n",
211: ifp->if_xname,
212: ieee80211_mgt_subtype_name[
213: (type & IEEE80211_FC0_SUBTYPE_MASK)
214: >> IEEE80211_FC0_SUBTYPE_SHIFT],
215: ether_sprintf(ni->ni_macaddr),
216: ieee80211_chan2ieee(ic, ni->ni_chan),
217: ieee80211_phymode_name[
218: ieee80211_chan2mode(ic, ni->ni_chan)]);
219: }
220:
221: IF_ENQUEUE(&ic->ic_mgtq, m);
222: ifp->if_timer = 1;
223: (*ifp->if_start)(ifp);
224: return 0;
225: }
226:
227: /*-
228: * EDCA tables are computed using the following formulas:
229: *
230: * 1) EDCATable (non-AP QSTA)
231: *
232: * AC CWmin CWmax AIFSN TXOP limit(ms)
233: * -------------------------------------------------------------
234: * AC_BK aCWmin aCWmax 7 0
235: * AC_BE aCWmin aCWmax 3 0
236: * AC_VI (aCWmin+1)/2-1 aCWmin 2 agn=3.008 b=6.016 others=0
237: * AC_VO (aCWmin+1)/4-1 (aCWmin+1)/2-1 2 agn=1.504 b=3.264 others=0
238: *
239: * 2) QAPEDCATable (QAP)
240: *
241: * AC CWmin CWmax AIFSN TXOP limit(ms)
242: * -------------------------------------------------------------
243: * AC_BK aCWmin aCWmax 7 0
244: * AC_BE aCWmin 4*(aCWmin+1)-1 3 0
245: * AC_VI (aCWmin+1)/2-1 aCWmin 1 agn=3.008 b=6.016 others=0
246: * AC_VO (aCWmin+1)/4-1 (aCWmin+1)/2-1 1 agn=1.504 b=3.264 others=0
247: *
248: * and the following aCWmin/aCWmax values:
249: *
250: * PHY aCWmin aCWmax
251: * ---------------------------
252: * 11A 15 1023
253: * 11B 31 1023
254: * 11G 15* 1023 (*) aCWmin(1)
255: * FH 15 1023
256: * Turbo A/G 7 1023 (Atheros proprietary mode)
257: */
258: static const struct ieee80211_edca_ac_params
259: ieee80211_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC] = {
260: [IEEE80211_MODE_FH] = {
261: [EDCA_AC_BK] = { 4, 10, 7, 0 },
262: [EDCA_AC_BE] = { 4, 10, 3, 0 },
263: [EDCA_AC_VI] = { 3, 4, 2, 0 },
264: [EDCA_AC_VO] = { 2, 3, 2, 0 }
265: },
266: [IEEE80211_MODE_11B] = {
267: [EDCA_AC_BK] = { 5, 10, 7, 0 },
268: [EDCA_AC_BE] = { 5, 10, 3, 0 },
269: [EDCA_AC_VI] = { 4, 5, 2, 188 },
270: [EDCA_AC_VO] = { 3, 4, 2, 102 }
271: },
272: [IEEE80211_MODE_11A] = {
273: [EDCA_AC_BK] = { 4, 10, 7, 0 },
274: [EDCA_AC_BE] = { 4, 10, 3, 0 },
275: [EDCA_AC_VI] = { 3, 4, 2, 94 },
276: [EDCA_AC_VO] = { 2, 3, 2, 47 }
277: },
278: [IEEE80211_MODE_11G] = {
279: [EDCA_AC_BK] = { 4, 10, 7, 0 },
280: [EDCA_AC_BE] = { 4, 10, 3, 0 },
281: [EDCA_AC_VI] = { 3, 4, 2, 94 },
282: [EDCA_AC_VO] = { 2, 3, 2, 47 }
283: },
284: [IEEE80211_MODE_TURBO] = {
285: [EDCA_AC_BK] = { 3, 10, 7, 0 },
286: [EDCA_AC_BE] = { 3, 10, 2, 0 },
287: [EDCA_AC_VI] = { 2, 3, 2, 94 },
288: [EDCA_AC_VO] = { 2, 2, 1, 47 }
289: }
290: };
291:
292: static const struct ieee80211_edca_ac_params
293: ieee80211_qap_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC] = {
294: [IEEE80211_MODE_FH] = {
295: [EDCA_AC_BK] = { 4, 10, 7, 0 },
296: [EDCA_AC_BE] = { 4, 6, 3, 0 },
297: [EDCA_AC_VI] = { 3, 4, 1, 0 },
298: [EDCA_AC_VO] = { 2, 3, 1, 0 }
299: },
300: [IEEE80211_MODE_11B] = {
301: [EDCA_AC_BK] = { 5, 10, 7, 0 },
302: [EDCA_AC_BE] = { 5, 7, 3, 0 },
303: [EDCA_AC_VI] = { 4, 5, 1, 188 },
304: [EDCA_AC_VO] = { 3, 4, 1, 102 }
305: },
306: [IEEE80211_MODE_11A] = {
307: [EDCA_AC_BK] = { 4, 10, 7, 0 },
308: [EDCA_AC_BE] = { 4, 6, 3, 0 },
309: [EDCA_AC_VI] = { 3, 4, 1, 94 },
310: [EDCA_AC_VO] = { 2, 3, 1, 47 }
311: },
312: [IEEE80211_MODE_11G] = {
313: [EDCA_AC_BK] = { 4, 10, 7, 0 },
314: [EDCA_AC_BE] = { 4, 6, 3, 0 },
315: [EDCA_AC_VI] = { 3, 4, 1, 94 },
316: [EDCA_AC_VO] = { 2, 3, 1, 47 }
317: },
318: [IEEE80211_MODE_TURBO] = {
319: [EDCA_AC_BK] = { 3, 10, 7, 0 },
320: [EDCA_AC_BE] = { 3, 5, 2, 0 },
321: [EDCA_AC_VI] = { 2, 3, 1, 94 },
322: [EDCA_AC_VO] = { 2, 2, 1, 47 }
323: }
324: };
325:
326: /*
327: * Return the EDCA Access Category to be used for transmitting a frame with
328: * user-priority `up'.
329: */
330: enum ieee80211_edca_ac
331: ieee80211_up_to_ac(struct ieee80211com *ic, int up)
332: {
333: /* IEEE Std 802.11e-2005, table 20i */
334: static const enum ieee80211_edca_ac up_to_ac[] = {
335: EDCA_AC_BE, /* BE */
336: EDCA_AC_BK, /* BK */
337: EDCA_AC_BK, /* -- */
338: EDCA_AC_BE, /* EE */
339: EDCA_AC_VI, /* CL */
340: EDCA_AC_VI, /* VI */
341: EDCA_AC_VO, /* VO */
342: EDCA_AC_VO /* NC */
343: };
344: enum ieee80211_edca_ac ac;
345:
346: ac = (up <= 7) ? up_to_ac[up] : EDCA_AC_BE;
347:
348: if (ic->ic_opmode == IEEE80211_M_HOSTAP)
349: return ac;
350:
351: /*
352: * We do not support the admission control procedure defined in
353: * IEEE Std 802.11e-2005 section 9.9.3.1.2. The spec says that
354: * non-AP QSTAs that don't support this procedure shall use EDCA
355: * parameters of a lower priority AC that does not require
356: * admission control.
357: */
358: while (ac != EDCA_AC_BK && ic->ic_edca_ac[ac].ac_acm) {
359: switch (ac) {
360: case EDCA_AC_BK:
361: /* can't get there */
362: break;
363: case EDCA_AC_BE:
364: /* BE shouldn't require admission control */
365: ac = EDCA_AC_BK;
366: break;
367: case EDCA_AC_VI:
368: ac = EDCA_AC_BE;
369: break;
370: case EDCA_AC_VO:
371: ac = EDCA_AC_VI;
372: break;
373: }
374: }
375: return ac;
376: }
377:
378: /*
379: * Get mbuf's user-priority: if mbuf is not VLAN tagged, select user-priority
380: * based on the DSCP (Differentiated Services Codepoint) field.
381: */
382: int
383: ieee80211_classify(struct ieee80211com *ic, struct mbuf *m)
384: {
385: #ifdef INET
386: const struct ether_header *eh;
387: #endif
388: #if NVLAN > 0
389: if ((m->m_flags & M_PROTO1) == M_PROTO1 && m->m_pkthdr.rcvif != NULL) {
390: const struct ifvlan *ifv = m->m_pkthdr.rcvif->if_softc;
391:
392: /* use VLAN 802.1D user-priority */
393: if (ifv->ifv_prio <= 7)
394: return ifv->ifv_prio;
395: }
396: #endif
397: #ifdef INET
398: eh = mtod(m, struct ether_header *);
399: if (eh->ether_type == htons(ETHERTYPE_IP)) {
400: const struct ip *ip = (const struct ip *)(eh + 1);
401: /*
402: * Map Differentiated Services Codepoint field (see RFC2474).
403: * Preserves backward compatibility with IP Precedence field.
404: */
405: switch (ip->ip_tos & 0xfc) {
406: case IPTOS_PREC_PRIORITY:
407: return 2;
408: case IPTOS_PREC_IMMEDIATE:
409: return 1;
410: case IPTOS_PREC_FLASH:
411: return 3;
412: case IPTOS_PREC_FLASHOVERRIDE:
413: return 4;
414: case IPTOS_PREC_CRITIC_ECP:
415: return 5;
416: case IPTOS_PREC_INTERNETCONTROL:
417: return 6;
418: case IPTOS_PREC_NETCONTROL:
419: return 7;
420: }
421: }
422: #endif
423: return 0; /* default to Best-Effort */
424: }
425:
426: /*
427: * Encapsulate an outbound data frame. The mbuf chain is updated and
428: * a reference to the destination node is returned. If an error is
429: * encountered NULL is returned and the node reference will also be NULL.
430: *
431: * NB: The caller is responsible for free'ing a returned node reference.
432: * The convention is ic_bss is not reference counted; the caller must
433: * maintain that.
434: */
435: struct mbuf *
436: ieee80211_encap(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node **pni)
437: {
438: struct ieee80211com *ic = (void *)ifp;
439: struct ether_header eh;
440: struct ieee80211_frame *wh;
441: struct ieee80211_node *ni = NULL;
442: struct llc *llc;
443: struct m_tag *mtag;
444: u_int8_t *addr;
445: u_int dlt, hdrlen;
446: int addqos, tid;
447:
448: /* Handle raw frames if mbuf is tagged as 802.11 */
449: if ((mtag = m_tag_find(m, PACKET_TAG_DLT, NULL)) != NULL) {
450: dlt = *(u_int *)(mtag + 1);
451:
452: if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
453: goto fallback;
454:
455: wh = mtod(m, struct ieee80211_frame *);
456:
457: if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min))
458: goto bad;
459:
460: if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
461: IEEE80211_FC0_VERSION_0)
462: goto bad;
463:
464: switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
465: case IEEE80211_FC1_DIR_NODS:
466: case IEEE80211_FC1_DIR_FROMDS:
467: addr = wh->i_addr1;
468: break;
469: case IEEE80211_FC1_DIR_DSTODS:
470: case IEEE80211_FC1_DIR_TODS:
471: addr = wh->i_addr3;
472: break;
473: default:
474: goto bad;
475: }
476:
477: ni = ieee80211_find_txnode(ic, addr);
478: if (ni == NULL)
479: ni = ieee80211_ref_node(ic->ic_bss);
480: if (ni == NULL) {
481: printf("%s: no node for dst %s, "
482: "discard raw tx frame\n", ifp->if_xname,
483: ether_sprintf(addr));
484: ic->ic_stats.is_tx_nonode++;
485: goto bad;
486: }
487: ni->ni_inact = 0;
488:
489: *pni = ni;
490: return (m);
491: }
492:
493: fallback:
494: if (m->m_len < sizeof(struct ether_header)) {
495: m = m_pullup(m, sizeof(struct ether_header));
496: if (m == NULL) {
497: ic->ic_stats.is_tx_nombuf++;
498: goto bad;
499: }
500: }
501: memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
502:
503: ni = ieee80211_find_txnode(ic, eh.ether_dhost);
504: if (ni == NULL) {
505: IEEE80211_DPRINTF(("%s: no node for dst %s, discard frame\n",
506: __func__, ether_sprintf(eh.ether_dhost)));
507: ic->ic_stats.is_tx_nonode++;
508: goto bad;
509: }
510: #if 0
511: if (!ni->ni_port_valid && eh.ether_type != htons(ETHERTYPE_PAE)) {
512: IEEE80211_DPRINTF(("%s: port not valid: %s\n",
513: __func__, ether_sprintf(eh.ether_dhost)));
514: ic->ic_stats.is_tx_noauth++;
515: goto bad;
516: }
517: #endif
518: ni->ni_inact = 0;
519:
520: if ((ic->ic_flags & IEEE80211_F_QOS) &&
521: (ni->ni_flags & IEEE80211_NODE_QOS) &&
522: /* do not QoS-encapsulate EAPOL frames */
523: eh.ether_type != htons(ETHERTYPE_PAE)) {
524: tid = ieee80211_classify(ic, m);
525: hdrlen = sizeof(struct ieee80211_qosframe);
526: addqos = 1;
527: } else {
528: hdrlen = sizeof(struct ieee80211_frame);
529: addqos = 0;
530: }
531: m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
532: llc = mtod(m, struct llc *);
533: llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
534: llc->llc_control = LLC_UI;
535: llc->llc_snap.org_code[0] = 0;
536: llc->llc_snap.org_code[1] = 0;
537: llc->llc_snap.org_code[2] = 0;
538: llc->llc_snap.ether_type = eh.ether_type;
539: M_PREPEND(m, hdrlen, M_DONTWAIT);
540: if (m == NULL) {
541: ic->ic_stats.is_tx_nombuf++;
542: goto bad;
543: }
544: wh = mtod(m, struct ieee80211_frame *);
545: wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
546: *(u_int16_t *)&wh->i_dur[0] = 0;
547: if (addqos) {
548: struct ieee80211_qosframe *qwh =
549: (struct ieee80211_qosframe *)wh;
550: qwh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
551: qwh->i_qos[0] = tid & IEEE80211_QOS_TID;
552: qwh->i_qos[1] = 0; /* no TXOP requested */
553: *(u_int16_t *)&qwh->i_seq[0] =
554: htole16(ni->ni_qos_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT);
555: ni->ni_qos_txseqs[tid]++;
556: } else {
557: *(u_int16_t *)&wh->i_seq[0] =
558: htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
559: ni->ni_txseq++;
560: }
561: switch (ic->ic_opmode) {
562: case IEEE80211_M_STA:
563: wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
564: IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid);
565: IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
566: IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
567: break;
568: case IEEE80211_M_IBSS:
569: case IEEE80211_M_AHDEMO:
570: wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
571: IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
572: IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
573: IEEE80211_ADDR_COPY(wh->i_addr3, ic->ic_bss->ni_bssid);
574: break;
575: case IEEE80211_M_HOSTAP:
576: wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
577: IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
578: IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
579: IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
580: break;
581: case IEEE80211_M_MONITOR:
582: goto bad;
583: }
584: if (ic->ic_flags & IEEE80211_F_WEPON)
585: wh->i_fc[1] |= IEEE80211_FC1_WEP;
586: *pni = ni;
587: return m;
588: bad:
589: if (m != NULL)
590: m_freem(m);
591: if (ni != NULL)
592: ieee80211_release_node(ic, ni);
593: *pni = NULL;
594: return NULL;
595: }
596:
597: /* unaligned little endian access */
598: #define LE_WRITE_2(p, v) do { \
599: ((u_int8_t *)(p))[0] = (v) & 0xff; \
600: ((u_int8_t *)(p))[1] = (v) >> 8; \
601: } while (0)
602:
603: /*
604: * Add a Capability Information field to a frame (see 7.3.1.4).
605: */
606: u_int8_t *
607: ieee80211_add_capinfo(u_int8_t *frm, struct ieee80211com *ic,
608: const struct ieee80211_node *ni)
609: {
610: u_int16_t capinfo;
611:
612: if (ic->ic_opmode == IEEE80211_M_IBSS)
613: capinfo = IEEE80211_CAPINFO_IBSS;
614: else if (ic->ic_opmode == IEEE80211_M_HOSTAP)
615: capinfo = IEEE80211_CAPINFO_ESS;
616: else
617: capinfo = 0;
618: if (ic->ic_flags & IEEE80211_F_WEPON)
619: capinfo |= IEEE80211_CAPINFO_PRIVACY;
620: /* NB: some 11a AP's reject the request when short preamble is set */
621: if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
622: IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
623: capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
624: if (ic->ic_flags & IEEE80211_F_SHSLOT)
625: capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
626: LE_WRITE_2(frm, capinfo);
627: return frm + 2;
628: }
629:
630: /*
631: * Add an SSID element to a frame (see 7.3.2.1).
632: */
633: u_int8_t *
634: ieee80211_add_ssid(u_int8_t *frm, const u_int8_t *ssid, u_int len)
635: {
636: *frm++ = IEEE80211_ELEMID_SSID;
637: *frm++ = len;
638: memcpy(frm, ssid, len);
639: return frm + len;
640: }
641:
642: /*
643: * Add a supported rates element to a frame (see 7.3.2.2).
644: */
645: u_int8_t *
646: ieee80211_add_rates(u_int8_t *frm, const struct ieee80211_rateset *rs)
647: {
648: int nrates;
649:
650: *frm++ = IEEE80211_ELEMID_RATES;
651: nrates = min(rs->rs_nrates, IEEE80211_RATE_SIZE);
652: *frm++ = nrates;
653: memcpy(frm, rs->rs_rates, nrates);
654: return frm + nrates;
655: }
656:
657: /*
658: * Add a FH Parameter Set element to a frame (see 7.3.2.3).
659: */
660: u_int8_t *
661: ieee80211_add_fh_params(u_int8_t *frm, struct ieee80211com *ic,
662: const struct ieee80211_node *ni)
663: {
664: u_int chan = ieee80211_chan2ieee(ic, ni->ni_chan);
665:
666: *frm++ = IEEE80211_ELEMID_FHPARMS;
667: *frm++ = 5;
668: LE_WRITE_2(frm, ni->ni_fhdwell); frm += 2;
669: *frm++ = IEEE80211_FH_CHANSET(chan);
670: *frm++ = IEEE80211_FH_CHANPAT(chan);
671: *frm++ = ni->ni_fhindex;
672: return frm;
673: }
674:
675: /*
676: * Add a DS Parameter Set element to a frame (see 7.3.2.4).
677: */
678: u_int8_t *
679: ieee80211_add_ds_params(u_int8_t *frm, struct ieee80211com *ic,
680: const struct ieee80211_node *ni)
681: {
682: *frm++ = IEEE80211_ELEMID_DSPARMS;
683: *frm++ = 1;
684: *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
685: return frm;
686: }
687:
688: /*
689: * Add a TIM element to a frame (see 7.3.2.6 and Annex L).
690: */
691: u_int8_t *
692: ieee80211_add_tim(u_int8_t *frm, struct ieee80211com *ic)
693: {
694: u_int i, offset = 0, len;
695:
696: /* find first non-zero octet in the virtual bit map */
697: for (i = 0; i < ic->ic_tim_len && ic->ic_tim_bitmap[i] == 0; i++);
698:
699: /* clear the lsb as it is reserved for the broadcast indication bit */
700: if (i < ic->ic_tim_len)
701: offset = i & ~1;
702:
703: /* find last non-zero octet in the virtual bit map */
704: for (i = ic->ic_tim_len - 1; i > 0 && ic->ic_tim_bitmap[i] == 0; i--);
705:
706: len = i - offset + 1;
707:
708: *frm++ = IEEE80211_ELEMID_TIM;
709: *frm++ = len + 3; /* length */
710: *frm++ = ic->ic_dtim_count; /* DTIM count */
711: *frm++ = ic->ic_dtim_period; /* DTIM period */
712:
713: /* Bitmap Control */
714: *frm = offset;
715: /* set broadcast/multicast indication bit if necessary */
716: if (ic->ic_dtim_count == 0 && ic->ic_tim_mcast)
717: *frm |= 0x01;
718: frm++;
719:
720: /* Partial Virtual Bitmap */
721: memcpy(frm, &ic->ic_tim_bitmap[offset], len);
722: return frm + len;
723: }
724:
725: /*
726: * Add an IBSS Parameter Set element to a frame (see 7.3.2.7).
727: */
728: u_int8_t *
729: ieee80211_add_ibss_params(u_int8_t *frm, const struct ieee80211_node *ni)
730: {
731: *frm++ = IEEE80211_ELEMID_IBSSPARMS;
732: *frm++ = 2;
733: LE_WRITE_2(frm, 0); /* TODO: ATIM window */
734: return frm + 2;
735: }
736:
737: /*
738: * Add an EDCA Parameter Set element to a frame (see 7.3.2.29).
739: */
740: u_int8_t *
741: ieee80211_add_edca_params(u_int8_t *frm, struct ieee80211com *ic)
742: {
743: const struct ieee80211_edca_ac_params *edca;
744: int aci;
745:
746: *frm++ = IEEE80211_ELEMID_EDCAPARMS;
747: *frm++ = 18; /* length */
748: *frm++ = 0; /* QoS Info */
749: *frm++ = 0; /* reserved */
750:
751: /* setup AC Parameter Records */
752: edca = ieee80211_qap_edca_table[ic->ic_curmode];
753: for (aci = 0; aci < EDCA_NUM_AC; aci++) {
754: const struct ieee80211_edca_ac_params *ac = &edca[aci];
755:
756: *frm++ = (aci << 5) | ((ac->ac_acm & 0x1) << 4) |
757: (ac->ac_aifsn & 0xf);
758: *frm++ = (ac->ac_ecwmax << 4) |
759: (ac->ac_ecwmin & 0xf);
760: LE_WRITE_2(frm, ac->ac_txoplimit); frm += 2;
761: }
762: return frm;
763: }
764:
765: /*
766: * Add an ERP element to a frame (see 7.3.2.13).
767: */
768: u_int8_t *
769: ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic)
770: {
771: u_int8_t erp;
772:
773: *frm++ = IEEE80211_ELEMID_ERP;
774: *frm++ = 1;
775: erp = 0;
776: /*
777: * The NonERP_Present bit shall be set to 1 when a NonERP STA
778: * is associated with the BSS.
779: */
780: if (ic->ic_nonerpsta != 0)
781: erp |= IEEE80211_ERP_NON_ERP_PRESENT;
782: /*
783: * If one or more NonERP STAs are associated in the BSS, the
784: * Use_Protection bit shall be set to 1 in transmitted ERP
785: * Information Elements.
786: */
787: if (ic->ic_flags & IEEE80211_F_USEPROT)
788: erp |= IEEE80211_ERP_USE_PROTECTION;
789: /*
790: * The Barker_Preamble_Mode bit shall be set to 1 by the ERP
791: * Information Element sender if one or more associated NonERP
792: * STAs are not short preamble capable.
793: */
794: if (!(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
795: erp |= IEEE80211_ERP_BARKER_MODE;
796: *frm++ = erp;
797: return frm;
798: }
799:
800: /*
801: * Add a QoS Capability element to a frame (see 7.3.2.35).
802: */
803: u_int8_t *
804: ieee80211_add_qos_capability(u_int8_t *frm, struct ieee80211com *ic)
805: {
806: *frm++ = IEEE80211_ELEMID_QOS_CAP;
807: *frm++ = 1;
808: *frm++ = 0; /* QoS Info */
809: return frm;
810: }
811:
812: /*
813: * Add an RSN element to a frame (see 7.3.2.25).
814: */
815: u_int8_t *
816: ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211com *ic,
817: const struct ieee80211_node *ni, int wpa1)
818: {
819: const u_int8_t *oui = wpa1 ? MICROSOFT_OUI : IEEE80211_OUI;
820: u_int8_t *pcount;
821: u_int16_t count;
822:
823: /* write Version field */
824: LE_WRITE_2(frm, 1); frm += 2;
825:
826: /* write Group Cipher Suite field (see Table 20da) */
827: memcpy(frm, oui, 3); frm += 3;
828: switch (ni->ni_group_cipher) {
829: case IEEE80211_CIPHER_USEGROUP:
830: /* can't get there */
831: panic("invalid group cipher!");
832: break;
833: case IEEE80211_CIPHER_WEP40:
834: *frm++ = 1;
835: break;
836: case IEEE80211_CIPHER_TKIP:
837: *frm++ = 2;
838: break;
839: case IEEE80211_CIPHER_CCMP:
840: *frm++ = 4;
841: break;
842: case IEEE80211_CIPHER_WEP104:
843: *frm++ = 5;
844: break;
845: }
846:
847: pcount = frm; frm += 2;
848: count = 0;
849: /* write Pairwise Cipher Suite List */
850: if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_USEGROUP) {
851: memcpy(frm, oui, 3); frm += 3;
852: *frm++ = 0;
853: count++;
854: }
855: if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_TKIP) {
856: memcpy(frm, oui, 3); frm += 3;
857: *frm++ = 2;
858: count++;
859: }
860: if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_CCMP) {
861: memcpy(frm, oui, 3); frm += 3;
862: *frm++ = 4;
863: count++;
864: }
865: /* write Pairwise Cipher Suite Count field */
866: LE_WRITE_2(pcount, count);
867:
868: pcount = frm; frm += 2;
869: count = 0;
870: /* write AKM Suite List (see Table 20dc) */
871: if (ni->ni_akmset & IEEE80211_AKM_IEEE8021X) {
872: memcpy(frm, oui, 3); frm += 3;
873: *frm++ = 1;
874: count++;
875: }
876: if (ni->ni_akmset & IEEE80211_AKM_PSK) {
877: memcpy(frm, oui, 3); frm += 3;
878: *frm++ = 2;
879: count++;
880: }
881: /* write AKM Suite List Count field */
882: LE_WRITE_2(pcount, count);
883:
884: /* write RSN Capabilities field */
885: LE_WRITE_2(frm, ni->ni_rsncaps); frm += 2;
886:
887: /* no PMKID List for now */
888:
889: return frm;
890: }
891:
892: u_int8_t *
893: ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
894: const struct ieee80211_node *ni)
895: {
896: u_int8_t *plen;
897:
898: *frm++ = IEEE80211_ELEMID_RSN;
899: plen = frm++; /* length filled in later */
900: frm = ieee80211_add_rsn_body(frm, ic, ni, 0);
901:
902: /* write length field */
903: *plen = frm - plen - 1;
904: return frm;
905: }
906:
907: /*
908: * Add a vendor specific WPA1 element to a frame.
909: * This is required for compatibility with Wi-Fi Alliance WPA1/WPA1+WPA2.
910: */
911: u_int8_t *
912: ieee80211_add_wpa1(u_int8_t *frm, struct ieee80211com *ic,
913: const struct ieee80211_node *ni)
914: {
915: u_int8_t *plen;
916:
917: *frm++ = IEEE80211_ELEMID_VENDOR;
918: plen = frm++; /* length filled in later */
919: memcpy(frm, MICROSOFT_OUI, 3); frm += 3;
920: *frm++ = 1; /* WPA1 */
921: frm = ieee80211_add_rsn_body(frm, ic, ni, 1);
922:
923: /* write length field */
924: *plen = frm - plen - 1;
925: return frm;
926: }
927:
928: /*
929: * Add an extended supported rates element to a frame (see 7.3.2.14).
930: */
931: u_int8_t *
932: ieee80211_add_xrates(u_int8_t *frm, const struct ieee80211_rateset *rs)
933: {
934: int nrates;
935:
936: KASSERT(rs->rs_nrates > IEEE80211_RATE_SIZE);
937:
938: *frm++ = IEEE80211_ELEMID_XRATES;
939: nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
940: *frm++ = nrates;
941: memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
942: return frm + nrates;
943: }
944:
945: struct mbuf *
946: ieee80211_getmbuf(int flags, int type, u_int pktlen)
947: {
948: struct mbuf *m;
949:
950: /* account for 802.11 header */
951: pktlen += sizeof(struct ieee80211_frame);
952:
953: if (pktlen > MCLBYTES)
954: panic("802.11 packet too large: %u", pktlen);
955: MGETHDR(m, flags, type);
956: if (m != NULL && pktlen > MHLEN) {
957: MCLGET(m, flags);
958: if (!(m->m_flags & M_EXT))
959: m = m_free(m);
960: }
961: return m;
962: }
963:
964: /*-
965: * Probe request frame format:
966: * [tlv] SSID
967: * [tlv] Supported rates
968: * [tlv] Extended Supported Rates (802.11g)
969: */
970: struct mbuf *
971: ieee80211_get_probe_req(struct ieee80211com *ic, struct ieee80211_node *ni)
972: {
973: const struct ieee80211_rateset *rs =
974: &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
975: struct mbuf *m;
976: u_int8_t *frm;
977:
978: m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
979: 2 + ic->ic_des_esslen +
980: 2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
981: ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
982: 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0));
983: if (m == NULL)
984: return NULL;
985:
986: m->m_data += sizeof(struct ieee80211_frame);
987:
988: frm = mtod(m, u_int8_t *);
989: frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen);
990: frm = ieee80211_add_rates(frm, rs);
991: if (rs->rs_nrates > IEEE80211_RATE_SIZE)
992: frm = ieee80211_add_xrates(frm, rs);
993:
994: m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
995:
996: return m;
997: }
998:
999: /*-
1000: * Probe response frame format:
1001: * [8] Timestamp
1002: * [2] Beacon interval
1003: * [2] Capability
1004: * [tlv] Service Set Identifier (SSID)
1005: * [tlv] Supported rates
1006: * [tlv*] Frequency-Hopping (FH) Parameter Set
1007: * [tlv*] DS Parameter Set (802.11g)
1008: * [tlv] ERP Information (802.11g)
1009: * [tlv] Extended Supported Rates (802.11g)
1010: * [tlv] RSN (802.11i)
1011: * [tlv] EDCA Parameter Set (802.11e)
1012: */
1013: struct mbuf *
1014: ieee80211_get_probe_resp(struct ieee80211com *ic, struct ieee80211_node *ni)
1015: {
1016: const struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates;
1017: struct mbuf *m;
1018: u_int8_t *frm;
1019:
1020: m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
1021: 8 + 2 + 2 +
1022: 2 + ni->ni_esslen +
1023: 2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
1024: 2 + ((ic->ic_phytype == IEEE80211_T_FH) ? 5 : 1) +
1025: ((ic->ic_opmode == IEEE80211_M_IBSS) ? 2 + 2 : 0) +
1026: ((ic->ic_curmode == IEEE80211_MODE_11G) ? 2 + 1 : 0) +
1027: ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
1028: 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
1029: ((ic->ic_flags & IEEE80211_F_RSN) ? 2 + 44 : 0) +
1030: ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0) +
1031: ((ic->ic_flags & IEEE80211_F_WPA1) ? 2 + 48 : 0));
1032: if (m == NULL)
1033: return NULL;
1034:
1035: m->m_data += sizeof(struct ieee80211_frame);
1036:
1037: frm = mtod(m, u_int8_t *);
1038: memset(frm, 0, 8); frm += 8; /* timestamp is set by hardware */
1039: LE_WRITE_2(frm, ic->ic_bss->ni_intval); frm += 2;
1040: frm = ieee80211_add_capinfo(frm, ic, ni);
1041: frm = ieee80211_add_ssid(frm, ic->ic_bss->ni_essid,
1042: ic->ic_bss->ni_esslen);
1043: frm = ieee80211_add_rates(frm, rs);
1044: if (ic->ic_phytype == IEEE80211_T_FH)
1045: frm = ieee80211_add_fh_params(frm, ic, ni);
1046: else
1047: frm = ieee80211_add_ds_params(frm, ic, ni);
1048: if (ic->ic_opmode == IEEE80211_M_IBSS)
1049: frm = ieee80211_add_ibss_params(frm, ni);
1050: if (ic->ic_curmode == IEEE80211_MODE_11G)
1051: frm = ieee80211_add_erp(frm, ic);
1052: if (rs->rs_nrates > IEEE80211_RATE_SIZE)
1053: frm = ieee80211_add_xrates(frm, rs);
1054: if (ic->ic_flags & IEEE80211_F_RSN)
1055: frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
1056: if (ic->ic_flags & IEEE80211_F_QOS)
1057: frm = ieee80211_add_edca_params(frm, ic);
1058: if (ic->ic_flags & IEEE80211_F_WPA1)
1059: frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
1060:
1061: m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
1062:
1063: return m;
1064: }
1065:
1066: /*-
1067: * Authentication frame format:
1068: * [2] Authentication algorithm number
1069: * [2] Authentication transaction sequence number
1070: * [2] Status code
1071: */
1072: struct mbuf *
1073: ieee80211_get_auth(struct ieee80211com *ic, struct ieee80211_node *ni,
1074: u_int16_t status, u_int16_t seq)
1075: {
1076: struct mbuf *m;
1077: u_int8_t *frm;
1078:
1079: MGETHDR(m, M_DONTWAIT, MT_DATA);
1080: if (m == NULL)
1081: return NULL;
1082: MH_ALIGN(m, 2 * 3);
1083: m->m_pkthdr.len = m->m_len = 2 * 3;
1084:
1085: frm = mtod(m, u_int8_t *);
1086: LE_WRITE_2(frm, IEEE80211_AUTH_ALG_OPEN); frm += 2;
1087: LE_WRITE_2(frm, seq); frm += 2;
1088: LE_WRITE_2(frm, status);
1089:
1090: return m;
1091: }
1092:
1093: /*-
1094: * Deauthentication frame format:
1095: * [2] Reason code
1096: */
1097: struct mbuf *
1098: ieee80211_get_deauth(struct ieee80211com *ic, struct ieee80211_node *ni,
1099: u_int16_t reason)
1100: {
1101: struct mbuf *m;
1102:
1103: MGETHDR(m, M_DONTWAIT, MT_DATA);
1104: if (m == NULL)
1105: return NULL;
1106: MH_ALIGN(m, 2);
1107:
1108: m->m_pkthdr.len = m->m_len = 2;
1109: *mtod(m, u_int16_t *) = htole16(reason);
1110:
1111: return m;
1112: }
1113:
1114: /*-
1115: * (Re)Association request frame format:
1116: * [2] Capability information
1117: * [2] Listen interval
1118: * [6*] Current AP address (Reassociation only)
1119: * [tlv] SSID
1120: * [tlv] Supported rates
1121: * [tlv] Extended Supported Rates (802.11g)
1122: * [tlv] RSN (802.11i)
1123: * [tlv] QoS Capability (802.11e)
1124: */
1125: struct mbuf *
1126: ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni,
1127: int reassoc)
1128: {
1129: const struct ieee80211_rateset *rs = &ni->ni_rates;
1130: struct mbuf *m;
1131: u_int8_t *frm;
1132: u_int16_t capinfo;
1133:
1134: m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
1135: 2 + 2 +
1136: ((reassoc == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) ?
1137: IEEE80211_ADDR_LEN : 0) +
1138: 2 + ni->ni_esslen +
1139: 2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
1140: ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
1141: 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
1142: ((ic->ic_flags & IEEE80211_F_RSN) ? 2 + 44 : 0) +
1143: ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 1 : 0) +
1144: ((ic->ic_flags & IEEE80211_F_WPA1) ? 2 + 48 : 0));
1145: if (m == NULL)
1146: return NULL;
1147:
1148: m->m_data += sizeof(struct ieee80211_frame);
1149:
1150: frm = mtod(m, u_int8_t *);
1151: capinfo = IEEE80211_CAPINFO_ESS;
1152: if (ic->ic_flags & IEEE80211_F_WEPON)
1153: capinfo |= IEEE80211_CAPINFO_PRIVACY;
1154: if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1155: IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
1156: capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
1157: if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) &&
1158: (ic->ic_flags & IEEE80211_F_SHSLOT))
1159: capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
1160: LE_WRITE_2(frm, capinfo); frm += 2;
1161: LE_WRITE_2(frm, ic->ic_lintval); frm += 2;
1162: if (reassoc == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
1163: IEEE80211_ADDR_COPY(frm, ic->ic_bss->ni_bssid);
1164: frm += IEEE80211_ADDR_LEN;
1165: }
1166: frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
1167: frm = ieee80211_add_rates(frm, rs);
1168: if (rs->rs_nrates > IEEE80211_RATE_SIZE)
1169: frm = ieee80211_add_xrates(frm, rs);
1170: if (ic->ic_flags & IEEE80211_F_RSN)
1171: frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
1172: if ((ic->ic_flags & IEEE80211_F_QOS) &&
1173: (ni->ni_flags & IEEE80211_NODE_QOS))
1174: frm = ieee80211_add_qos_capability(frm, ic);
1175: if (ic->ic_flags & IEEE80211_F_WPA1)
1176: frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
1177:
1178: m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
1179:
1180: return m;
1181: }
1182:
1183: /*-
1184: * (Re)Association response frame format:
1185: * [2] Capability information
1186: * [2] Status code
1187: * [2] Association ID (AID)
1188: * [tlv] Supported rates
1189: * [tlv] Extended Supported Rates (802.11g)
1190: * [tlv] EDCA Parameter Set (802.11e)
1191: */
1192: struct mbuf *
1193: ieee80211_get_assoc_resp(struct ieee80211com *ic, struct ieee80211_node *ni,
1194: u_int16_t status)
1195: {
1196: const struct ieee80211_rateset *rs = &ni->ni_rates;
1197: struct mbuf *m;
1198: u_int8_t *frm;
1199:
1200: m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
1201: 2 + 2 + 2 +
1202: 2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
1203: ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
1204: 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
1205: ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0));
1206: if (m == NULL)
1207: return NULL;
1208:
1209: m->m_data += sizeof(struct ieee80211_frame);
1210:
1211: frm = mtod(m, u_int8_t *);
1212: frm = ieee80211_add_capinfo(frm, ic, ni);
1213: LE_WRITE_2(frm, status); frm += 2;
1214: if (status == IEEE80211_STATUS_SUCCESS)
1215: LE_WRITE_2(frm, ni->ni_associd);
1216: else
1217: LE_WRITE_2(frm, 0);
1218: frm += 2;
1219: frm = ieee80211_add_rates(frm, rs);
1220: if (rs->rs_nrates > IEEE80211_RATE_SIZE)
1221: frm = ieee80211_add_xrates(frm, rs);
1222: if ((ic->ic_flags & IEEE80211_F_QOS) &&
1223: (ni->ni_flags & IEEE80211_NODE_QOS))
1224: frm = ieee80211_add_edca_params(frm, ic);
1225:
1226: m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
1227:
1228: return m;
1229: }
1230:
1231: /*-
1232: * Disassociation frame format:
1233: * [2] Reason code
1234: */
1235: struct mbuf *
1236: ieee80211_get_disassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
1237: u_int16_t reason)
1238: {
1239: struct mbuf *m;
1240:
1241: MGETHDR(m, M_DONTWAIT, MT_DATA);
1242: if (m == NULL)
1243: return NULL;
1244: MH_ALIGN(m, 2);
1245:
1246: m->m_pkthdr.len = m->m_len = 2;
1247: *mtod(m, u_int16_t *) = htole16(reason);
1248:
1249: return m;
1250: }
1251:
1252: /*
1253: * Send a management frame. The node is for the destination (or ic_bss
1254: * when in station mode). Nodes other than ic_bss have their reference
1255: * count bumped to reflect our use for an indeterminant time.
1256: */
1257: int
1258: ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
1259: int type, int arg)
1260: {
1261: #define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
1262: struct ifnet *ifp = &ic->ic_if;
1263: struct mbuf *m;
1264: int ret, timer;
1265:
1266: if (ni == NULL)
1267: panic("null node");
1268:
1269: /*
1270: * Hold a reference on the node so it doesn't go away until after
1271: * the xmit is complete all the way in the driver. On error we
1272: * will remove our reference.
1273: */
1274: ieee80211_ref_node(ni);
1275: timer = 0;
1276: switch (type) {
1277: case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
1278: if ((m = ieee80211_get_probe_req(ic, ni)) == NULL)
1279: senderr(ENOMEM, is_tx_nombuf);
1280:
1281: timer = IEEE80211_TRANS_WAIT;
1282: break;
1283:
1284: case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1285: if ((m = ieee80211_get_probe_resp(ic, ni)) == NULL)
1286: senderr(ENOMEM, is_tx_nombuf);
1287: break;
1288:
1289: case IEEE80211_FC0_SUBTYPE_AUTH:
1290: m = ieee80211_get_auth(ic, ni, arg >> 16, arg & 0xffff);
1291: if (m == NULL)
1292: senderr(ENOMEM, is_tx_nombuf);
1293:
1294: if (ic->ic_opmode == IEEE80211_M_STA)
1295: timer = IEEE80211_TRANS_WAIT;
1296: break;
1297:
1298: case IEEE80211_FC0_SUBTYPE_DEAUTH:
1299: if ((m = ieee80211_get_deauth(ic, ni, arg)) == NULL)
1300: senderr(ENOMEM, is_tx_nombuf);
1301:
1302: if (ifp->if_flags & IFF_DEBUG) {
1303: printf("%s: station %s deauthenticate (reason %d)\n",
1304: ifp->if_xname, ether_sprintf(ni->ni_macaddr), arg);
1305: }
1306: break;
1307:
1308: case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1309: case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
1310: if ((m = ieee80211_get_assoc_req(ic, ni, type)) == NULL)
1311: senderr(ENOMEM, is_tx_nombuf);
1312:
1313: timer = IEEE80211_TRANS_WAIT;
1314: break;
1315:
1316: case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
1317: case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
1318: if ((m = ieee80211_get_assoc_resp(ic, ni, arg)) == NULL)
1319: senderr(ENOMEM, is_tx_nombuf);
1320: break;
1321:
1322: case IEEE80211_FC0_SUBTYPE_DISASSOC:
1323: if ((m = ieee80211_get_disassoc(ic, ni, arg)) == NULL)
1324: senderr(ENOMEM, is_tx_nombuf);
1325:
1326: if (ifp->if_flags & IFF_DEBUG) {
1327: printf("%s: station %s disassociate (reason %d)\n",
1328: ifp->if_xname, ether_sprintf(ni->ni_macaddr), arg);
1329: }
1330: break;
1331:
1332: default:
1333: IEEE80211_DPRINTF(("%s: invalid mgmt frame type %u\n",
1334: __func__, type));
1335: senderr(EINVAL, is_tx_unknownmgt);
1336: /* NOTREACHED */
1337: }
1338:
1339: ret = ieee80211_mgmt_output(ifp, ni, m, type);
1340: if (ret == 0) {
1341: if (timer)
1342: ic->ic_mgt_timer = timer;
1343: } else {
1344: bad:
1345: ieee80211_release_node(ic, ni);
1346: }
1347: return ret;
1348: #undef senderr
1349: }
1350:
1351: /*
1352: * Build a RTS (Request To Send) control frame (see 7.2.1.1).
1353: */
1354: struct mbuf *
1355: ieee80211_get_rts(struct ieee80211com *ic, const struct ieee80211_frame *wh,
1356: u_int16_t dur)
1357: {
1358: struct ieee80211_frame_rts *rts;
1359: struct mbuf *m;
1360:
1361: MGETHDR(m, M_DONTWAIT, MT_DATA);
1362: if (m == NULL)
1363: return NULL;
1364:
1365: m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts);
1366:
1367: rts = mtod(m, struct ieee80211_frame_rts *);
1368: rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
1369: IEEE80211_FC0_SUBTYPE_RTS;
1370: rts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
1371: *(u_int16_t *)rts->i_dur = htole16(dur);
1372: IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1);
1373: IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2);
1374:
1375: return m;
1376: }
1377:
1378: /*
1379: * Build a CTS-to-self (Clear To Send) control frame (see 7.2.1.2).
1380: */
1381: struct mbuf *
1382: ieee80211_get_cts_to_self(struct ieee80211com *ic, u_int16_t dur)
1383: {
1384: struct ieee80211_frame_cts *cts;
1385: struct mbuf *m;
1386:
1387: MGETHDR(m, M_DONTWAIT, MT_DATA);
1388: if (m == NULL)
1389: return NULL;
1390:
1391: m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_cts);
1392:
1393: cts = mtod(m, struct ieee80211_frame_cts *);
1394: cts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
1395: IEEE80211_FC0_SUBTYPE_CTS;
1396: cts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
1397: *(u_int16_t *)cts->i_dur = htole16(dur);
1398: IEEE80211_ADDR_COPY(cts->i_ra, ic->ic_myaddr);
1399:
1400: return m;
1401: }
1402:
1403: /*-
1404: * Beacon frame format:
1405: * [8] Timestamp
1406: * [2] Beacon interval
1407: * [2] Capability
1408: * [tlv] Service Set Identifier (SSID)
1409: * [tlv] Supported rates
1410: * [tlv*] Frequency-Hopping (FH) Parameter Set
1411: * [tlv*] DS Parameter Set (802.11g)
1412: * [tlv*] IBSS Parameter Set
1413: * [tlv] Traffic Indication Map (TIM)
1414: * [tlv] ERP Information (802.11g)
1415: * [tlv] Extended Supported Rates (802.11g)
1416: * [tlv] RSN (802.11i)
1417: * [tlv] EDCA Parameter Set (802.11e)
1418: */
1419: struct mbuf *
1420: ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni)
1421: {
1422: const struct ieee80211_rateset *rs = &ni->ni_rates;
1423: struct ieee80211_frame *wh;
1424: struct mbuf *m;
1425: u_int8_t *frm;
1426:
1427: m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
1428: 8 + 2 + 2 +
1429: 2 + ((ic->ic_flags & IEEE80211_F_HIDENWID) ? 0 : ni->ni_esslen) +
1430: 2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
1431: 2 + ((ic->ic_phytype == IEEE80211_T_FH) ? 5 : 1) +
1432: 2 + ((ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 254) +
1433: ((ic->ic_curmode == IEEE80211_MODE_11G) ? 2 + 1 : 0) +
1434: ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
1435: 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
1436: ((ic->ic_flags & IEEE80211_F_RSN) ? 2 + 44 : 0) +
1437: ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0) +
1438: ((ic->ic_flags & IEEE80211_F_WPA1) ? 2 + 48 : 0));
1439: if (m == NULL)
1440: return NULL;
1441:
1442: wh = mtod(m, struct ieee80211_frame *);
1443: wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
1444: IEEE80211_FC0_SUBTYPE_BEACON;
1445: wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
1446: *(u_int16_t *)wh->i_dur = 0;
1447: IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
1448: IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
1449: IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
1450: *(u_int16_t *)wh->i_seq = 0;
1451:
1452: frm = (u_int8_t *)&wh[1];
1453: memset(frm, 0, 8); frm += 8; /* timestamp is set by hardware */
1454: LE_WRITE_2(frm, ni->ni_intval); frm += 2;
1455: frm = ieee80211_add_capinfo(frm, ic, ni);
1456: if (ic->ic_flags & IEEE80211_F_HIDENWID)
1457: frm = ieee80211_add_ssid(frm, NULL, 0);
1458: else
1459: frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
1460: frm = ieee80211_add_rates(frm, rs);
1461: if (ic->ic_phytype == IEEE80211_T_FH)
1462: frm = ieee80211_add_fh_params(frm, ic, ni);
1463: else
1464: frm = ieee80211_add_ds_params(frm, ic, ni);
1465: if (ic->ic_opmode == IEEE80211_M_IBSS)
1466: frm = ieee80211_add_ibss_params(frm, ni);
1467: else
1468: frm = ieee80211_add_tim(frm, ic);
1469: if (ic->ic_curmode == IEEE80211_MODE_11G)
1470: frm = ieee80211_add_erp(frm, ic);
1471: if (rs->rs_nrates > IEEE80211_RATE_SIZE)
1472: frm = ieee80211_add_xrates(frm, rs);
1473: if (ic->ic_flags & IEEE80211_F_RSN)
1474: frm = ieee80211_add_rsn(frm, ic, ni);
1475: if (ic->ic_flags & IEEE80211_F_QOS)
1476: frm = ieee80211_add_edca_params(frm, ic);
1477: if (ic->ic_flags & IEEE80211_F_WPA1)
1478: frm = ieee80211_add_wpa1(frm, ic, ni);
1479:
1480: m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
1481: m->m_pkthdr.rcvif = (void *)ni;
1482:
1483: return m;
1484: }
1485:
1486: /* unaligned big endian access */
1487: #define BE_READ_2(p) \
1488: ((u_int16_t)(p)[0] << 8 | (u_int16_t)(p)[1])
1489:
1490: #define BE_WRITE_2(p, v) do { \
1491: (p)[0] = (v) >> 8; (p)[1] = (v); \
1492: } while (0)
1493:
1494: #define BE_WRITE_8(p, v) do { \
1495: (p)[0] = (v) >> 56; (p)[1] = (v) >> 48; \
1496: (p)[2] = (v) >> 40; (p)[3] = (v) >> 32; \
1497: (p)[4] = (v) >> 24; (p)[5] = (v) >> 16; \
1498: (p)[6] = (v) >> 8; (p)[7] = (v); \
1499: } while (0)
1500:
1501: /* unaligned little endian access */
1502: #define LE_WRITE_8(p, v) do { \
1503: (p)[7] = (v) >> 56; (p)[6] = (v) >> 48; \
1504: (p)[5] = (v) >> 40; (p)[4] = (v) >> 32; \
1505: (p)[3] = (v) >> 24; (p)[2] = (v) >> 16; \
1506: (p)[1] = (v) >> 8; (p)[0] = (v); \
1507: } while (0)
1508:
1509: int
1510: ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
1511: struct ieee80211_node *ni)
1512: {
1513: struct ifnet *ifp = &ic->ic_if;
1514: struct ether_header *eh;
1515: struct ieee80211_eapol_key *key;
1516: u_int16_t len, info;
1517: int s, error;
1518:
1519: M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
1520: if (m == NULL)
1521: return ENOMEM;
1522: eh = mtod(m, struct ether_header *);
1523: eh->ether_type = htons(ETHERTYPE_PAE);
1524: IEEE80211_ADDR_COPY(eh->ether_shost, ic->ic_myaddr);
1525: IEEE80211_ADDR_COPY(eh->ether_dhost, ni->ni_macaddr);
1526:
1527: key = (struct ieee80211_eapol_key *)&eh[1];
1528: key->version = EAPOL_VERSION;
1529: key->type = EAPOL_KEY;
1530: key->desc = ni->ni_eapol_desc;
1531:
1532: info = BE_READ_2(key->info);
1533: /* use V2 descriptor only when pairwise cipher is CCMP */
1534: info |= (ni->ni_pairwise_cipher != IEEE80211_CIPHER_CCMP) ?
1535: EAPOL_KEY_DESC_V1 : EAPOL_KEY_DESC_V2;
1536: BE_WRITE_2(key->info, info);
1537:
1538: len = m->m_len - sizeof(struct ether_header);
1539: BE_WRITE_2(key->paylen, len - sizeof(*key));
1540: BE_WRITE_2(key->len, len - 4);
1541:
1542: KASSERT((info & (EAPOL_KEY_ENCRYPTED | EAPOL_KEY_KEYMIC)) == 0 ||
1543: ni->ni_ptk_ok);
1544:
1545: if (info & EAPOL_KEY_ENCRYPTED)
1546: ieee80211_eapol_key_encrypt(ic, key, ni->ni_ptk.kek);
1547:
1548: if (info & EAPOL_KEY_KEYMIC)
1549: ieee80211_eapol_key_mic(key, ni->ni_ptk.kck);
1550:
1551: s = splnet();
1552: IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
1553: if (error) {
1554: splx(s);
1555: return error;
1556: }
1557: ifp->if_obytes += m->m_pkthdr.len;
1558: if ((ifp->if_flags & IFF_OACTIVE) == 0)
1559: (*ifp->if_start)(ifp);
1560: splx(s);
1561:
1562: return 0;
1563: }
1564:
1565: /*
1566: * Add a GTK KDE to an EAPOL-Key frame (see Figure 144).
1567: */
1568: u_int8_t *
1569: ieee80211_add_gtk_kde(u_int8_t *frm, const struct ieee80211_key *k)
1570: {
1571: KASSERT(k->k_flags & IEEE80211_KEY_GROUP);
1572:
1573: *frm++ = IEEE80211_ELEMID_VENDOR;
1574: *frm++ = 6 + k->k_len;
1575: memcpy(frm, IEEE80211_OUI, 3); frm += 3;
1576: *frm++ = IEEE80211_KDE_GTK;
1577: *frm = k->k_id & 3;
1578: if (k->k_flags & IEEE80211_KEY_TX)
1579: *frm |= 1 << 2; /* set the Tx bit */
1580: frm++;
1581: *frm++ = 0; /* reserved */
1582: memcpy(frm, k->k_key, k->k_len);
1583: return frm + k->k_len;
1584: }
1585:
1586: /*
1587: * Add a PMKID KDE to an EAPOL-Key frame (see Figure 146).
1588: */
1589: u_int8_t *
1590: ieee80211_add_pmkid_kde(u_int8_t *frm, const u_int8_t *pmkid)
1591: {
1592: *frm++ = IEEE80211_ELEMID_VENDOR;
1593: *frm++ = 20;
1594: memcpy(frm, IEEE80211_OUI, 3); frm += 3;
1595: *frm++ = IEEE80211_KDE_PMKID;
1596: memcpy(frm, pmkid, IEEE80211_PMKID_LEN);
1597: return frm + IEEE80211_PMKID_LEN;
1598: }
1599:
1600: struct mbuf *
1601: ieee80211_get_eapol_key(int flags, int type, u_int pktlen)
1602: {
1603: struct mbuf *m;
1604:
1605: pktlen += sizeof(struct ether_header) +
1606: sizeof(struct ieee80211_eapol_key);
1607:
1608: if (pktlen > MCLBYTES)
1609: panic("EAPOL-Key frame too large: %u", pktlen);
1610: MGETHDR(m, flags, type);
1611: if (m != NULL && pktlen > MHLEN) {
1612: MCLGET(m, flags);
1613: if (!(m->m_flags & M_EXT))
1614: m = m_free(m);
1615: }
1616: m->m_data += sizeof(struct ether_header);
1617: return m;
1618: }
1619:
1620: /*
1621: * 4-Way Handshake Message 1 is sent by the authenticator to the supplicant
1622: * (see 8.5.3.1).
1623: */
1624: int
1625: ieee80211_send_4way_msg1(struct ieee80211com *ic, struct ieee80211_node *ni)
1626: {
1627: struct ieee80211_eapol_key *key;
1628: struct mbuf *m;
1629: u_int16_t info, keylen;
1630: u_int8_t *pmkid;
1631: u_int8_t *frm;
1632:
1633: m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
1634: (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) ? 2 + 20 : 0);
1635: if (m == NULL)
1636: return ENOMEM;
1637: key = mtod(m, struct ieee80211_eapol_key *);
1638: memset(key, 0, sizeof(*key));
1639:
1640: info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYACK;
1641: BE_WRITE_2(key->info, info);
1642:
1643: /* generate a new nonce ANonce */
1644: get_random_bytes(ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
1645: memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
1646:
1647: keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
1648: BE_WRITE_2(key->keylen, keylen);
1649:
1650: frm = (u_int8_t *)&key[1];
1651: /* WPA1 does not have PMKID KDE */
1652: if (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) {
1653: /* XXX retrieve PMKID from the PMKSA cache */
1654: frm = ieee80211_add_pmkid_kde(frm, pmkid);
1655: }
1656:
1657: m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
1658:
1659: if (ic->ic_if.if_flags & IFF_DEBUG)
1660: printf("%s: sending msg %d/%d of the %s handshake to %s\n",
1661: ic->ic_if.if_xname, 1, 4, "4-way",
1662: ether_sprintf(ni->ni_macaddr));
1663:
1664: return ieee80211_send_eapol_key(ic, m, ni);
1665: }
1666:
1667: /*
1668: * 4-Way Handshake Message 2 is sent by the supplicant to the authenticator
1669: * (see 8.5.3.2).
1670: */
1671: int
1672: ieee80211_send_4way_msg2(struct ieee80211com *ic, struct ieee80211_node *ni,
1673: const u_int8_t *snonce)
1674: {
1675: struct ieee80211_eapol_key *key;
1676: struct mbuf *m;
1677: u_int16_t info;
1678: u_int8_t *frm;
1679:
1680: m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
1681: 2 + 48);
1682: if (m == NULL)
1683: return ENOMEM;
1684: key = mtod(m, struct ieee80211_eapol_key *);
1685: memset(key, 0, sizeof(*key));
1686:
1687: info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC;
1688: BE_WRITE_2(key->info, info);
1689:
1690: /* copy key replay counter from authenticator */
1691: BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
1692:
1693: /* copy the supplicant's nonce (SNonce) */
1694: memcpy(key->nonce, snonce, EAPOL_KEY_NONCE_LEN);
1695:
1696: frm = (u_int8_t *)&key[1];
1697: /* add the WPA/RSN IE used in the (Re)Association Request */
1698: if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
1699: u_int16_t keylen;
1700: frm = ieee80211_add_wpa1(frm, ic, ni);
1701: /* WPA1 sets the key length field here */
1702: keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
1703: BE_WRITE_2(key->keylen, keylen);
1704: } else /* RSN */
1705: frm = ieee80211_add_rsn(frm, ic, ni);
1706:
1707: m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
1708:
1709: if (ic->ic_if.if_flags & IFF_DEBUG)
1710: printf("%s: sending msg %d/%d of the %s handshake to %s\n",
1711: ic->ic_if.if_xname, 2, 4, "4-way",
1712: ether_sprintf(ni->ni_macaddr));
1713:
1714: return ieee80211_send_eapol_key(ic, m, ni);
1715: }
1716:
1717: /*
1718: * 4-Way Handshake Message 3 is sent by the authenticator to the supplicant
1719: * (see 8.5.3.3).
1720: */
1721: int
1722: ieee80211_send_4way_msg3(struct ieee80211com *ic, struct ieee80211_node *ni)
1723: {
1724: struct ieee80211_eapol_key *key;
1725: struct ieee80211_key *gtk;
1726: struct mbuf *m;
1727: u_int16_t info, keylen;
1728: u_int8_t *frm;
1729:
1730: m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
1731: 2 + 48 +
1732: ((ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) ?
1733: 2 + 6 + gtk->k_len : 0) +
1734: 8);
1735: if (m == NULL)
1736: return ENOMEM;
1737: key = mtod(m, struct ieee80211_eapol_key *);
1738: memset(key, 0, sizeof(*key));
1739:
1740: info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_INSTALL | EAPOL_KEY_KEYACK |
1741: EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
1742:
1743: BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
1744: /* use same nonce as in Message 1 */
1745: memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
1746:
1747: keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
1748: BE_WRITE_2(key->keylen, keylen);
1749:
1750: frm = (u_int8_t *)&key[1];
1751: /* add the WPA/RSN IE included in Beacon/Probe Response */
1752: if (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) {
1753: frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
1754: /* RSN: encapsulate the GTK and ask for encryption */
1755: frm = ieee80211_add_gtk_kde(frm, gtk);
1756: LE_WRITE_8(key->rsc, gtk->k_rsc);
1757: info |= EAPOL_KEY_ENCRYPTED;
1758: } else /* WPA1 */
1759: frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
1760:
1761: /* write the key info field */
1762: BE_WRITE_2(key->info, info);
1763:
1764: m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
1765:
1766: if (ic->ic_if.if_flags & IFF_DEBUG)
1767: printf("%s: sending msg %d/%d of the %s handshake to %s\n",
1768: ic->ic_if.if_xname, 3, 4, "4-way",
1769: ether_sprintf(ni->ni_macaddr));
1770:
1771: return ieee80211_send_eapol_key(ic, m, ni);
1772: }
1773:
1774: /*
1775: * 4-Way Handshake Message 4 is sent by the supplicant to the authenticator
1776: * (see 8.5.3.4).
1777: */
1778: int
1779: ieee80211_send_4way_msg4(struct ieee80211com *ic, struct ieee80211_node *ni)
1780: {
1781: struct ieee80211_eapol_key *key;
1782: struct mbuf *m;
1783: u_int16_t info;
1784:
1785: m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
1786: if (m == NULL)
1787: return ENOMEM;
1788: key = mtod(m, struct ieee80211_eapol_key *);
1789: memset(key, 0, sizeof(*key));
1790:
1791: info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
1792: BE_WRITE_2(key->info, info);
1793:
1794: /* copy key replay counter from authenticator */
1795: BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
1796:
1797: if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
1798: u_int16_t keylen;
1799: /* WPA1 sets the key length field here */
1800: keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
1801: BE_WRITE_2(key->keylen, keylen);
1802: }
1803:
1804: /* empty key data field */
1805: m->m_pkthdr.len = m->m_len = sizeof(*key);
1806:
1807: if (ic->ic_if.if_flags & IFF_DEBUG)
1808: printf("%s: sending msg %d/%d of the %s handshake to %s\n",
1809: ic->ic_if.if_xname, 4, 4, "4-way",
1810: ether_sprintf(ni->ni_macaddr));
1811:
1812: return ieee80211_send_eapol_key(ic, m, ni);
1813: }
1814:
1815: /*
1816: * Group Key Handshake Message 1 is sent by the authenticator to the
1817: * supplicant (see 8.5.4.1).
1818: */
1819: int
1820: ieee80211_send_group_msg1(struct ieee80211com *ic, struct ieee80211_node *ni)
1821: {
1822: struct ieee80211_eapol_key *key;
1823: struct ieee80211_key *gtk;
1824: struct mbuf *m;
1825: u_int16_t info;
1826: u_int8_t *frm;
1827:
1828: m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
1829: ((ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) ?
1830: gtk->k_len : 2 + 6 + gtk->k_len) +
1831: 8);
1832: if (m == NULL)
1833: return ENOMEM;
1834: key = mtod(m, struct ieee80211_eapol_key *);
1835: memset(key, 0, sizeof(*key));
1836:
1837: info = EAPOL_KEY_KEYACK | EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE |
1838: EAPOL_KEY_ENCRYPTED;
1839:
1840: BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
1841:
1842: frm = (u_int8_t *)&key[1];
1843: if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
1844: /* WPA1 does not have GTK KDE */
1845: BE_WRITE_2(key->keylen, gtk->k_len);
1846: memcpy(frm, gtk->k_key, gtk->k_len);
1847: frm += gtk->k_len;
1848: info |= gtk->k_id << EAPOL_KEY_WPA_KID_SHIFT;
1849: if (gtk->k_flags & IEEE80211_KEY_TX)
1850: info |= EAPOL_KEY_WPA_TX;
1851: } else /* RSN */
1852: frm = ieee80211_add_gtk_kde(frm, gtk);
1853:
1854: LE_WRITE_8(key->rsc, gtk->k_rsc);
1855:
1856: /* write the key info field */
1857: BE_WRITE_2(key->info, info);
1858:
1859: m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
1860:
1861: if (ic->ic_if.if_flags & IFF_DEBUG)
1862: printf("%s: sending msg %d/%d of the %s handshake to %s\n",
1863: ic->ic_if.if_xname, 1, 2, "group key",
1864: ether_sprintf(ni->ni_macaddr));
1865:
1866: return ieee80211_send_eapol_key(ic, m, ni);
1867: }
1868:
1869: /*
1870: * Group Key Handshake Message 2 is sent by the supplicant to the
1871: * authenticator (see 8.5.4.2).
1872: */
1873: int
1874: ieee80211_send_group_msg2(struct ieee80211com *ic, struct ieee80211_node *ni,
1875: const struct ieee80211_key *gtk)
1876: {
1877: struct ieee80211_eapol_key *key;
1878: u_int16_t info;
1879: struct mbuf *m;
1880:
1881: m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
1882: if (m == NULL)
1883: return ENOMEM;
1884: key = mtod(m, struct ieee80211_eapol_key *);
1885: memset(key, 0, sizeof(*key));
1886:
1887: info = EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
1888:
1889: /* copy key replay counter from authenticator */
1890: BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
1891:
1892: if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
1893: /* WPA1 sets the key length and key id fields here */
1894: BE_WRITE_2(key->keylen, gtk->k_len);
1895: info |= (gtk->k_id & 3) << EAPOL_KEY_WPA_KID_SHIFT;
1896: }
1897:
1898: /* write the key info field */
1899: BE_WRITE_2(key->info, info);
1900:
1901: /* empty key data field */
1902: m->m_pkthdr.len = m->m_len = sizeof(*key);
1903:
1904: if (ic->ic_if.if_flags & IFF_DEBUG)
1905: printf("%s: sending msg %d/%d of the %s handshake to %s\n",
1906: ic->ic_if.if_xname, 2, 2, "group key",
1907: ether_sprintf(ni->ni_macaddr));
1908:
1909: return ieee80211_send_eapol_key(ic, m, ni);
1910: }
1911:
1912: /*
1913: * EAPOL-Key Request frames are sent by the supplicant to request that the
1914: * authenticator initiate either a 4-Way Handshake or Group Key Handshake
1915: * and to report a MIC failure in a TKIP MSDU.
1916: */
1917: int
1918: ieee80211_send_eapol_key_req(struct ieee80211com *ic,
1919: struct ieee80211_node *ni, u_int16_t info, u_int64_t tsc)
1920: {
1921: struct ieee80211_eapol_key *key;
1922: struct mbuf *m;
1923:
1924: m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
1925: if (m == NULL)
1926: return ENOMEM;
1927: key = mtod(m, struct ieee80211_eapol_key *);
1928: memset(key, 0, sizeof(*key));
1929:
1930: BE_WRITE_2(key->info, info);
1931:
1932: /* in case of TKIP MIC failure, fill the RSC field */
1933: if (info & EAPOL_KEY_ERROR)
1934: LE_WRITE_8(key->rsc, tsc);
1935:
1936: /* use our separate key replay counter for key requests */
1937: BE_WRITE_8(key->replaycnt, ic->ic_keyreplaycnt);
1938: ic->ic_keyreplaycnt++;
1939:
1940: if (ic->ic_if.if_flags & IFF_DEBUG)
1941: printf("%s: sending EAPOL-Key request to %s\n",
1942: ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr));
1943:
1944: return ieee80211_send_eapol_key(ic, m, ni);
1945: }
1946:
1947: void
1948: ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni,
1949: struct mbuf *m)
1950: {
1951: /* store the new packet on our queue, changing the TIM if necessary */
1952: if (IF_IS_EMPTY(&ni->ni_savedq))
1953: (*ic->ic_set_tim)(ic, ni->ni_associd, 1);
1954:
1955: if (ni->ni_savedq.ifq_len >= IEEE80211_PS_MAX_QUEUE) {
1956: IF_DROP(&ni->ni_savedq);
1957: m_freem(m);
1958: if (ic->ic_if.if_flags & IFF_DEBUG)
1959: printf("%s: station %s power save queue overflow"
1960: " of size %d drops %d\n",
1961: ic->ic_if.if_xname,
1962: ether_sprintf(ni->ni_macaddr),
1963: IEEE80211_PS_MAX_QUEUE,
1964: ni->ni_savedq.ifq_drops);
1965: } else {
1966: /*
1967: * Similar to ieee80211_mgmt_output, store the node in
1968: * the rcvif field.
1969: */
1970: IF_ENQUEUE(&ni->ni_savedq, m);
1971: m->m_pkthdr.rcvif = (void *)ni;
1972: }
1973: }
CVSweb