This source file includes following definitions.
- ieee80211_output
- ieee80211_mgmt_output
- ieee80211_up_to_ac
- ieee80211_classify
- ieee80211_encap
- ieee80211_add_capinfo
- ieee80211_add_ssid
- ieee80211_add_rates
- ieee80211_add_fh_params
- ieee80211_add_ds_params
- ieee80211_add_tim
- ieee80211_add_ibss_params
- ieee80211_add_edca_params
- ieee80211_add_erp
- ieee80211_add_qos_capability
- ieee80211_add_rsn_body
- ieee80211_add_rsn
- ieee80211_add_wpa1
- ieee80211_add_xrates
- ieee80211_getmbuf
- ieee80211_get_probe_req
- ieee80211_get_probe_resp
- ieee80211_get_auth
- ieee80211_get_deauth
- ieee80211_get_assoc_req
- ieee80211_get_assoc_resp
- ieee80211_get_disassoc
- ieee80211_send_mgmt
- ieee80211_get_rts
- ieee80211_get_cts_to_self
- ieee80211_beacon_alloc
- ieee80211_send_eapol_key
- ieee80211_add_gtk_kde
- ieee80211_add_pmkid_kde
- ieee80211_get_eapol_key
- ieee80211_send_4way_msg1
- ieee80211_send_4way_msg2
- ieee80211_send_4way_msg3
- ieee80211_send_4way_msg4
- ieee80211_send_group_msg1
- ieee80211_send_group_msg2
- ieee80211_send_eapol_key_req
- ieee80211_pwrsave
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
100
101
102
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
113 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
114 (IFF_UP | IFF_RUNNING)) {
115 error = ENETDOWN;
116 goto bad;
117 }
118
119
120 if ((mtag = m_tag_find(m, PACKET_TAG_DLT, NULL)) != NULL) {
121 dlt = *(u_int *)(mtag + 1);
122
123
124 if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
125 goto fallback;
126
127
128
129
130
131
132 s = splnet();
133 IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
134 if (error) {
135
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
162
163
164
165
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
180
181
182
183
184
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
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
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
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
328
329
330 enum ieee80211_edca_ac
331 ieee80211_up_to_ac(struct ieee80211com *ic, int up)
332 {
333
334 static const enum ieee80211_edca_ac up_to_ac[] = {
335 EDCA_AC_BE,
336 EDCA_AC_BK,
337 EDCA_AC_BK,
338 EDCA_AC_BE,
339 EDCA_AC_VI,
340 EDCA_AC_VI,
341 EDCA_AC_VO,
342 EDCA_AC_VO
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
353
354
355
356
357
358 while (ac != EDCA_AC_BK && ic->ic_edca_ac[ac].ac_acm) {
359 switch (ac) {
360 case EDCA_AC_BK:
361
362 break;
363 case EDCA_AC_BE:
364
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
380
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
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
403
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;
424 }
425
426
427
428
429
430
431
432
433
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
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
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;
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
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
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
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
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
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
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
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
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
697 for (i = 0; i < ic->ic_tim_len && ic->ic_tim_bitmap[i] == 0; i++);
698
699
700 if (i < ic->ic_tim_len)
701 offset = i & ~1;
702
703
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;
710 *frm++ = ic->ic_dtim_count;
711 *frm++ = ic->ic_dtim_period;
712
713
714 *frm = offset;
715
716 if (ic->ic_dtim_count == 0 && ic->ic_tim_mcast)
717 *frm |= 0x01;
718 frm++;
719
720
721 memcpy(frm, &ic->ic_tim_bitmap[offset], len);
722 return frm + len;
723 }
724
725
726
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);
734 return frm + 2;
735 }
736
737
738
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;
748 *frm++ = 0;
749 *frm++ = 0;
750
751
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
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
778
779
780 if (ic->ic_nonerpsta != 0)
781 erp |= IEEE80211_ERP_NON_ERP_PRESENT;
782
783
784
785
786
787 if (ic->ic_flags & IEEE80211_F_USEPROT)
788 erp |= IEEE80211_ERP_USE_PROTECTION;
789
790
791
792
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
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;
809 return frm;
810 }
811
812
813
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
824 LE_WRITE_2(frm, 1); frm += 2;
825
826
827 memcpy(frm, oui, 3); frm += 3;
828 switch (ni->ni_group_cipher) {
829 case IEEE80211_CIPHER_USEGROUP:
830
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
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
866 LE_WRITE_2(pcount, count);
867
868 pcount = frm; frm += 2;
869 count = 0;
870
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
882 LE_WRITE_2(pcount, count);
883
884
885 LE_WRITE_2(frm, ni->ni_rsncaps); frm += 2;
886
887
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++;
900 frm = ieee80211_add_rsn_body(frm, ic, ni, 0);
901
902
903 *plen = frm - plen - 1;
904 return frm;
905 }
906
907
908
909
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++;
919 memcpy(frm, MICROSOFT_OUI, 3); frm += 3;
920 *frm++ = 1;
921 frm = ieee80211_add_rsn_body(frm, ic, ni, 1);
922
923
924 *plen = frm - plen - 1;
925 return frm;
926 }
927
928
929
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
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
966
967
968
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
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;
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
1068
1069
1070
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
1095
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
1116
1117
1118
1119
1120
1121
1122
1123
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
1185
1186
1187
1188
1189
1190
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
1233
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
1254
1255
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
1271
1272
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
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
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
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
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
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;
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
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
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
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
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;
1580 frm++;
1581 *frm++ = 0;
1582 memcpy(frm, k->k_key, k->k_len);
1583 return frm + k->k_len;
1584 }
1585
1586
1587
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
1622
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
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
1652 if (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) {
1653
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
1669
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
1691 BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
1692
1693
1694 memcpy(key->nonce, snonce, EAPOL_KEY_NONCE_LEN);
1695
1696 frm = (u_int8_t *)&key[1];
1697
1698 if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
1699 u_int16_t keylen;
1700 frm = ieee80211_add_wpa1(frm, ic, ni);
1701
1702 keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
1703 BE_WRITE_2(key->keylen, keylen);
1704 } else
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
1719
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
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
1752 if (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) {
1753 frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
1754
1755 frm = ieee80211_add_gtk_kde(frm, gtk);
1756 LE_WRITE_8(key->rsc, gtk->k_rsc);
1757 info |= EAPOL_KEY_ENCRYPTED;
1758 } else
1759 frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
1760
1761
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
1776
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
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
1800 keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
1801 BE_WRITE_2(key->keylen, keylen);
1802 }
1803
1804
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
1817
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
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
1852 frm = ieee80211_add_gtk_kde(frm, gtk);
1853
1854 LE_WRITE_8(key->rsc, gtk->k_rsc);
1855
1856
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
1871
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
1890 BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
1891
1892 if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
1893
1894 BE_WRITE_2(key->keylen, gtk->k_len);
1895 info |= (gtk->k_id & 3) << EAPOL_KEY_WPA_KID_SHIFT;
1896 }
1897
1898
1899 BE_WRITE_2(key->info, info);
1900
1901
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
1914
1915
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
1933 if (info & EAPOL_KEY_ERROR)
1934 LE_WRITE_8(key->rsc, tsc);
1935
1936
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
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
1968
1969
1970 IF_ENQUEUE(&ni->ni_savedq, m);
1971 m->m_pkthdr.rcvif = (void *)ni;
1972 }
1973 }