2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
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.
32 * $FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.26.2.8 2006/09/02 15:06:04 sam Exp $
33 * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_output.c,v 1.21 2007/05/07 14:12:16 sephe Exp $
38 #include <sys/param.h>
39 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/endian.h>
44 #include <sys/socket.h>
47 #include <net/ethernet.h>
49 #include <net/if_arp.h>
50 #include <net/if_llc.h>
51 #include <net/if_media.h>
52 #include <net/vlan/if_vlan_var.h>
54 #include <netproto/802_11/ieee80211_var.h>
57 #include <netinet/in.h>
58 #include <netinet/if_ether.h>
59 #include <netinet/in_systm.h>
60 #include <netinet/ip.h>
63 #ifdef IEEE80211_DEBUG
65 * Decide if an outbound management frame should be
66 * printed when debugging is enabled. This filters some
67 * of the less interesting frames that come frequently
71 doprint(struct ieee80211com
*ic
, int subtype
)
74 case IEEE80211_FC0_SUBTYPE_PROBE_RESP
:
75 return (ic
->ic_opmode
== IEEE80211_M_IBSS
);
82 * Set the direction field and address fields of an outgoing
83 * non-QoS frame. Note this should be called early on in
84 * constructing a frame as it sets i_fc[1]; other bits can
88 ieee80211_send_setup(struct ieee80211com
*ic
,
89 struct ieee80211_node
*ni
,
90 struct ieee80211_frame
*wh
,
92 const uint8_t sa
[IEEE80211_ADDR_LEN
],
93 const uint8_t da
[IEEE80211_ADDR_LEN
],
94 const uint8_t bssid
[IEEE80211_ADDR_LEN
])
96 #define WH4(wh) ((struct ieee80211_frame_addr4 *)wh)
98 wh
->i_fc
[0] = IEEE80211_FC0_VERSION_0
| type
;
99 if ((type
& IEEE80211_FC0_TYPE_MASK
) == IEEE80211_FC0_TYPE_DATA
) {
100 switch (ic
->ic_opmode
) {
101 case IEEE80211_M_STA
:
102 wh
->i_fc
[1] = IEEE80211_FC1_DIR_TODS
;
103 IEEE80211_ADDR_COPY(wh
->i_addr1
, bssid
);
104 IEEE80211_ADDR_COPY(wh
->i_addr2
, sa
);
105 IEEE80211_ADDR_COPY(wh
->i_addr3
, da
);
107 case IEEE80211_M_IBSS
:
108 case IEEE80211_M_AHDEMO
:
109 wh
->i_fc
[1] = IEEE80211_FC1_DIR_NODS
;
110 IEEE80211_ADDR_COPY(wh
->i_addr1
, da
);
111 IEEE80211_ADDR_COPY(wh
->i_addr2
, sa
);
112 IEEE80211_ADDR_COPY(wh
->i_addr3
, bssid
);
114 case IEEE80211_M_HOSTAP
:
115 wh
->i_fc
[1] = IEEE80211_FC1_DIR_FROMDS
;
116 IEEE80211_ADDR_COPY(wh
->i_addr1
, da
);
117 IEEE80211_ADDR_COPY(wh
->i_addr2
, bssid
);
118 IEEE80211_ADDR_COPY(wh
->i_addr3
, sa
);
120 case IEEE80211_M_MONITOR
: /* NB: to quiet compiler */
124 wh
->i_fc
[1] = IEEE80211_FC1_DIR_NODS
;
125 IEEE80211_ADDR_COPY(wh
->i_addr1
, da
);
126 IEEE80211_ADDR_COPY(wh
->i_addr2
, sa
);
127 IEEE80211_ADDR_COPY(wh
->i_addr3
, bssid
);
129 *(uint16_t *)&wh
->i_dur
[0] = 0;
130 /* NB: use non-QoS tid */
131 *(uint16_t *)&wh
->i_seq
[0] =
132 htole16(ni
->ni_txseqs
[0] << IEEE80211_SEQ_SEQ_SHIFT
);
138 * Send a management frame to the specified node. The node pointer
139 * must have a reference as the pointer will be passed to the driver
140 * and potentially held for a long time. If the frame is successfully
141 * dispatched to the driver, then it is responsible for freeing the
142 * reference (and potentially free'ing up any associated storage).
145 ieee80211_mgmt_output(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
146 struct mbuf
*m
, int type
, int timer
, int encrypt
)
148 struct ifnet
*ifp
= ic
->ic_ifp
;
149 struct ieee80211_frame
*wh
;
151 KASSERT(ni
!= NULL
, ("null node"));
154 * Yech, hack alert! We want to pass the node down to the
155 * driver's start routine. If we don't do so then the start
156 * routine must immediately look it up again and that can
157 * cause a lock order reversal if, for example, this frame
158 * is being sent because the station is being timedout and
159 * the frame being sent is a DEAUTH message. We could stick
160 * this in an m_tag and tack that on to the mbuf. However
161 * that's rather expensive to do for every frame so instead
162 * we stuff it in the rcvif field since outbound frames do
163 * not (presently) use this.
165 M_PREPEND(m
, sizeof(struct ieee80211_frame
), MB_DONTWAIT
);
168 KASSERT(m
->m_pkthdr
.rcvif
== NULL
, ("rcvif not null"));
169 m
->m_pkthdr
.rcvif
= (void *)ni
;
171 wh
= mtod(m
, struct ieee80211_frame
*);
172 ieee80211_send_setup(ic
, ni
, wh
,
173 IEEE80211_FC0_TYPE_MGT
| type
,
174 ic
->ic_myaddr
, ni
->ni_macaddr
, ni
->ni_bssid
);
176 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_AUTH
,
177 "[%6D] encrypting frame (%s)\n",
178 wh
->i_addr1
, ":", __func__
);
179 wh
->i_fc
[1] |= IEEE80211_FC1_WEP
;
181 #ifdef IEEE80211_DEBUG
182 /* avoid printing too many frames */
183 if ((ieee80211_msg_debug(ic
) && doprint(ic
, type
)) ||
184 ieee80211_msg_dumppkts(ic
)) {
185 kprintf("[%6D] send %s on channel %u\n",
187 ieee80211_mgt_subtype_name
[
188 (type
& IEEE80211_FC0_SUBTYPE_MASK
) >>
189 IEEE80211_FC0_SUBTYPE_SHIFT
],
190 ieee80211_chan2ieee(ic
, ic
->ic_curchan
));
193 IEEE80211_NODE_STAT(ni
, tx_mgmt
);
194 IF_ENQUEUE(&ic
->ic_mgtq
, m
);
197 * Set the mgt frame timeout.
199 ic
->ic_mgt_timer
= timer
;
207 * Send a null data frame to the specified node.
209 * NB: the caller is assumed to have setup a node reference
210 * for use; this is necessary to deal with a race condition
211 * when probing for inactive stations.
214 ieee80211_send_nulldata(struct ieee80211_node
*ni
)
216 struct ieee80211com
*ic
= ni
->ni_ic
;
217 struct ifnet
*ifp
= ic
->ic_ifp
;
219 struct ieee80211_frame
*wh
;
221 MGETHDR(m
, MB_DONTWAIT
, MT_HEADER
);
224 ic
->ic_stats
.is_tx_nobuf
++;
225 ieee80211_unref_node(&ni
);
228 m
->m_pkthdr
.rcvif
= (void *) ni
;
230 wh
= mtod(m
, struct ieee80211_frame
*);
231 ieee80211_send_setup(ic
, ni
, wh
,
232 IEEE80211_FC0_TYPE_DATA
| IEEE80211_FC0_SUBTYPE_NODATA
,
233 ic
->ic_myaddr
, ni
->ni_macaddr
, ni
->ni_bssid
);
234 /* NB: power management bit is never sent by an AP */
235 if ((ni
->ni_flags
& IEEE80211_NODE_PWR_MGT
) &&
236 ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
237 wh
->i_fc
[1] |= IEEE80211_FC1_PWR_MGT
;
238 m
->m_len
= m
->m_pkthdr
.len
= sizeof(struct ieee80211_frame
);
240 IEEE80211_NODE_STAT(ni
, tx_data
);
242 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_DEBUG
| IEEE80211_MSG_DUMPPKTS
,
243 "[%s] send null data frame on channel %u, pwr mgt %s\n",
245 ieee80211_chan2ieee(ic
, ic
->ic_curchan
),
246 wh
->i_fc
[1] & IEEE80211_FC1_PWR_MGT
? "ena" : "dis");
248 IF_ENQUEUE(&ic
->ic_mgtq
, m
); /* cheat */
254 * Assign priority to a frame based on any vlan tag assigned
255 * to the station and/or any Diffserv setting in an IP header.
256 * Finally, if an ACM policy is setup (in station mode) it's
260 ieee80211_classify(struct ieee80211com
*ic
, struct mbuf
*m
, struct ieee80211_node
*ni
)
262 int v_wme_ac
= 0, d_wme_ac
, ac
;
264 struct ether_header
*eh
;
267 if ((ni
->ni_flags
& IEEE80211_NODE_QOS
) == 0) {
274 * If node has a vlan tag then all traffic
275 * to it must have a matching tag.
278 if (ni
->ni_vlan
!= 0) {
279 struct m_tag
*mtag
= VLAN_OUTPUT_TAG(ic
->ic_ifp
, m
);
281 IEEE80211_NODE_STAT(ni
, tx_novlantag
);
284 if (EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag
)) !=
285 EVL_VLANOFTAG(ni
->ni_vlan
)) {
286 IEEE80211_NODE_STAT(ni
, tx_vlanmismatch
);
289 /* map vlan priority to AC */
290 switch (EVL_PRIOFTAG(ni
->ni_vlan
)) {
293 v_wme_ac
= WME_AC_BK
;
297 v_wme_ac
= WME_AC_BE
;
301 v_wme_ac
= WME_AC_VI
;
305 v_wme_ac
= WME_AC_VO
;
309 #endif /* FREEBSD_VLAN */
312 eh
= mtod(m
, struct ether_header
*);
313 if (eh
->ether_type
== htons(ETHERTYPE_IP
)) {
314 const struct ip
*ip
= (struct ip
*)
315 (mtod(m
, uint8_t *) + sizeof (*eh
));
317 * IP frame, map the TOS field.
319 switch (ip
->ip_tos
) {
322 d_wme_ac
= WME_AC_BK
; /* background */
326 d_wme_ac
= WME_AC_VI
; /* video */
328 case 0x30: /* voice */
330 case 0x88: /* XXX UPSD */
332 d_wme_ac
= WME_AC_VO
;
335 d_wme_ac
= WME_AC_BE
;
340 d_wme_ac
= WME_AC_BE
;
345 * Use highest priority AC.
347 if (v_wme_ac
> d_wme_ac
)
355 if (ic
->ic_opmode
== IEEE80211_M_STA
) {
356 static const int acmap
[4] = {
357 WME_AC_BK
, /* WME_AC_BE */
358 WME_AC_BK
, /* WME_AC_BK */
359 WME_AC_BE
, /* WME_AC_VI */
360 WME_AC_VI
, /* WME_AC_VO */
362 while (ac
!= WME_AC_BK
&&
363 ic
->ic_wme
.wme_wmeBssChanParams
.cap_wmeParams
[ac
].wmep_acm
)
372 * Insure there is sufficient contiguous space to encapsulate the
373 * 802.11 data frame. If room isn't already there, arrange for it.
374 * Drivers and cipher modules assume we have done the necessary work
375 * and fail rudely if they don't find the space they need.
378 ieee80211_mbuf_adjust(struct ieee80211com
*ic
, int hdrsize
,
379 struct ieee80211_key
*key
, struct mbuf
*m
)
381 #define TO_BE_RECLAIMED (sizeof(struct ether_header) - sizeof(struct llc))
382 int needed_space
= hdrsize
;
385 /* XXX belongs in crypto code? */
386 if ((key
->wk_flags
& IEEE80211_KEY_NOHDR
) == 0)
387 needed_space
+= key
->wk_cipher
->ic_header
;
390 * When crypto is being done in the host we must insure
391 * the data are writable for the cipher routines; clone
392 * a writable mbuf chain.
393 * XXX handle SWMIC specially
395 if (key
->wk_flags
& (IEEE80211_KEY_SWCRYPT
|IEEE80211_KEY_SWMIC
)) {
396 m
= ieee80211_mbuf_clone(m
, MB_DONTWAIT
);
398 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_OUTPUT
,
399 "%s: cannot get writable mbuf\n", __func__
);
400 ic
->ic_stats
.is_tx_nobuf
++; /* XXX new stat */
406 * We know we are called just before stripping an Ethernet
407 * header and prepending an LLC header. This means we know
409 * sizeof(struct ether_header) - sizeof(struct llc)
410 * bytes recovered to which we need additional space for the
411 * 802.11 header and any crypto header.
413 /* XXX check trailing space and copy instead? */
414 if (M_LEADINGSPACE(m
) < needed_space
- TO_BE_RECLAIMED
) {
415 struct mbuf
*n
= m_gethdr(MB_DONTWAIT
, m
->m_type
);
417 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_OUTPUT
,
418 "%s: cannot expand storage\n", __func__
);
419 ic
->ic_stats
.is_tx_nobuf
++;
423 KASSERT(needed_space
<= MHLEN
,
424 ("not enough room, need %u got %zu\n", needed_space
, MHLEN
));
426 * Setup new mbuf to have leading space to prepend the
427 * 802.11 header and any crypto header bits that are
428 * required (the latter are added when the driver calls
429 * back to ieee80211_crypto_encap to do crypto encapsulation).
431 /* NB: must be first 'cuz it clobbers m_data */
433 n
->m_len
= 0; /* NB: m_gethdr does not set */
434 n
->m_data
+= needed_space
;
436 * Pull up Ethernet header to create the expected layout.
437 * We could use m_pullup but that's overkill (i.e. we don't
438 * need the actual data) and it cannot fail so do it inline
441 /* NB: struct ether_header is known to be contiguous */
442 n
->m_len
+= sizeof(struct ether_header
);
443 m
->m_len
-= sizeof(struct ether_header
);
444 m
->m_data
+= sizeof(struct ether_header
);
446 * Replace the head of the chain.
452 #undef TO_BE_RECLAIMED
455 #define KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none)
457 * Return the transmit key to use in sending a unicast frame.
458 * If a unicast key is set we use that. When no unicast key is set
459 * we fall back to the default transmit key.
461 static __inline
struct ieee80211_key
*
462 ieee80211_crypto_getucastkey(struct ieee80211com
*ic
, struct ieee80211_node
*ni
)
464 if (KEY_UNDEFINED(ni
->ni_ucastkey
)) {
465 if (ic
->ic_def_txkey
== IEEE80211_KEYIX_NONE
||
466 KEY_UNDEFINED(ic
->ic_nw_keys
[ic
->ic_def_txkey
]))
468 return &ic
->ic_nw_keys
[ic
->ic_def_txkey
];
470 return &ni
->ni_ucastkey
;
475 * Return the transmit key to use in sending a multicast frame.
476 * Multicast traffic always uses the group key which is installed as
477 * the default tx key.
479 static __inline
struct ieee80211_key
*
480 ieee80211_crypto_getmcastkey(struct ieee80211com
*ic
, struct ieee80211_node
*ni
)
482 if (ic
->ic_def_txkey
== IEEE80211_KEYIX_NONE
||
483 KEY_UNDEFINED(ic
->ic_nw_keys
[ic
->ic_def_txkey
]))
485 return &ic
->ic_nw_keys
[ic
->ic_def_txkey
];
489 * Encapsulate an outbound data frame. The mbuf chain is updated.
490 * If an error is encountered NULL is returned. The caller is required
491 * to provide a node reference and pullup the ethernet header in the
495 ieee80211_encap(struct ieee80211com
*ic
, struct mbuf
*m
,
496 struct ieee80211_node
*ni
)
498 struct ether_header eh
;
499 struct ieee80211_frame
*wh
;
500 struct ieee80211_key
*key
;
502 int hdrsize
, datalen
, addqos
;
504 KASSERT(m
->m_len
>= sizeof(eh
), ("no ethernet header!"));
505 memcpy(&eh
, mtod(m
, caddr_t
), sizeof(struct ether_header
));
508 * Insure space for additional headers. First identify
509 * transmit key to use in calculating any buffer adjustments
510 * required. This is also used below to do privacy
511 * encapsulation work. Then calculate the 802.11 header
512 * size and any padding required by the driver.
514 * Note key may be NULL if we fall back to the default
515 * transmit key and that is not set. In that case the
516 * buffer may not be expanded as needed by the cipher
517 * routines, but they will/should discard it.
519 if (ic
->ic_flags
& IEEE80211_F_PRIVACY
) {
520 if (ic
->ic_opmode
== IEEE80211_M_STA
||
521 !IEEE80211_IS_MULTICAST(eh
.ether_dhost
))
522 key
= ieee80211_crypto_getucastkey(ic
, ni
);
524 key
= ieee80211_crypto_getmcastkey(ic
, ni
);
525 if (key
== NULL
&& eh
.ether_type
!= htons(ETHERTYPE_PAE
)) {
526 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_CRYPTO
,
527 "[%6D] no default transmit key (%s) deftxkey %u\n",
528 eh
.ether_dhost
, ":", __func__
,
530 ic
->ic_stats
.is_tx_nodefkey
++;
534 /* XXX 4-address format */
536 * XXX Some ap's don't handle QoS-encapsulated EAPOL
537 * frames so suppress use. This may be an issue if other
538 * ap's require all data frames to be QoS-encapsulated
539 * once negotiated in which case we'll need to make this
542 addqos
= (ni
->ni_flags
& IEEE80211_NODE_QOS
) &&
543 eh
.ether_type
!= htons(ETHERTYPE_PAE
);
545 hdrsize
= sizeof(struct ieee80211_qosframe
);
547 hdrsize
= sizeof(struct ieee80211_frame
);
548 if (ic
->ic_flags
& IEEE80211_F_DATAPAD
)
549 hdrsize
= roundup(hdrsize
, sizeof(uint32_t));
550 m
= ieee80211_mbuf_adjust(ic
, hdrsize
, key
, m
);
552 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */
556 /* NB: this could be optimized because of ieee80211_mbuf_adjust */
557 m_adj(m
, sizeof(struct ether_header
) - sizeof(struct llc
));
558 llc
= mtod(m
, struct llc
*);
559 llc
->llc_dsap
= llc
->llc_ssap
= LLC_SNAP_LSAP
;
560 llc
->llc_control
= LLC_UI
;
561 llc
->llc_snap
.org_code
[0] = 0;
562 llc
->llc_snap
.org_code
[1] = 0;
563 llc
->llc_snap
.org_code
[2] = 0;
564 llc
->llc_snap
.ether_type
= eh
.ether_type
;
565 datalen
= m
->m_pkthdr
.len
; /* NB: w/o 802.11 header */
567 M_PREPEND(m
, hdrsize
, MB_DONTWAIT
);
569 ic
->ic_stats
.is_tx_nobuf
++;
572 wh
= mtod(m
, struct ieee80211_frame
*);
573 wh
->i_fc
[0] = IEEE80211_FC0_VERSION_0
| IEEE80211_FC0_TYPE_DATA
;
574 *(uint16_t *)wh
->i_dur
= 0;
575 switch (ic
->ic_opmode
) {
576 case IEEE80211_M_STA
:
577 wh
->i_fc
[1] = IEEE80211_FC1_DIR_TODS
;
578 IEEE80211_ADDR_COPY(wh
->i_addr1
, ni
->ni_bssid
);
579 IEEE80211_ADDR_COPY(wh
->i_addr2
, eh
.ether_shost
);
580 IEEE80211_ADDR_COPY(wh
->i_addr3
, eh
.ether_dhost
);
582 case IEEE80211_M_IBSS
:
583 case IEEE80211_M_AHDEMO
:
584 wh
->i_fc
[1] = IEEE80211_FC1_DIR_NODS
;
585 IEEE80211_ADDR_COPY(wh
->i_addr1
, eh
.ether_dhost
);
586 IEEE80211_ADDR_COPY(wh
->i_addr2
, eh
.ether_shost
);
588 * NB: always use the bssid from ic_bss as the
589 * neighbor's may be stale after an ibss merge
591 IEEE80211_ADDR_COPY(wh
->i_addr3
, ic
->ic_bss
->ni_bssid
);
593 case IEEE80211_M_HOSTAP
:
594 wh
->i_fc
[1] = IEEE80211_FC1_DIR_FROMDS
;
595 IEEE80211_ADDR_COPY(wh
->i_addr1
, eh
.ether_dhost
);
596 IEEE80211_ADDR_COPY(wh
->i_addr2
, ni
->ni_bssid
);
597 IEEE80211_ADDR_COPY(wh
->i_addr3
, eh
.ether_shost
);
599 case IEEE80211_M_MONITOR
:
602 if (m
->m_flags
& M_MORE_DATA
)
603 wh
->i_fc
[1] |= IEEE80211_FC1_MORE_DATA
;
605 struct ieee80211_qosframe
*qwh
=
606 (struct ieee80211_qosframe
*) wh
;
610 /* map from access class/queue to 11e header priorty value */
611 tid
= WME_AC_TO_TID(ac
);
612 qwh
->i_qos
[0] = tid
& IEEE80211_QOS_TID
;
613 if (ic
->ic_wme
.wme_wmeChanParams
.cap_wmeParams
[ac
].wmep_noackPolicy
)
614 qwh
->i_qos
[0] |= 1 << IEEE80211_QOS_ACKPOLICY_S
;
616 qwh
->i_fc
[0] |= IEEE80211_FC0_SUBTYPE_QOS
;
618 *(uint16_t *)wh
->i_seq
=
619 htole16(ni
->ni_txseqs
[tid
] << IEEE80211_SEQ_SEQ_SHIFT
);
620 ni
->ni_txseqs
[tid
]++;
622 *(uint16_t *)wh
->i_seq
=
623 htole16(ni
->ni_txseqs
[0] << IEEE80211_SEQ_SEQ_SHIFT
);
628 * IEEE 802.1X: send EAPOL frames always in the clear.
629 * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set.
631 if (eh
.ether_type
!= htons(ETHERTYPE_PAE
) ||
632 ((ic
->ic_flags
& IEEE80211_F_WPA
) &&
633 (ic
->ic_opmode
== IEEE80211_M_STA
?
634 !KEY_UNDEFINED(*key
) : !KEY_UNDEFINED(ni
->ni_ucastkey
)))) {
635 wh
->i_fc
[1] |= IEEE80211_FC1_WEP
;
636 /* XXX do fragmentation */
637 if (!ieee80211_crypto_enmic(ic
, key
, m
, 0)) {
638 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_OUTPUT
,
639 "[%6D] enmic failed, discard frame\n",
640 eh
.ether_dhost
, ":");
641 ic
->ic_stats
.is_crypto_enmicfail
++;
647 IEEE80211_NODE_STAT(ni
, tx_data
);
648 if (IEEE80211_IS_MULTICAST(wh
->i_addr1
))
649 IEEE80211_NODE_STAT(ni
, tx_mcast
);
651 IEEE80211_NODE_STAT(ni
, tx_ucast
);
652 IEEE80211_NODE_STAT_ADD(ni
, tx_bytes
, datalen
);
662 * Add a supported rates element id to a frame.
665 ieee80211_add_rates(uint8_t *frm
, const struct ieee80211_rateset
*rs
)
669 *frm
++ = IEEE80211_ELEMID_RATES
;
670 nrates
= rs
->rs_nrates
;
671 if (nrates
> IEEE80211_RATE_SIZE
)
672 nrates
= IEEE80211_RATE_SIZE
;
674 memcpy(frm
, rs
->rs_rates
, nrates
);
679 * Add an extended supported rates element id to a frame.
682 ieee80211_add_xrates(uint8_t *frm
, const struct ieee80211_rateset
*rs
)
685 * Add an extended supported rates element if operating in 11g mode.
687 if (rs
->rs_nrates
> IEEE80211_RATE_SIZE
) {
688 int nrates
= rs
->rs_nrates
- IEEE80211_RATE_SIZE
;
689 *frm
++ = IEEE80211_ELEMID_XRATES
;
691 memcpy(frm
, rs
->rs_rates
+ IEEE80211_RATE_SIZE
, nrates
);
698 * Add an ssid elemet to a frame.
701 ieee80211_add_ssid(uint8_t *frm
, const uint8_t *ssid
, u_int len
)
703 *frm
++ = IEEE80211_ELEMID_SSID
;
705 memcpy(frm
, ssid
, len
);
710 * Add an erp element to a frame.
713 ieee80211_add_erp(uint8_t *frm
, struct ieee80211com
*ic
)
717 *frm
++ = IEEE80211_ELEMID_ERP
;
720 if (ic
->ic_nonerpsta
!= 0)
721 erp
|= IEEE80211_ERP_NON_ERP_PRESENT
;
722 if (ic
->ic_flags
& IEEE80211_F_USEPROT
)
723 erp
|= IEEE80211_ERP_USE_PROTECTION
;
724 if (ic
->ic_flags
& IEEE80211_F_USEBARKER
)
725 erp
|= IEEE80211_ERP_LONG_PREAMBLE
;
731 ieee80211_setup_wpa_ie(struct ieee80211com
*ic
, uint8_t *ie
)
733 #define WPA_OUI_BYTES 0x00, 0x50, 0xf2
734 #define ADDSHORT(frm, v) do { \
735 frm[0] = (v) & 0xff; \
739 #define ADDSELECTOR(frm, sel) do { \
740 memcpy(frm, sel, 4); \
743 static const uint8_t oui
[4] = { WPA_OUI_BYTES
, WPA_OUI_TYPE
};
744 static const uint8_t cipher_suite
[][4] = {
745 { WPA_OUI_BYTES
, WPA_CSE_WEP40
}, /* NB: 40-bit */
746 { WPA_OUI_BYTES
, WPA_CSE_TKIP
},
747 { 0x00, 0x00, 0x00, 0x00 }, /* XXX WRAP */
748 { WPA_OUI_BYTES
, WPA_CSE_CCMP
},
749 { 0x00, 0x00, 0x00, 0x00 }, /* XXX CKIP */
750 { WPA_OUI_BYTES
, WPA_CSE_NULL
},
752 static const uint8_t wep104_suite
[4] =
753 { WPA_OUI_BYTES
, WPA_CSE_WEP104
};
754 static const uint8_t key_mgt_unspec
[4] =
755 { WPA_OUI_BYTES
, WPA_ASE_8021X_UNSPEC
};
756 static const uint8_t key_mgt_psk
[4] =
757 { WPA_OUI_BYTES
, WPA_ASE_8021X_PSK
};
758 const struct ieee80211_rsnparms
*rsn
= &ic
->ic_bss
->ni_rsn
;
762 *frm
++ = IEEE80211_ELEMID_VENDOR
;
763 *frm
++ = 0; /* length filled in below */
764 memcpy(frm
, oui
, sizeof(oui
)); /* WPA OUI */
766 ADDSHORT(frm
, WPA_VERSION
);
768 /* XXX filter out CKIP */
770 /* multicast cipher */
771 if (rsn
->rsn_mcastcipher
== IEEE80211_CIPHER_WEP
&&
772 rsn
->rsn_mcastkeylen
>= 13)
773 ADDSELECTOR(frm
, wep104_suite
);
775 ADDSELECTOR(frm
, cipher_suite
[rsn
->rsn_mcastcipher
]);
777 /* unicast cipher list */
779 ADDSHORT(frm
, 0); /* selector count */
780 if (rsn
->rsn_ucastcipherset
& (1<<IEEE80211_CIPHER_AES_CCM
)) {
782 ADDSELECTOR(frm
, cipher_suite
[IEEE80211_CIPHER_AES_CCM
]);
784 if (rsn
->rsn_ucastcipherset
& (1<<IEEE80211_CIPHER_TKIP
)) {
786 ADDSELECTOR(frm
, cipher_suite
[IEEE80211_CIPHER_TKIP
]);
789 /* authenticator selector list */
791 ADDSHORT(frm
, 0); /* selector count */
792 if (rsn
->rsn_keymgmtset
& WPA_ASE_8021X_UNSPEC
) {
794 ADDSELECTOR(frm
, key_mgt_unspec
);
796 if (rsn
->rsn_keymgmtset
& WPA_ASE_8021X_PSK
) {
798 ADDSELECTOR(frm
, key_mgt_psk
);
801 /* optional capabilities */
802 if (rsn
->rsn_caps
!= 0 && rsn
->rsn_caps
!= RSN_CAP_PREAUTH
)
803 ADDSHORT(frm
, rsn
->rsn_caps
);
805 /* calculate element length */
806 ie
[1] = frm
- ie
- 2;
807 KASSERT(ie
[1]+2 <= sizeof(struct ieee80211_ie_wpa
),
808 ("WPA IE too big, %u > %zu",
809 ie
[1]+2, sizeof(struct ieee80211_ie_wpa
)));
817 ieee80211_setup_rsn_ie(struct ieee80211com
*ic
, uint8_t *ie
)
819 #define RSN_OUI_BYTES 0x00, 0x0f, 0xac
820 #define ADDSHORT(frm, v) do { \
821 frm[0] = (v) & 0xff; \
825 #define ADDSELECTOR(frm, sel) do { \
826 memcpy(frm, sel, 4); \
829 static const uint8_t cipher_suite
[][4] = {
830 { RSN_OUI_BYTES
, RSN_CSE_WEP40
}, /* NB: 40-bit */
831 { RSN_OUI_BYTES
, RSN_CSE_TKIP
},
832 { RSN_OUI_BYTES
, RSN_CSE_WRAP
},
833 { RSN_OUI_BYTES
, RSN_CSE_CCMP
},
834 { 0x00, 0x00, 0x00, 0x00 }, /* XXX CKIP */
835 { RSN_OUI_BYTES
, RSN_CSE_NULL
},
837 static const uint8_t wep104_suite
[4] =
838 { RSN_OUI_BYTES
, RSN_CSE_WEP104
};
839 static const uint8_t key_mgt_unspec
[4] =
840 { RSN_OUI_BYTES
, RSN_ASE_8021X_UNSPEC
};
841 static const uint8_t key_mgt_psk
[4] =
842 { RSN_OUI_BYTES
, RSN_ASE_8021X_PSK
};
843 const struct ieee80211_rsnparms
*rsn
= &ic
->ic_bss
->ni_rsn
;
847 *frm
++ = IEEE80211_ELEMID_RSN
;
848 *frm
++ = 0; /* length filled in below */
849 ADDSHORT(frm
, RSN_VERSION
);
851 /* XXX filter out CKIP */
853 /* multicast cipher */
854 if (rsn
->rsn_mcastcipher
== IEEE80211_CIPHER_WEP
&&
855 rsn
->rsn_mcastkeylen
>= 13)
856 ADDSELECTOR(frm
, wep104_suite
);
858 ADDSELECTOR(frm
, cipher_suite
[rsn
->rsn_mcastcipher
]);
860 /* unicast cipher list */
862 ADDSHORT(frm
, 0); /* selector count */
863 if (rsn
->rsn_ucastcipherset
& (1<<IEEE80211_CIPHER_AES_CCM
)) {
865 ADDSELECTOR(frm
, cipher_suite
[IEEE80211_CIPHER_AES_CCM
]);
867 if (rsn
->rsn_ucastcipherset
& (1<<IEEE80211_CIPHER_TKIP
)) {
869 ADDSELECTOR(frm
, cipher_suite
[IEEE80211_CIPHER_TKIP
]);
872 /* authenticator selector list */
874 ADDSHORT(frm
, 0); /* selector count */
875 if (rsn
->rsn_keymgmtset
& WPA_ASE_8021X_UNSPEC
) {
877 ADDSELECTOR(frm
, key_mgt_unspec
);
879 if (rsn
->rsn_keymgmtset
& WPA_ASE_8021X_PSK
) {
881 ADDSELECTOR(frm
, key_mgt_psk
);
884 /* optional capabilities */
885 ADDSHORT(frm
, rsn
->rsn_caps
);
888 /* calculate element length */
889 ie
[1] = frm
- ie
- 2;
890 KASSERT(ie
[1]+2 <= sizeof(struct ieee80211_ie_wpa
),
891 ("RSN IE too big, %u > %zu",
892 ie
[1]+2, sizeof(struct ieee80211_ie_wpa
)));
900 * Add a WPA/RSN element to a frame.
903 ieee80211_add_wpa(uint8_t *frm
, struct ieee80211com
*ic
)
906 KASSERT(ic
->ic_flags
& IEEE80211_F_WPA
, ("no WPA/RSN!"));
907 if (ic
->ic_flags
& IEEE80211_F_WPA2
)
908 frm
= ieee80211_setup_rsn_ie(ic
, frm
);
909 if (ic
->ic_flags
& IEEE80211_F_WPA1
)
910 frm
= ieee80211_setup_wpa_ie(ic
, frm
);
914 #define WME_OUI_BYTES 0x00, 0x50, 0xf2
916 * Add a WME information element to a frame.
919 ieee80211_add_wme_info(uint8_t *frm
, struct ieee80211_wme_state
*wme
)
921 static const struct ieee80211_wme_info info
= {
922 .wme_id
= IEEE80211_ELEMID_VENDOR
,
923 .wme_len
= sizeof(struct ieee80211_wme_info
) - 2,
924 .wme_oui
= { WME_OUI_BYTES
},
925 .wme_type
= WME_OUI_TYPE
,
926 .wme_subtype
= WME_INFO_OUI_SUBTYPE
,
927 .wme_version
= WME_VERSION
,
930 memcpy(frm
, &info
, sizeof(info
));
931 return frm
+ sizeof(info
);
935 * Add a WME parameters element to a frame.
938 ieee80211_add_wme_param(uint8_t *frm
, struct ieee80211_wme_state
*wme
)
940 #define SM(_v, _f) (((_v) << _f##_S) & _f)
941 #define ADDSHORT(frm, v) do { \
942 frm[0] = (v) & 0xff; \
946 /* NB: this works 'cuz a param has an info at the front */
947 static const struct ieee80211_wme_info param
= {
948 .wme_id
= IEEE80211_ELEMID_VENDOR
,
949 .wme_len
= sizeof(struct ieee80211_wme_param
) - 2,
950 .wme_oui
= { WME_OUI_BYTES
},
951 .wme_type
= WME_OUI_TYPE
,
952 .wme_subtype
= WME_PARAM_OUI_SUBTYPE
,
953 .wme_version
= WME_VERSION
,
957 memcpy(frm
, ¶m
, sizeof(param
));
958 frm
+= __offsetof(struct ieee80211_wme_info
, wme_info
);
959 *frm
++ = wme
->wme_bssChanParams
.cap_info
; /* AC info */
960 *frm
++ = 0; /* reserved field */
961 for (i
= 0; i
< WME_NUM_AC
; i
++) {
962 const struct wmeParams
*ac
=
963 &wme
->wme_bssChanParams
.cap_wmeParams
[i
];
964 *frm
++ = SM(i
, WME_PARAM_ACI
)
965 | SM(ac
->wmep_acm
, WME_PARAM_ACM
)
966 | SM(ac
->wmep_aifsn
, WME_PARAM_AIFSN
)
968 *frm
++ = SM(ac
->wmep_logcwmax
, WME_PARAM_LOGCWMAX
)
969 | SM(ac
->wmep_logcwmin
, WME_PARAM_LOGCWMIN
)
971 ADDSHORT(frm
, ac
->wmep_txopLimit
);
980 * Send a probe request frame with the specified ssid
981 * and any optional information element data.
984 ieee80211_send_probereq(struct ieee80211_node
*ni
,
985 const uint8_t sa
[IEEE80211_ADDR_LEN
],
986 const uint8_t da
[IEEE80211_ADDR_LEN
],
987 const uint8_t bssid
[IEEE80211_ADDR_LEN
],
988 const uint8_t *ssid
, size_t ssidlen
,
989 const void *optie
, size_t optielen
)
991 struct ieee80211com
*ic
= ni
->ni_ic
;
992 struct ifnet
*ifp
= ic
->ic_ifp
;
993 enum ieee80211_phymode mode
;
994 struct ieee80211_frame
*wh
;
995 struct ieee80211_rateset rs
;
1000 * Hold a reference on the node so it doesn't go away until after
1001 * the xmit is complete all the way in the driver. On error we
1002 * will remove our reference.
1004 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_NODE
,
1005 "ieee80211_ref_node (%s:%u) %p<%6D> refcnt %d\n",
1007 ni
, ni
->ni_macaddr
, ":",
1008 ieee80211_node_refcnt(ni
) + 1);
1009 ieee80211_ref_node(ni
);
1012 * prreq frame format
1014 * [tlv] supported rates
1015 * [tlv] extended supported rates
1016 * [tlv] user-specified ie's
1018 m
= ieee80211_getmgtframe(&frm
,
1019 2 + IEEE80211_NWID_LEN
1020 + 2 + IEEE80211_RATE_SIZE
1021 + 2 + (IEEE80211_RATE_MAXSIZE
- IEEE80211_RATE_SIZE
)
1022 + (optie
!= NULL
? optielen
: 0)
1025 ic
->ic_stats
.is_tx_nobuf
++;
1026 ieee80211_free_node(ni
);
1030 frm
= ieee80211_add_ssid(frm
, ssid
, ssidlen
);
1034 * Clear basic rates.
1036 * Though according to 802.11 standard: MSB of each supported rate
1037 * octet in (Extended) Supported Rates ie of probe requests should
1038 * be ignored, some HostAP implementations still check it ...
1040 mode
= ieee80211_chan2mode(ic
, ic
->ic_curchan
);
1041 rs
= ic
->ic_sup_rates
[mode
];
1042 ieee80211_set_basicrates(&rs
, IEEE80211_MODE_AUTO
, 0);
1043 frm
= ieee80211_add_rates(frm
, &rs
);
1044 frm
= ieee80211_add_xrates(frm
, &rs
);
1046 if (optie
!= NULL
) {
1047 memcpy(frm
, optie
, optielen
);
1050 m
->m_pkthdr
.len
= m
->m_len
= frm
- mtod(m
, uint8_t *);
1052 M_PREPEND(m
, sizeof(struct ieee80211_frame
), MB_DONTWAIT
);
1055 KASSERT(m
->m_pkthdr
.rcvif
== NULL
, ("rcvif not null"));
1056 m
->m_pkthdr
.rcvif
= (void *)ni
;
1058 wh
= mtod(m
, struct ieee80211_frame
*);
1059 ieee80211_send_setup(ic
, ni
, wh
,
1060 IEEE80211_FC0_TYPE_MGT
| IEEE80211_FC0_SUBTYPE_PROBE_REQ
,
1062 /* XXX power management? */
1064 IEEE80211_NODE_STAT(ni
, tx_probereq
);
1065 IEEE80211_NODE_STAT(ni
, tx_mgmt
);
1067 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_DEBUG
| IEEE80211_MSG_DUMPPKTS
,
1068 "[%6D] send probe req on channel %u\n",
1070 ieee80211_chan2ieee(ic
, ic
->ic_curchan
));
1072 IF_ENQUEUE(&ic
->ic_mgtq
, m
);
1078 * Calculate capability information for mgt frames.
1081 getcapinfo(struct ieee80211com
*ic
, struct ieee80211_channel
*chan
)
1085 KASSERT(ic
->ic_opmode
!= IEEE80211_M_STA
, ("station mode"));
1087 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
)
1088 capinfo
= IEEE80211_CAPINFO_ESS
;
1089 else if (ic
->ic_opmode
== IEEE80211_M_IBSS
)
1090 capinfo
= IEEE80211_CAPINFO_IBSS
;
1093 if (ic
->ic_flags
& IEEE80211_F_PRIVACY
)
1094 capinfo
|= IEEE80211_CAPINFO_PRIVACY
;
1095 if (IEEE80211_IS_CHAN_2GHZ(chan
)) {
1096 if (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
)
1097 capinfo
|= IEEE80211_CAPINFO_SHORT_PREAMBLE
;
1098 if (ic
->ic_caps_ext
& IEEE80211_CEXT_PBCC
)
1099 capinfo
|= IEEE80211_CAPINFO_PBCC
;
1101 if (ic
->ic_flags
& IEEE80211_F_SHSLOT
)
1102 capinfo
|= IEEE80211_CAPINFO_SHORT_SLOTTIME
;
1106 static struct mbuf
*
1107 _ieee80211_probe_resp_alloc(struct ieee80211com
*ic
, struct ieee80211_node
*ni
)
1109 const struct ieee80211_rateset
*rs
;
1116 * probe response frame format
1118 * [2] beacon interval
1119 * [2] cabability information
1121 * [tlv] supported rates
1122 * [tlv] parameter set (FH/DS)
1123 * [4] parameter set (IBSS)
1124 * [tlv] extended rate phy (ERP)
1125 * [tlv] extended supported rates
1127 * [tlv] WME (optional)
1129 KKASSERT(ic
->ic_curmode
!= IEEE80211_MODE_AUTO
);
1130 rs
= &ic
->ic_sup_rates
[ic
->ic_curmode
];
1131 pktlen
= 8 /* time stamp */
1132 + sizeof(uint16_t) /* beacon interval */
1133 + sizeof(uint16_t) /* capabilities */
1134 + 2 + ni
->ni_esslen
/* ssid */
1135 + 2 + IEEE80211_RATE_SIZE
/* supported rates */
1136 + 2 + 5 /* max(5,1) */ /* DS/FH parameters */
1137 + 2 + 2 /* IBSS parameters */
1139 + 2 + (IEEE80211_RATE_MAXSIZE
- IEEE80211_RATE_SIZE
)
1140 /* XXX !WPA1+WPA2 fits w/o a cluster */
1141 + (ic
->ic_flags
& IEEE80211_F_WPA
? /* WPA 1+2 */
1142 2*sizeof(struct ieee80211_ie_wpa
) : 0)
1143 + sizeof(struct ieee80211_wme_param
); /* WME */
1145 m
= ieee80211_getmgtframe(&frm
, pktlen
);
1147 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ANY
,
1148 "%s: cannot get buf; size %u\n", __func__
, pktlen
);
1149 ic
->ic_stats
.is_tx_nobuf
++;
1153 memset(frm
, 0, 8); /* timestamp should be filled later */
1155 *(uint16_t *)frm
= htole16(ni
->ni_intval
);
1157 capinfo
= getcapinfo(ic
, ni
->ni_chan
);
1158 *(uint16_t *)frm
= htole16(capinfo
);
1161 frm
= ieee80211_add_ssid(frm
, ni
->ni_essid
, ni
->ni_esslen
);
1162 frm
= ieee80211_add_rates(frm
, rs
);
1164 if (ic
->ic_phytype
== IEEE80211_T_FH
) {
1165 *frm
++ = IEEE80211_ELEMID_FHPARMS
;
1167 *frm
++ = ni
->ni_fhdwell
& 0x00ff;
1168 *frm
++ = (ni
->ni_fhdwell
>> 8) & 0x00ff;
1169 *frm
++ = IEEE80211_FH_CHANSET(
1170 ieee80211_chan2ieee(ic
, ni
->ni_chan
));
1171 *frm
++ = IEEE80211_FH_CHANPAT(
1172 ieee80211_chan2ieee(ic
, ni
->ni_chan
));
1173 *frm
++ = ni
->ni_fhindex
;
1175 *frm
++ = IEEE80211_ELEMID_DSPARMS
;
1177 *frm
++ = ieee80211_chan2ieee(ic
, ni
->ni_chan
);
1180 if (ic
->ic_opmode
== IEEE80211_M_IBSS
) {
1181 *frm
++ = IEEE80211_ELEMID_IBSSPARMS
;
1183 *frm
++ = 0; *frm
++ = 0; /* TODO: ATIM window */
1185 if (ic
->ic_flags
& IEEE80211_F_WPA
)
1186 frm
= ieee80211_add_wpa(frm
, ic
);
1187 if (ic
->ic_curmode
== IEEE80211_MODE_11G
)
1188 frm
= ieee80211_add_erp(frm
, ic
);
1189 frm
= ieee80211_add_xrates(frm
, rs
);
1190 if (ic
->ic_flags
& IEEE80211_F_WME
)
1191 frm
= ieee80211_add_wme_param(frm
, &ic
->ic_wme
);
1192 m
->m_pkthdr
.len
= m
->m_len
= frm
- mtod(m
, uint8_t *);
1193 KKASSERT(m
->m_len
<= pktlen
);
1199 * Send a management frame. The node is for the destination (or ic_bss
1200 * when in station mode). Nodes other than ic_bss have their reference
1201 * count bumped to reflect our use for an indeterminant time.
1204 ieee80211_send_mgmt(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
1207 #define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
1211 int has_challenge
, is_shared_key
, ret
, timer
, status
, encrypt
;
1212 const struct ieee80211_rateset
*rs
;
1214 KASSERT(ni
!= NULL
, ("null node"));
1217 * Hold a reference on the node so it doesn't go away until after
1218 * the xmit is complete all the way in the driver. On error we
1219 * will remove our reference.
1221 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_NODE
,
1222 "ieee80211_ref_node (%s:%u) %p<%6D> refcnt %d\n",
1224 ni
, ni
->ni_macaddr
, ":",
1225 ieee80211_node_refcnt(ni
) + 1);
1226 ieee80211_ref_node(ni
);
1231 case IEEE80211_FC0_SUBTYPE_PROBE_RESP
:
1232 m
= _ieee80211_probe_resp_alloc(ic
, ic
->ic_bss
);
1234 /* NB: Statistics have been updated. */
1240 case IEEE80211_FC0_SUBTYPE_AUTH
:
1243 has_challenge
= ((arg
== IEEE80211_AUTH_SHARED_CHALLENGE
||
1244 arg
== IEEE80211_AUTH_SHARED_RESPONSE
) &&
1245 ni
->ni_challenge
!= NULL
);
1248 * Deduce whether we're doing open authentication or
1249 * shared key authentication. We do the latter if
1250 * we're in the middle of a shared key authentication
1251 * handshake or if we're initiating an authentication
1252 * request and configured to use shared key.
1254 is_shared_key
= has_challenge
||
1255 arg
>= IEEE80211_AUTH_SHARED_RESPONSE
||
1256 (arg
== IEEE80211_AUTH_SHARED_REQUEST
&&
1257 ic
->ic_bss
->ni_authmode
== IEEE80211_AUTH_SHARED
);
1259 m
= ieee80211_getmgtframe(&frm
,
1260 3 * sizeof(uint16_t)
1261 + (has_challenge
&& status
== IEEE80211_STATUS_SUCCESS
?
1262 sizeof(uint16_t)+IEEE80211_CHALLENGE_LEN
: 0)
1265 senderr(ENOMEM
, is_tx_nobuf
);
1267 ((uint16_t *)frm
)[0] =
1268 (is_shared_key
) ? htole16(IEEE80211_AUTH_ALG_SHARED
)
1269 : htole16(IEEE80211_AUTH_ALG_OPEN
);
1270 ((uint16_t *)frm
)[1] = htole16(arg
); /* sequence number */
1271 ((uint16_t *)frm
)[2] = htole16(status
);/* status */
1273 if (has_challenge
&& status
== IEEE80211_STATUS_SUCCESS
) {
1274 ((uint16_t *)frm
)[3] =
1275 htole16((IEEE80211_CHALLENGE_LEN
<< 8) |
1276 IEEE80211_ELEMID_CHALLENGE
);
1277 memcpy(&((uint16_t *)frm
)[4], ni
->ni_challenge
,
1278 IEEE80211_CHALLENGE_LEN
);
1279 m
->m_pkthdr
.len
= m
->m_len
=
1280 4 * sizeof(uint16_t) + IEEE80211_CHALLENGE_LEN
;
1281 if (arg
== IEEE80211_AUTH_SHARED_RESPONSE
) {
1282 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_AUTH
,
1283 "[%6D] request encrypt frame (%s)\n",
1284 ni
->ni_macaddr
, ":", __func__
);
1285 encrypt
= 1; /* WEP-encrypt, please */
1288 m
->m_pkthdr
.len
= m
->m_len
= 3 * sizeof(uint16_t);
1290 /* XXX not right for shared key */
1291 if (status
== IEEE80211_STATUS_SUCCESS
)
1292 IEEE80211_NODE_STAT(ni
, tx_auth
);
1294 IEEE80211_NODE_STAT(ni
, tx_auth_fail
);
1296 if (ic
->ic_opmode
== IEEE80211_M_STA
)
1297 timer
= IEEE80211_TRANS_WAIT
;
1300 case IEEE80211_FC0_SUBTYPE_DEAUTH
:
1301 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_AUTH
,
1302 "[%6D] send station deauthenticate (reason %d)\n",
1303 ni
->ni_macaddr
, ":", arg
);
1304 m
= ieee80211_getmgtframe(&frm
, sizeof(uint16_t));
1306 senderr(ENOMEM
, is_tx_nobuf
);
1307 *(uint16_t *)frm
= htole16(arg
); /* reason */
1308 m
->m_pkthdr
.len
= m
->m_len
= sizeof(uint16_t);
1310 IEEE80211_NODE_STAT(ni
, tx_deauth
);
1311 IEEE80211_NODE_STAT_SET(ni
, tx_deauth_code
, arg
);
1313 ieee80211_node_unauthorize(ni
); /* port closed */
1316 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ
:
1317 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ
:
1319 * asreq frame format
1320 * [2] capability information
1321 * [2] listen interval
1322 * [6*] current AP address (reassoc only)
1324 * [tlv] supported rates
1325 * [tlv] extended supported rates
1327 * [tlv] user-specified ie's
1329 m
= ieee80211_getmgtframe(&frm
,
1332 + IEEE80211_ADDR_LEN
1333 + 2 + IEEE80211_NWID_LEN
1334 + 2 + IEEE80211_RATE_SIZE
1335 + 2 + (IEEE80211_RATE_MAXSIZE
- IEEE80211_RATE_SIZE
)
1336 + sizeof(struct ieee80211_wme_info
)
1337 + (ic
->ic_opt_ie
!= NULL
? ic
->ic_opt_ie_len
: 0)
1340 senderr(ENOMEM
, is_tx_nobuf
);
1342 KASSERT(ic
->ic_opmode
== IEEE80211_M_STA
,
1343 ("wrong mode %u", ic
->ic_opmode
));
1344 capinfo
= IEEE80211_CAPINFO_ESS
;
1345 if (ic
->ic_flags
& IEEE80211_F_PRIVACY
)
1346 capinfo
|= IEEE80211_CAPINFO_PRIVACY
;
1348 * NB: Some 11a AP's reject the request when
1349 * short premable or PBCC modulation is set.
1351 if (IEEE80211_IS_CHAN_2GHZ(ic
->ic_curchan
)) {
1352 if (ic
->ic_caps
& IEEE80211_C_SHPREAMBLE
)
1353 capinfo
|= IEEE80211_CAPINFO_SHORT_PREAMBLE
;
1354 if (ic
->ic_caps_ext
& IEEE80211_CEXT_PBCC
)
1355 capinfo
|= IEEE80211_CAPINFO_PBCC
;
1357 if (IEEE80211_IS_CHAN_2GHZ(ni
->ni_chan
) &&
1358 (ic
->ic_caps
& IEEE80211_C_SHSLOT
))
1359 capinfo
|= IEEE80211_CAPINFO_SHORT_SLOTTIME
;
1360 *(uint16_t *)frm
= htole16(capinfo
);
1363 KKASSERT(ic
->ic_bss
->ni_intval
!= 0);
1364 *(uint16_t *)frm
= htole16(howmany(ic
->ic_lintval
,
1365 ic
->ic_bss
->ni_intval
));
1368 if (type
== IEEE80211_FC0_SUBTYPE_REASSOC_REQ
) {
1369 IEEE80211_ADDR_COPY(frm
, ic
->ic_bss
->ni_bssid
);
1370 frm
+= IEEE80211_ADDR_LEN
;
1373 frm
= ieee80211_add_ssid(frm
, ni
->ni_essid
, ni
->ni_esslen
);
1375 rs
= &ic
->ic_sup_rates
[ieee80211_chan2mode(ic
, ni
->ni_chan
)];
1376 frm
= ieee80211_add_rates(frm
, rs
);
1377 frm
= ieee80211_add_xrates(frm
, rs
);
1379 if ((ic
->ic_flags
& IEEE80211_F_WME
) && ni
->ni_wme_ie
!= NULL
)
1380 frm
= ieee80211_add_wme_info(frm
, &ic
->ic_wme
);
1381 if (ic
->ic_opt_ie
!= NULL
) {
1382 memcpy(frm
, ic
->ic_opt_ie
, ic
->ic_opt_ie_len
);
1383 frm
+= ic
->ic_opt_ie_len
;
1385 m
->m_pkthdr
.len
= m
->m_len
= frm
- mtod(m
, uint8_t *);
1387 timer
= IEEE80211_TRANS_WAIT
;
1390 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP
:
1391 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP
:
1393 * asreq frame format
1394 * [2] capability information
1396 * [2] association ID
1397 * [tlv] supported rates
1398 * [tlv] extended supported rates
1399 * [tlv] WME (if enabled and STA enabled)
1401 m
= ieee80211_getmgtframe(&frm
,
1405 + 2 + IEEE80211_RATE_SIZE
1406 + 2 + (IEEE80211_RATE_MAXSIZE
- IEEE80211_RATE_SIZE
)
1407 + sizeof(struct ieee80211_wme_param
)
1410 senderr(ENOMEM
, is_tx_nobuf
);
1412 capinfo
= getcapinfo(ic
, ic
->ic_curchan
);
1413 *(uint16_t *)frm
= htole16(capinfo
);
1416 *(uint16_t *)frm
= htole16(arg
); /* status */
1419 if (arg
== IEEE80211_STATUS_SUCCESS
) {
1420 *(uint16_t *)frm
= htole16(ni
->ni_associd
);
1421 IEEE80211_NODE_STAT(ni
, tx_assoc
);
1423 IEEE80211_NODE_STAT(ni
, tx_assoc_fail
);
1426 KKASSERT(ic
->ic_curmode
!= IEEE80211_MODE_AUTO
);
1427 rs
= &ic
->ic_sup_rates
[ic
->ic_curmode
];
1428 frm
= ieee80211_add_rates(frm
, rs
);
1429 frm
= ieee80211_add_xrates(frm
, rs
);
1430 if ((ic
->ic_flags
& IEEE80211_F_WME
) && ni
->ni_wme_ie
!= NULL
)
1431 frm
= ieee80211_add_wme_param(frm
, &ic
->ic_wme
);
1432 m
->m_pkthdr
.len
= m
->m_len
= frm
- mtod(m
, uint8_t *);
1435 case IEEE80211_FC0_SUBTYPE_DISASSOC
:
1436 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
1437 "[%6D] send station disassociate (reason %d)\n",
1438 ni
->ni_macaddr
, ":", arg
);
1439 m
= ieee80211_getmgtframe(&frm
, sizeof(uint16_t));
1441 senderr(ENOMEM
, is_tx_nobuf
);
1442 *(uint16_t *)frm
= htole16(arg
); /* reason */
1443 m
->m_pkthdr
.len
= m
->m_len
= sizeof(uint16_t);
1445 IEEE80211_NODE_STAT(ni
, tx_disassoc
);
1446 IEEE80211_NODE_STAT_SET(ni
, tx_disassoc_code
, arg
);
1450 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ANY
,
1451 "[%6D] invalid mgmt frame type %u\n",
1452 ni
->ni_macaddr
, ":", type
);
1453 senderr(EINVAL
, is_tx_unknownmgt
);
1456 ret
= ieee80211_mgmt_output(ic
, ni
, m
, type
, timer
, encrypt
);
1459 ieee80211_free_node(ni
);
1466 * Allocate a probe response frame and fillin the appropriate bits.
1469 ieee80211_probe_resp_alloc(struct ieee80211com
*ic
, struct ieee80211_node
*ni
)
1471 struct ieee80211_frame
*wh
;
1474 m
= _ieee80211_probe_resp_alloc(ic
, ni
);
1478 M_PREPEND(m
, sizeof(struct ieee80211_frame
), MB_DONTWAIT
);
1479 KASSERT(m
!= NULL
, ("no space for 802.11 header?"));
1481 wh
= mtod(m
, struct ieee80211_frame
*);
1482 wh
->i_fc
[0] = IEEE80211_FC0_VERSION_0
| IEEE80211_FC0_TYPE_MGT
|
1483 IEEE80211_FC0_SUBTYPE_PROBE_RESP
;
1484 wh
->i_fc
[1] = IEEE80211_FC1_DIR_NODS
;
1485 *(uint16_t *)wh
->i_dur
= 0;
1486 bzero(wh
->i_addr1
, sizeof(wh
->i_addr1
));
1487 IEEE80211_ADDR_COPY(wh
->i_addr2
, ic
->ic_myaddr
);
1488 IEEE80211_ADDR_COPY(wh
->i_addr3
, ni
->ni_bssid
);
1489 *(uint16_t *)wh
->i_seq
= 0;
1495 * Allocate a beacon frame and fillin the appropriate bits.
1498 ieee80211_beacon_alloc(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
1499 struct ieee80211_beacon_offsets
*bo
)
1501 struct ifnet
*ifp
= ic
->ic_ifp
;
1502 struct ieee80211_frame
*wh
;
1505 uint8_t *frm
, *efrm
;
1507 const struct ieee80211_rateset
*rs
;
1510 * beacon frame format
1512 * [2] beacon interval
1513 * [2] cabability information
1515 * [tlv] supported rates
1516 * [3] parameter set (DS)
1517 * [tlv] parameter set (IBSS/TIM)
1518 * [tlv] extended rate phy (ERP)
1519 * [tlv] extended supported rates
1520 * [tlv] WME parameters
1521 * [tlv] WPA/RSN parameters
1522 * XXX Vendor-specific OIDs (e.g. Atheros)
1523 * NB: we allocate the max space required for the TIM bitmap.
1525 KKASSERT(ic
->ic_curmode
!= IEEE80211_MODE_AUTO
);
1526 rs
= &ic
->ic_sup_rates
[ic
->ic_curmode
];
1527 pktlen
= 8 /* time stamp */
1528 + sizeof(uint16_t) /* beacon interval */
1529 + sizeof(uint16_t) /* capabilities */
1530 + 2 + ni
->ni_esslen
/* ssid */
1531 + 2 + IEEE80211_RATE_SIZE
/* supported rates */
1532 + 2 + 1 /* DS parameters */
1533 + 2 + 4 + ic
->ic_tim_len
/* DTIM/IBSSPARMS */
1535 + 2 + (IEEE80211_RATE_MAXSIZE
- IEEE80211_RATE_SIZE
)
1536 + (ic
->ic_caps
& IEEE80211_C_WME
? /* WME */
1537 sizeof(struct ieee80211_wme_param
) : 0)
1538 + (ic
->ic_caps
& IEEE80211_C_WPA
? /* WPA 1+2 */
1539 2*sizeof(struct ieee80211_ie_wpa
) : 0)
1541 m
= ieee80211_getmgtframe(&frm
, pktlen
);
1543 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ANY
,
1544 "%s: cannot get buf; size %u\n", __func__
, pktlen
);
1545 ic
->ic_stats
.is_tx_nobuf
++;
1549 memset(frm
, 0, 8); /* XXX timestamp is set by hardware/driver */
1551 *(uint16_t *)frm
= htole16(ni
->ni_intval
);
1553 capinfo
= getcapinfo(ic
, ni
->ni_chan
);
1554 bo
->bo_caps
= (uint16_t *)frm
;
1555 *(uint16_t *)frm
= htole16(capinfo
);
1557 *frm
++ = IEEE80211_ELEMID_SSID
;
1558 if ((ic
->ic_flags
& IEEE80211_F_HIDESSID
) == 0) {
1559 *frm
++ = ni
->ni_esslen
;
1560 memcpy(frm
, ni
->ni_essid
, ni
->ni_esslen
);
1561 frm
+= ni
->ni_esslen
;
1564 frm
= ieee80211_add_rates(frm
, rs
);
1565 if (ic
->ic_curmode
!= IEEE80211_MODE_FH
) {
1566 *frm
++ = IEEE80211_ELEMID_DSPARMS
;
1568 *frm
++ = ieee80211_chan2ieee(ic
, ni
->ni_chan
);
1571 if (ic
->ic_opmode
== IEEE80211_M_IBSS
) {
1572 *frm
++ = IEEE80211_ELEMID_IBSSPARMS
;
1574 *frm
++ = 0; *frm
++ = 0; /* TODO: ATIM window */
1576 } else if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) {
1577 struct ieee80211_tim_ie
*tie
= (struct ieee80211_tim_ie
*) frm
;
1579 tie
->tim_ie
= IEEE80211_ELEMID_TIM
;
1580 tie
->tim_len
= 4; /* length */
1581 tie
->tim_count
= 0; /* DTIM count */
1582 tie
->tim_period
= ic
->ic_dtim_period
; /* DTIM period */
1583 tie
->tim_bitctl
= 0; /* bitmap control */
1584 tie
->tim_bitmap
[0] = 0; /* Partial Virtual Bitmap */
1585 frm
+= sizeof(struct ieee80211_tim_ie
);
1588 bo
->bo_trailer
= frm
;
1589 if (ic
->ic_flags
& IEEE80211_F_WME
) {
1591 frm
= ieee80211_add_wme_param(frm
, &ic
->ic_wme
);
1592 ic
->ic_flags
&= ~IEEE80211_F_WMEUPDATE
;
1594 if (ic
->ic_flags
& IEEE80211_F_WPA
)
1595 frm
= ieee80211_add_wpa(frm
, ic
);
1596 if (ic
->ic_curmode
== IEEE80211_MODE_11G
) {
1598 frm
= ieee80211_add_erp(frm
, ic
);
1600 efrm
= ieee80211_add_xrates(frm
, rs
);
1601 bo
->bo_trailer_len
= efrm
- bo
->bo_trailer
;
1602 m
->m_pkthdr
.len
= m
->m_len
= efrm
- mtod(m
, uint8_t *);
1603 KKASSERT(m
->m_len
<= pktlen
);
1605 M_PREPEND(m
, sizeof(struct ieee80211_frame
), MB_DONTWAIT
);
1606 KASSERT(m
!= NULL
, ("no space for 802.11 header?"));
1607 wh
= mtod(m
, struct ieee80211_frame
*);
1608 wh
->i_fc
[0] = IEEE80211_FC0_VERSION_0
| IEEE80211_FC0_TYPE_MGT
|
1609 IEEE80211_FC0_SUBTYPE_BEACON
;
1610 wh
->i_fc
[1] = IEEE80211_FC1_DIR_NODS
;
1611 *(uint16_t *)wh
->i_dur
= 0;
1612 IEEE80211_ADDR_COPY(wh
->i_addr1
, ifp
->if_broadcastaddr
);
1613 IEEE80211_ADDR_COPY(wh
->i_addr2
, ic
->ic_myaddr
);
1614 IEEE80211_ADDR_COPY(wh
->i_addr3
, ni
->ni_bssid
);
1615 *(uint16_t *)wh
->i_seq
= 0;
1621 * Update the dynamic parts of a beacon frame based on the current state.
1624 ieee80211_beacon_update(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
1625 struct ieee80211_beacon_offsets
*bo
, struct mbuf
*m
, int mcast
)
1627 int len_changed
= 0;
1630 ASSERT_SERIALIZED(ic
->ic_ifp
->if_serializer
);
1632 /* XXX faster to recalculate entirely or just changes? */
1633 capinfo
= getcapinfo(ic
, ni
->ni_chan
);
1634 *bo
->bo_caps
= htole16(capinfo
);
1636 if (ic
->ic_flags
& IEEE80211_F_WME
) {
1637 struct ieee80211_wme_state
*wme
= &ic
->ic_wme
;
1640 * Check for agressive mode change. When there is
1641 * significant high priority traffic in the BSS
1642 * throttle back BE traffic by using conservative
1643 * parameters. Otherwise BE uses agressive params
1644 * to optimize performance of legacy/non-QoS traffic.
1646 if (wme
->wme_flags
& WME_F_AGGRMODE
) {
1647 if (wme
->wme_hipri_traffic
>
1648 wme
->wme_hipri_switch_thresh
) {
1649 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_WME
,
1650 "%s: traffic %u, disable aggressive mode\n",
1651 __func__
, wme
->wme_hipri_traffic
);
1652 wme
->wme_flags
&= ~WME_F_AGGRMODE
;
1653 ieee80211_wme_updateparams(ic
);
1654 wme
->wme_hipri_traffic
=
1655 wme
->wme_hipri_switch_hysteresis
;
1657 wme
->wme_hipri_traffic
= 0;
1659 if (wme
->wme_hipri_traffic
<=
1660 wme
->wme_hipri_switch_thresh
) {
1661 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_WME
,
1662 "%s: traffic %u, enable aggressive mode\n",
1663 __func__
, wme
->wme_hipri_traffic
);
1664 wme
->wme_flags
|= WME_F_AGGRMODE
;
1665 ieee80211_wme_updateparams(ic
);
1666 wme
->wme_hipri_traffic
= 0;
1668 wme
->wme_hipri_traffic
=
1669 wme
->wme_hipri_switch_hysteresis
;
1671 if (ic
->ic_flags
& IEEE80211_F_WMEUPDATE
) {
1672 (void) ieee80211_add_wme_param(bo
->bo_wme
, wme
);
1673 ic
->ic_flags
&= ~IEEE80211_F_WMEUPDATE
;
1677 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) { /* NB: no IBSS support*/
1678 struct ieee80211_tim_ie
*tie
=
1679 (struct ieee80211_tim_ie
*) bo
->bo_tim
;
1680 if (ic
->ic_flags
& IEEE80211_F_TIMUPDATE
) {
1681 u_int timlen
, timoff
, i
;
1683 * ATIM/DTIM needs updating. If it fits in the
1684 * current space allocated then just copy in the
1685 * new bits. Otherwise we need to move any trailing
1686 * data to make room. Note that we know there is
1687 * contiguous space because ieee80211_beacon_allocate
1688 * insures there is space in the mbuf to write a
1689 * maximal-size virtual bitmap (based on ic_max_aid).
1692 * Calculate the bitmap size and offset, copy any
1693 * trailer out of the way, and then copy in the
1694 * new bitmap and update the information element.
1695 * Note that the tim bitmap must contain at least
1696 * one byte and any offset must be even.
1698 if (ic
->ic_ps_pending
!= 0) {
1699 timoff
= 128; /* impossibly large */
1700 for (i
= 0; i
< ic
->ic_tim_len
; i
++)
1701 if (ic
->ic_tim_bitmap
[i
]) {
1705 KASSERT(timoff
!= 128, ("tim bitmap empty!"));
1706 for (i
= ic
->ic_tim_len
-1; i
>= timoff
; i
--)
1707 if (ic
->ic_tim_bitmap
[i
])
1709 timlen
= 1 + (i
- timoff
);
1714 if (timlen
!= bo
->bo_tim_len
) {
1715 /* copy up/down trailer */
1716 int adjust
= tie
->tim_bitmap
+timlen
1718 ovbcopy(bo
->bo_trailer
, bo
->bo_trailer
+adjust
,
1719 bo
->bo_trailer_len
);
1720 bo
->bo_trailer
+= adjust
;
1721 bo
->bo_wme
+= adjust
;
1722 bo
->bo_erp
+= adjust
;
1723 bo
->bo_tim_len
= timlen
;
1725 /* update information element */
1726 tie
->tim_len
= 3 + timlen
;
1727 tie
->tim_bitctl
= timoff
;
1730 memcpy(tie
->tim_bitmap
, ic
->ic_tim_bitmap
+ timoff
,
1733 ic
->ic_flags
&= ~IEEE80211_F_TIMUPDATE
;
1735 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
1736 "%s: TIM updated, pending %u, off %u, len %u\n",
1737 __func__
, ic
->ic_ps_pending
, timoff
, timlen
);
1739 /* count down DTIM period */
1740 if (tie
->tim_count
== 0)
1741 tie
->tim_count
= tie
->tim_period
- 1;
1744 /* update state for buffered multicast frames on DTIM */
1745 if (mcast
&& tie
->tim_count
== 0)
1746 tie
->tim_bitctl
|= 1;
1748 tie
->tim_bitctl
&= ~1;
1749 if (ic
->ic_flags_ext
& IEEE80211_FEXT_ERPUPDATE
) {
1751 * ERP element needs updating.
1753 (void) ieee80211_add_erp(bo
->bo_erp
, ic
);
1754 ic
->ic_flags_ext
&= ~IEEE80211_FEXT_ERPUPDATE
;
1762 * Save an outbound packet for a node in power-save sleep state.
1763 * The new packet is placed on the node's saved queue, and the TIM
1764 * is changed, if necessary.
1767 ieee80211_pwrsave(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
1772 ASSERT_SERIALIZED(ic
->ic_ifp
->if_serializer
);
1774 if (IF_QFULL(&ni
->ni_savedq
)) {
1775 IF_DROP(&ni
->ni_savedq
);
1776 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ANY
,
1777 "[%6D] pwr save q overflow, drops %d (size %d)\n",
1778 ni
->ni_macaddr
, ":",
1779 ni
->ni_savedq
.ifq_drops
, IEEE80211_PS_MAX_QUEUE
);
1780 #ifdef IEEE80211_DEBUG
1781 if (ieee80211_msg_dumppkts(ic
))
1782 ieee80211_dump_pkt(mtod(m
, caddr_t
), m
->m_len
, -1, -1);
1788 * Tag the frame with it's expiry time and insert
1789 * it in the queue. The aging interval is 4 times
1790 * the listen interval specified by the station.
1791 * Frames that sit around too long are reclaimed
1792 * using this information.
1794 /* TU -> secs. XXX handle overflow? */
1795 age
= IEEE80211_TU_TO_MS((ni
->ni_intval
* ic
->ic_bintval
) << 2) / 1000;
1796 _IEEE80211_NODE_SAVEQ_ENQUEUE(ni
, m
, qlen
, age
);
1798 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
1799 "[%6D] save frame with age %d, %u now queued\n",
1800 ni
->ni_macaddr
, ":", age
, qlen
);
1803 ic
->ic_set_tim(ni
, 1);
1807 ieee80211_ack_rate(struct ieee80211_node
*ni
, uint8_t rate
)
1809 const struct ieee80211_rateset
*rs
= &ni
->ni_rates
;
1810 uint8_t ack_rate
= 0;
1811 enum ieee80211_modtype modtype
;
1814 rate
&= IEEE80211_RATE_VAL
;
1816 modtype
= ieee80211_rate2modtype(rate
);
1818 for (i
= 0; i
< rs
->rs_nrates
; ++i
) {
1819 uint8_t rate1
= IEEE80211_RS_RATE(rs
, i
);
1828 if ((rs
->rs_rates
[i
] & IEEE80211_RATE_BASIC
) &&
1829 ieee80211_rate2modtype(rate1
) == modtype
)
1863 panic("unsupported rate %d\n", rate
);
1868 /* IEEE Std 802.11a-1999, page 9, table 79 */
1869 #define IEEE80211_OFDM_SYM_TIME 4
1870 #define IEEE80211_OFDM_PREAMBLE_TIME 16
1871 #define IEEE80211_OFDM_SIGNAL_TIME 4
1872 /* IEEE Std 802.11g-2003, page 44 */
1873 #define IEEE80211_OFDM_SIGNAL_EXT_TIME 6
1875 /* IEEE Std 802.11a-1999, page 7, figure 107 */
1876 #define IEEE80211_OFDM_PLCP_SERVICE_NBITS 16
1877 #define IEEE80211_OFDM_TAIL_NBITS 6
1879 #define IEEE80211_OFDM_NBITS(frmlen) \
1880 (IEEE80211_OFDM_PLCP_SERVICE_NBITS + \
1881 ((frmlen) * NBBY) + \
1882 IEEE80211_OFDM_TAIL_NBITS)
1884 #define IEEE80211_OFDM_NBITS_PER_SYM(kbps) \
1885 (((kbps) * IEEE80211_OFDM_SYM_TIME) / 1000)
1887 #define IEEE80211_OFDM_NSYMS(kbps, frmlen) \
1888 howmany(IEEE80211_OFDM_NBITS((frmlen)), \
1889 IEEE80211_OFDM_NBITS_PER_SYM((kbps)))
1891 #define IEEE80211_OFDM_TXTIME(kbps, frmlen) \
1892 (IEEE80211_OFDM_PREAMBLE_TIME + \
1893 IEEE80211_OFDM_SIGNAL_TIME + \
1894 (IEEE80211_OFDM_NSYMS((kbps), (frmlen)) * IEEE80211_OFDM_SYM_TIME))
1896 /* IEEE Std 802.11b-1999, page 28, subclause 18.3.4 */
1897 #define IEEE80211_CCK_PREAMBLE_LEN 144
1898 #define IEEE80211_CCK_PLCP_HDR_TIME 48
1899 #define IEEE80211_CCK_SHPREAMBLE_LEN 72
1900 #define IEEE80211_CCK_SHPLCP_HDR_TIME 24
1902 #define IEEE80211_CCK_NBITS(frmlen) ((frmlen) * NBBY)
1903 #define IEEE80211_CCK_TXTIME(kbps, frmlen) \
1904 (((IEEE80211_CCK_NBITS((frmlen)) * 1000) + (kbps) - 1) / (kbps))
1907 ieee80211_txtime(struct ieee80211_node
*ni
, u_int len
, uint8_t rs_rate
,
1910 struct ieee80211com
*ic
= ni
->ni_ic
;
1911 enum ieee80211_modtype modtype
;
1915 rs_rate
&= IEEE80211_RATE_VAL
;
1917 rate
= rs_rate
* 500; /* ieee80211 rate -> kbps */
1919 modtype
= ieee80211_rate2modtype(rs_rate
);
1920 if (modtype
== IEEE80211_MODTYPE_OFDM
) {
1922 * IEEE Std 802.11a-1999, page 37, equation (29)
1923 * IEEE Std 802.11g-2003, page 44, equation (42)
1925 txtime
= IEEE80211_OFDM_TXTIME(rate
, len
);
1926 if (ic
->ic_curmode
== IEEE80211_MODE_11G
)
1927 txtime
+= IEEE80211_OFDM_SIGNAL_EXT_TIME
;
1930 * IEEE Std 802.11b-1999, page 28, subclause 18.3.4
1931 * IEEE Std 802.11g-2003, page 45, equation (43)
1933 if (modtype
== IEEE80211_MODTYPE_PBCC
)
1935 txtime
= IEEE80211_CCK_TXTIME(rate
, len
);
1938 * Short preamble is not applicable for DS 1Mbits/s
1940 if (rs_rate
!= 2 && (flags
& IEEE80211_F_SHPREAMBLE
)) {
1941 txtime
+= IEEE80211_CCK_SHPREAMBLE_LEN
+
1942 IEEE80211_CCK_SHPLCP_HDR_TIME
;
1944 txtime
+= IEEE80211_CCK_PREAMBLE_LEN
+
1945 IEEE80211_CCK_PLCP_HDR_TIME
;