1 /* $NetBSD: ieee80211_input.c,v 1.67 2008/12/17 20:51:37 cegger Exp $ */
3 * Copyright (c) 2001 Atsushi Onoe
4 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * Alternatively, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") version 2 as published by the Free
20 * Software Foundation.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $");
39 __KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.67 2008/12/17 20:51:37 cegger Exp $");
46 #endif /* __NetBSD__ */
48 #include <sys/param.h>
49 #include <sys/systm.h>
51 #include <sys/malloc.h>
52 #include <sys/endian.h>
53 #include <sys/kernel.h>
55 #include <sys/socket.h>
56 #include <sys/sockio.h>
57 #include <sys/endian.h>
58 #include <sys/errno.h>
60 #include <sys/sysctl.h>
63 #include <net/if_media.h>
64 #include <net/if_arp.h>
65 #include <net/if_ether.h>
66 #include <net/if_llc.h>
68 #include <net80211/ieee80211_netbsd.h>
69 #include <net80211/ieee80211_var.h>
76 #include <netinet/in.h>
77 #include <net/if_ether.h>
80 const struct timeval ieee80211_merge_print_intvl
= {.tv_sec
= 1, .tv_usec
= 0};
82 #ifdef IEEE80211_DEBUG
83 #include <machine/stdarg.h>
86 * Decide if a received management frame should be
87 * printed when debugging is enabled. This filters some
88 * of the less interesting frames that come frequently
92 doprint(struct ieee80211com
*ic
, int subtype
)
95 case IEEE80211_FC0_SUBTYPE_BEACON
:
96 return (ic
->ic_flags
& IEEE80211_F_SCAN
);
97 case IEEE80211_FC0_SUBTYPE_PROBE_REQ
:
98 return (ic
->ic_opmode
== IEEE80211_M_IBSS
);
104 * Emit a debug message about discarding a frame or information
105 * element. One format is for extracting the mac address from
106 * the frame header; the other is for when a header is not
107 * available or otherwise appropriate.
109 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) do { \
110 if ((_ic)->ic_debug & (_m)) \
111 ieee80211_discard_frame(_ic, _wh, _type, _fmt, __VA_ARGS__);\
113 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) do { \
114 if ((_ic)->ic_debug & (_m)) \
115 ieee80211_discard_ie(_ic, _wh, _type, _fmt, __VA_ARGS__);\
117 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) do { \
118 if ((_ic)->ic_debug & (_m)) \
119 ieee80211_discard_mac(_ic, _mac, _type, _fmt, __VA_ARGS__);\
122 static const u_int8_t
*ieee80211_getbssid(struct ieee80211com
*,
123 const struct ieee80211_frame
*);
124 static void ieee80211_discard_frame(struct ieee80211com
*,
125 const struct ieee80211_frame
*, const char *type
, const char *fmt
, ...);
126 static void ieee80211_discard_ie(struct ieee80211com
*,
127 const struct ieee80211_frame
*, const char *type
, const char *fmt
, ...);
128 static void ieee80211_discard_mac(struct ieee80211com
*,
129 const u_int8_t mac
[IEEE80211_ADDR_LEN
], const char *type
,
130 const char *fmt
, ...);
132 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...)
133 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...)
134 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...)
135 #endif /* IEEE80211_DEBUG */
137 static struct mbuf
*ieee80211_defrag(struct ieee80211com
*,
138 struct ieee80211_node
*, struct mbuf
*, int);
139 static struct mbuf
*ieee80211_decap(struct ieee80211com
*, struct mbuf
*, int);
140 static void ieee80211_send_error(struct ieee80211com
*, struct ieee80211_node
*,
141 const u_int8_t
*mac
, int subtype
, int arg
);
142 static void ieee80211_deliver_data(struct ieee80211com
*,
143 struct ieee80211_node
*, struct mbuf
*);
144 #ifndef IEEE80211_NO_HOSTAP
145 static void ieee80211_node_pwrsave(struct ieee80211_node
*, int enable
);
146 static void ieee80211_recv_pspoll(struct ieee80211com
*,
147 struct ieee80211_node
*, struct mbuf
*);
148 #endif /* !IEEE80211_NO_HOSTAP */
149 static void ieee80211_update_adhoc_node(struct ieee80211com
*,
150 struct ieee80211_node
*, struct ieee80211_frame
*,
151 struct ieee80211_scanparams
*, int, u_int32_t
);
154 * Process a received frame. The node associated with the sender
155 * should be supplied. If nothing was found in the node table then
156 * the caller is assumed to supply a reference to ic_bss instead.
157 * The RSSI and a timestamp are also supplied. The RSSI data is used
158 * during AP scanning to select a AP to associate with; it can have
159 * any units so long as values have consistent units and higher values
160 * mean ``better signal''. The receive timestamp is currently not used
161 * by the 802.11 layer.
164 ieee80211_input(struct ieee80211com
*ic
, struct mbuf
*m
,
165 struct ieee80211_node
*ni
, int rssi
, u_int32_t rstamp
)
167 #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
168 #define HAS_SEQ(type) ((type & 0x4) == 0)
169 struct ifnet
*ifp
= ic
->ic_ifp
;
170 struct ieee80211_frame
*wh
;
171 struct ieee80211_key
*key
;
172 struct ether_header
*eh
;
174 u_int8_t dir
, type
, subtype
;
178 IASSERT(ni
!= NULL
, ("null node"));
179 ni
->ni_inact
= ni
->ni_inact_reload
;
181 /* trim CRC here so WEP can find its own CRC at the end of packet. */
182 if (m
->m_flags
& M_HASFCS
) {
183 m_adj(m
, -IEEE80211_CRC_LEN
);
184 m
->m_flags
&= ~M_HASFCS
;
186 type
= -1; /* undefined */
188 * In monitor mode, send everything directly to bpf.
189 * XXX may want to include the CRC
191 if (ic
->ic_opmode
== IEEE80211_M_MONITOR
)
194 if (m
->m_pkthdr
.len
< sizeof(struct ieee80211_frame_min
)) {
195 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_ANY
,
196 ni
->ni_macaddr
, NULL
,
197 "too short (1): len %u", m
->m_pkthdr
.len
);
198 ic
->ic_stats
.is_rx_tooshort
++;
202 * Bit of a cheat here, we use a pointer for a 3-address
203 * frame format but don't reference fields past outside
204 * ieee80211_frame_min w/o first validating the data is
207 wh
= mtod(m
, struct ieee80211_frame
*);
209 if ((wh
->i_fc
[0] & IEEE80211_FC0_VERSION_MASK
) !=
210 IEEE80211_FC0_VERSION_0
) {
211 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_ANY
,
212 ni
->ni_macaddr
, NULL
, "wrong version %x", wh
->i_fc
[0]);
213 ic
->ic_stats
.is_rx_badversion
++;
217 dir
= wh
->i_fc
[1] & IEEE80211_FC1_DIR_MASK
;
218 type
= wh
->i_fc
[0] & IEEE80211_FC0_TYPE_MASK
;
219 subtype
= wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
;
220 if ((ic
->ic_flags
& IEEE80211_F_SCAN
) == 0) {
221 switch (ic
->ic_opmode
) {
222 case IEEE80211_M_STA
:
224 if (!IEEE80211_ADDR_EQ(bssid
, ni
->ni_bssid
)) {
225 /* not interested in */
226 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_INPUT
,
227 bssid
, NULL
, "%s", "not to bss");
228 ic
->ic_stats
.is_rx_wrongbss
++;
232 case IEEE80211_M_IBSS
:
233 case IEEE80211_M_AHDEMO
:
234 case IEEE80211_M_HOSTAP
:
235 if (dir
!= IEEE80211_FC1_DIR_NODS
)
237 else if (type
== IEEE80211_FC0_TYPE_CTL
)
240 if (m
->m_pkthdr
.len
< sizeof(struct ieee80211_frame
)) {
241 IEEE80211_DISCARD_MAC(ic
,
242 IEEE80211_MSG_ANY
, ni
->ni_macaddr
,
243 NULL
, "too short (2): len %u",
245 ic
->ic_stats
.is_rx_tooshort
++;
250 if (type
!= IEEE80211_FC0_TYPE_DATA
)
253 * Data frame, validate the bssid.
255 if (!IEEE80211_ADDR_EQ(bssid
, ic
->ic_bss
->ni_bssid
) &&
256 !IEEE80211_ADDR_EQ(bssid
, ifp
->if_broadcastaddr
)) {
257 /* not interested in */
258 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_INPUT
,
259 bssid
, NULL
, "%s", "not to bss");
260 ic
->ic_stats
.is_rx_wrongbss
++;
264 * For adhoc mode we cons up a node when it doesn't
265 * exist. This should probably done after an ACL check.
267 if (ni
== ic
->ic_bss
&&
268 ic
->ic_opmode
!= IEEE80211_M_HOSTAP
&&
269 !IEEE80211_ADDR_EQ(wh
->i_addr2
, ni
->ni_macaddr
)) {
271 * Fake up a node for this newly
272 * discovered member of the IBSS.
274 ni
= ieee80211_fakeup_adhoc_node(&ic
->ic_sta
,
277 /* NB: stat kept for alloc failure */
286 ni
->ni_rstamp
= rstamp
;
289 if (IEEE80211_QOS_HAS_SEQ(wh
)) {
290 tid
= ((struct ieee80211_qosframe
*)wh
)->
291 i_qos
[0] & IEEE80211_QOS_TID
;
292 if (TID_TO_WME_AC(tid
) >= WME_AC_VI
)
293 ic
->ic_wme
.wme_hipri_traffic
++;
297 rxseq
= le16toh(*(u_int16_t
*)wh
->i_seq
);
298 if ((wh
->i_fc
[1] & IEEE80211_FC1_RETRY
) &&
299 SEQ_LEQ(rxseq
, ni
->ni_rxseqs
[tid
])) {
300 /* duplicate, discard */
301 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_INPUT
,
303 "seqno <%u,%u> fragno <%u,%u> tid %u",
304 rxseq
>> IEEE80211_SEQ_SEQ_SHIFT
,
305 ni
->ni_rxseqs
[tid
] >>
306 IEEE80211_SEQ_SEQ_SHIFT
,
307 rxseq
& IEEE80211_SEQ_FRAG_MASK
,
309 IEEE80211_SEQ_FRAG_MASK
,
311 ic
->ic_stats
.is_rx_dup
++;
312 IEEE80211_NODE_STAT(ni
, rx_dup
);
315 ni
->ni_rxseqs
[tid
] = rxseq
;
320 case IEEE80211_FC0_TYPE_DATA
:
321 hdrspace
= ieee80211_hdrspace(ic
, wh
);
322 if (m
->m_len
< hdrspace
&&
323 (m
= m_pullup(m
, hdrspace
)) == NULL
) {
324 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_ANY
,
325 ni
->ni_macaddr
, NULL
,
326 "data too short: expecting %u", hdrspace
);
327 ic
->ic_stats
.is_rx_tooshort
++;
330 switch (ic
->ic_opmode
) {
331 case IEEE80211_M_STA
:
332 if (dir
!= IEEE80211_FC1_DIR_FROMDS
) {
333 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
334 wh
, "data", "%s", "unknown dir 0x%x", dir
);
335 ic
->ic_stats
.is_rx_wrongdir
++;
338 if ((ifp
->if_flags
& IFF_SIMPLEX
) &&
339 IEEE80211_IS_MULTICAST(wh
->i_addr1
) &&
340 IEEE80211_ADDR_EQ(wh
->i_addr3
, ic
->ic_myaddr
)) {
342 * In IEEE802.11 network, multicast packet
343 * sent from me is broadcasted from AP.
344 * It should be silently discarded for
347 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
348 wh
, NULL
, "%s", "multicast echo");
349 ic
->ic_stats
.is_rx_mcastecho
++;
353 case IEEE80211_M_IBSS
:
354 case IEEE80211_M_AHDEMO
:
355 if (dir
!= IEEE80211_FC1_DIR_NODS
) {
356 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
357 wh
, "data", "%s", "unknown dir 0x%x", dir
);
358 ic
->ic_stats
.is_rx_wrongdir
++;
361 /* XXX no power-save support */
363 case IEEE80211_M_HOSTAP
:
364 #ifndef IEEE80211_NO_HOSTAP
365 if (dir
!= IEEE80211_FC1_DIR_TODS
) {
366 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
367 wh
, "data", "%s", "unknown dir 0x%x", dir
);
368 ic
->ic_stats
.is_rx_wrongdir
++;
371 /* check if source STA is associated */
372 if (ni
== ic
->ic_bss
) {
373 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
374 wh
, "data", "%s", "unknown src");
375 ieee80211_send_error(ic
, ni
, wh
->i_addr2
,
376 IEEE80211_FC0_SUBTYPE_DEAUTH
,
377 IEEE80211_REASON_NOT_AUTHED
);
378 ic
->ic_stats
.is_rx_notassoc
++;
381 if (ni
->ni_associd
== 0) {
382 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
383 wh
, "data", "%s", "unassoc src");
384 IEEE80211_SEND_MGMT(ic
, ni
,
385 IEEE80211_FC0_SUBTYPE_DISASSOC
,
386 IEEE80211_REASON_NOT_ASSOCED
);
387 ic
->ic_stats
.is_rx_notassoc
++;
392 * Check for power save state change.
394 if (((wh
->i_fc
[1] & IEEE80211_FC1_PWR_MGT
) ^
395 (ni
->ni_flags
& IEEE80211_NODE_PWR_MGT
)))
396 ieee80211_node_pwrsave(ni
,
397 wh
->i_fc
[1] & IEEE80211_FC1_PWR_MGT
);
398 #endif /* !IEEE80211_NO_HOSTAP */
401 /* XXX here to keep compiler happy */
406 * Handle privacy requirements. Note that we
407 * must not be preempted from here until after
408 * we (potentially) call ieee80211_crypto_demic;
409 * otherwise we may violate assumptions in the
410 * crypto cipher modules used to do delayed update
411 * of replay sequence numbers.
413 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
414 if ((ic
->ic_flags
& IEEE80211_F_PRIVACY
) == 0) {
416 * Discard encrypted frames when privacy is off.
418 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
419 wh
, "WEP", "%s", "PRIVACY off");
420 ic
->ic_stats
.is_rx_noprivacy
++;
421 IEEE80211_NODE_STAT(ni
, rx_noprivacy
);
424 key
= ieee80211_crypto_decap(ic
, ni
, m
, hdrspace
);
426 /* NB: stats+msgs handled in crypto_decap */
427 IEEE80211_NODE_STAT(ni
, rx_wepfail
);
430 wh
= mtod(m
, struct ieee80211_frame
*);
431 wh
->i_fc
[1] &= ~IEEE80211_FC1_WEP
;
437 * Next up, any fragmentation.
439 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
440 m
= ieee80211_defrag(ic
, ni
, m
, hdrspace
);
442 /* Fragment dropped or frame not complete yet */
446 wh
= NULL
; /* no longer valid, catch any uses */
449 * Next strip any MSDU crypto bits.
451 if (key
!= NULL
&& !ieee80211_crypto_demic(ic
, key
, m
, 0)) {
452 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_INPUT
,
453 ni
->ni_macaddr
, "data", "%s", "demic error");
454 IEEE80211_NODE_STAT(ni
, rx_demicfail
);
459 /* copy to listener after decrypt */
461 bpf_mtap(ic
->ic_rawbpf
, m
);
465 * Finally, strip the 802.11 header.
467 m
= ieee80211_decap(ic
, m
, hdrspace
);
469 /* don't count Null data frames as errors */
470 if (subtype
== IEEE80211_FC0_SUBTYPE_NODATA
)
472 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_INPUT
,
473 ni
->ni_macaddr
, "data", "%s", "decap error");
474 ic
->ic_stats
.is_rx_decap
++;
475 IEEE80211_NODE_STAT(ni
, rx_decap
);
478 eh
= mtod(m
, struct ether_header
*);
479 if (!ieee80211_node_is_authorized(ni
)) {
481 * Deny any non-PAE frames received prior to
482 * authorization. For open/shared-key
483 * authentication the port is mark authorized
484 * after authentication completes. For 802.1x
485 * the port is not marked authorized by the
486 * authenticator until the handshake has completed.
488 if (eh
->ether_type
!= htons(ETHERTYPE_PAE
)) {
489 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_INPUT
,
490 eh
->ether_shost
, "data",
491 "unauthorized port: ether type 0x%x len %u",
492 eh
->ether_type
, m
->m_pkthdr
.len
);
493 ic
->ic_stats
.is_rx_unauth
++;
494 IEEE80211_NODE_STAT(ni
, rx_unauth
);
499 * When denying unencrypted frames, discard
500 * any non-PAE frames received without encryption.
502 if ((ic
->ic_flags
& IEEE80211_F_DROPUNENC
) &&
504 eh
->ether_type
!= htons(ETHERTYPE_PAE
)) {
506 * Drop unencrypted frames.
508 ic
->ic_stats
.is_rx_unencrypted
++;
509 IEEE80211_NODE_STAT(ni
, rx_unencrypted
);
514 IEEE80211_NODE_STAT(ni
, rx_data
);
515 IEEE80211_NODE_STAT_ADD(ni
, rx_bytes
, m
->m_pkthdr
.len
);
517 ieee80211_deliver_data(ic
, ni
, m
);
518 return IEEE80211_FC0_TYPE_DATA
;
520 case IEEE80211_FC0_TYPE_MGT
:
521 IEEE80211_NODE_STAT(ni
, rx_mgmt
);
522 if (dir
!= IEEE80211_FC1_DIR_NODS
) {
523 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
524 wh
, "data", "%s", "unknown dir 0x%x", dir
);
525 ic
->ic_stats
.is_rx_wrongdir
++;
528 if (m
->m_pkthdr
.len
< sizeof(struct ieee80211_frame
)) {
529 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_ANY
,
530 ni
->ni_macaddr
, "mgt", "too short: len %u",
532 ic
->ic_stats
.is_rx_tooshort
++;
535 #ifdef IEEE80211_DEBUG
536 if ((ieee80211_msg_debug(ic
) && doprint(ic
, subtype
)) ||
537 ieee80211_msg_dumppkts(ic
)) {
538 if_printf(ic
->ic_ifp
, "received %s from %s rssi %d\n",
539 ieee80211_mgt_subtype_name
[subtype
>>
540 IEEE80211_FC0_SUBTYPE_SHIFT
],
541 ether_sprintf(wh
->i_addr2
), rssi
);
544 if (wh
->i_fc
[1] & IEEE80211_FC1_WEP
) {
545 if (subtype
!= IEEE80211_FC0_SUBTYPE_AUTH
) {
547 * Only shared key auth frames with a challenge
548 * should be encrypted, discard all others.
550 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
551 wh
, ieee80211_mgt_subtype_name
[subtype
>>
552 IEEE80211_FC0_SUBTYPE_SHIFT
],
553 "%s", "WEP set but not permitted");
554 ic
->ic_stats
.is_rx_mgtdiscard
++; /* XXX */
557 if ((ic
->ic_flags
& IEEE80211_F_PRIVACY
) == 0) {
559 * Discard encrypted frames when privacy is off.
561 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
562 wh
, "mgt", "%s", "WEP set but PRIVACY off");
563 ic
->ic_stats
.is_rx_noprivacy
++;
566 hdrspace
= ieee80211_hdrspace(ic
, wh
);
567 key
= ieee80211_crypto_decap(ic
, ni
, m
, hdrspace
);
569 /* NB: stats+msgs handled in crypto_decap */
572 wh
= mtod(m
, struct ieee80211_frame
*);
573 wh
->i_fc
[1] &= ~IEEE80211_FC1_WEP
;
577 bpf_mtap(ic
->ic_rawbpf
, m
);
579 (*ic
->ic_recv_mgmt
)(ic
, m
, ni
, subtype
, rssi
, rstamp
);
583 case IEEE80211_FC0_TYPE_CTL
:
584 IEEE80211_NODE_STAT(ni
, rx_ctrl
);
585 ic
->ic_stats
.is_rx_ctl
++;
586 #ifndef IEEE80211_NO_HOSTAP
587 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) {
589 case IEEE80211_FC0_SUBTYPE_PS_POLL
:
590 ieee80211_recv_pspoll(ic
, ni
, m
);
594 #endif /* !IEEE80211_NO_HOSTAP */
597 IEEE80211_DISCARD(ic
, IEEE80211_MSG_ANY
,
598 wh
, NULL
, "bad frame type 0x%x", type
);
599 /* should not come here */
608 bpf_mtap(ic
->ic_rawbpf
, m
);
617 * This function reassemble fragments.
620 ieee80211_defrag(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
621 struct mbuf
*m
, int hdrspace
)
623 struct ieee80211_frame
*wh
= mtod(m
, struct ieee80211_frame
*);
624 struct ieee80211_frame
*lwh
;
627 u_int8_t more_frag
= wh
->i_fc
[1] & IEEE80211_FC1_MORE_FRAG
;
630 IASSERT(!IEEE80211_IS_MULTICAST(wh
->i_addr1
), ("multicast fragm?"));
632 rxseq
= le16toh(*(u_int16_t
*)wh
->i_seq
);
633 fragno
= rxseq
& IEEE80211_SEQ_FRAG_MASK
;
635 /* Quick way out, if there's nothing to defragment */
636 if (!more_frag
&& fragno
== 0 && ni
->ni_rxfrag
[0] == NULL
)
640 * Remove frag to insure it doesn't get reaped by timer.
642 if (ni
->ni_table
== NULL
) {
644 * Should never happen. If the node is orphaned (not in
645 * the table) then input packets should not reach here.
646 * Otherwise, a concurrent request that yanks the table
647 * should be blocked by other interlocking and/or by first
648 * shutting the driver down. Regardless, be defensive
651 /* XXX need msg+stat */
655 IEEE80211_NODE_LOCK(ni
->ni_table
);
656 mfrag
= ni
->ni_rxfrag
[0];
657 ni
->ni_rxfrag
[0] = NULL
;
658 IEEE80211_NODE_UNLOCK(ni
->ni_table
);
661 * Validate new fragment is in order and
662 * related to the previous ones.
665 u_int16_t last_rxseq
;
667 lwh
= mtod(mfrag
, struct ieee80211_frame
*);
668 last_rxseq
= le16toh(*(u_int16_t
*)lwh
->i_seq
);
669 /* NB: check seq # and frag together */
670 if (rxseq
!= last_rxseq
+1 ||
671 !IEEE80211_ADDR_EQ(wh
->i_addr1
, lwh
->i_addr1
) ||
672 !IEEE80211_ADDR_EQ(wh
->i_addr2
, lwh
->i_addr2
)) {
674 * Unrelated fragment or no space for it,
675 * clear current fragments.
683 if (fragno
!= 0) { /* !first fragment, discard */
684 IEEE80211_NODE_STAT(ni
, rx_defrag
);
689 } else { /* concatenate */
690 m_adj(m
, hdrspace
); /* strip header */
692 /* NB: m_cat doesn't update the packet header */
693 mfrag
->m_pkthdr
.len
+= m
->m_pkthdr
.len
;
694 /* track last seqnum and fragno */
695 lwh
= mtod(mfrag
, struct ieee80211_frame
*);
696 *(u_int16_t
*) lwh
->i_seq
= *(u_int16_t
*) wh
->i_seq
;
698 if (more_frag
) { /* more to come, save */
699 ni
->ni_rxfragstamp
= ticks
;
700 ni
->ni_rxfrag
[0] = mfrag
;
707 ieee80211_deliver_data(struct ieee80211com
*ic
,
708 struct ieee80211_node
*ni
, struct mbuf
*m
)
710 struct ether_header
*eh
= mtod(m
, struct ether_header
*);
711 struct ifnet
*ifp
= ic
->ic_ifp
;
712 ALTQ_DECL(struct altq_pktattr pktattr
;)
715 /* perform as a bridge within the AP */
716 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
&&
717 (ic
->ic_flags
& IEEE80211_F_NOBRIDGE
) == 0) {
718 struct mbuf
*m1
= NULL
;
720 if (ETHER_IS_MULTICAST(eh
->ether_dhost
)) {
721 m1
= m_copypacket(m
, M_DONTWAIT
);
725 m1
->m_flags
|= M_MCAST
;
728 * Check if the destination is known; if so
729 * and the port is authorized dispatch directly.
731 struct ieee80211_node
*sta
=
732 ieee80211_find_node(&ic
->ic_sta
, eh
->ether_dhost
);
734 if (ieee80211_node_is_authorized(sta
)) {
736 * Beware of sending to ourself; this
737 * needs to happen via the normal
740 if (sta
!= ic
->ic_bss
) {
745 ic
->ic_stats
.is_rx_unauth
++;
746 IEEE80211_NODE_STAT(sta
, rx_unauth
);
748 ieee80211_free_node(sta
);
754 if (ALTQ_IS_ENABLED(&ifp
->if_snd
)) {
755 altq_etherclassify(&ifp
->if_snd
, m1
,
759 len
= m1
->m_pkthdr
.len
;
760 IFQ_ENQUEUE(&ifp
->if_snd
, m1
, &pktattr
, error
);
765 ifp
->if_obytes
+= len
;
771 * XXX If we forward packet into transmitter of the AP,
772 * we don't need to duplicate for DLT_EN10MB.
775 bpf_mtap(ifp
->if_bpf
, m
);
778 if (ni
->ni_vlan
!= 0) {
779 /* attach vlan tag */
781 VLAN_INPUT_TAG(ifp
, m
, ni
->ni_vlan
, goto out
);
783 (*ifp
->if_input
)(ifp
, m
);
790 bpf_mtap(ic
->ic_rawbpf
, m
);
797 ieee80211_decap(struct ieee80211com
*ic
, struct mbuf
*m
, int hdrlen
)
799 struct ieee80211_qosframe_addr4 wh
; /* Max size address frames */
800 struct ether_header
*eh
;
803 if (m
->m_len
< hdrlen
+ sizeof(*llc
) &&
804 (m
= m_pullup(m
, hdrlen
+ sizeof(*llc
))) == NULL
) {
808 memcpy(&wh
, mtod(m
, void *), hdrlen
);
809 llc
= (struct llc
*)(mtod(m
, char *) + hdrlen
);
810 if (llc
->llc_dsap
== LLC_SNAP_LSAP
&& llc
->llc_ssap
== LLC_SNAP_LSAP
&&
811 llc
->llc_control
== LLC_UI
&& llc
->llc_snap
.org_code
[0] == 0 &&
812 llc
->llc_snap
.org_code
[1] == 0 && llc
->llc_snap
.org_code
[2] == 0) {
813 m_adj(m
, hdrlen
+ sizeof(struct llc
) - sizeof(*eh
));
816 m_adj(m
, hdrlen
- sizeof(*eh
));
818 eh
= mtod(m
, struct ether_header
*);
819 switch (wh
.i_fc
[1] & IEEE80211_FC1_DIR_MASK
) {
820 case IEEE80211_FC1_DIR_NODS
:
821 IEEE80211_ADDR_COPY(eh
->ether_dhost
, wh
.i_addr1
);
822 IEEE80211_ADDR_COPY(eh
->ether_shost
, wh
.i_addr2
);
824 case IEEE80211_FC1_DIR_TODS
:
825 IEEE80211_ADDR_COPY(eh
->ether_dhost
, wh
.i_addr3
);
826 IEEE80211_ADDR_COPY(eh
->ether_shost
, wh
.i_addr2
);
828 case IEEE80211_FC1_DIR_FROMDS
:
829 IEEE80211_ADDR_COPY(eh
->ether_dhost
, wh
.i_addr1
);
830 IEEE80211_ADDR_COPY(eh
->ether_shost
, wh
.i_addr3
);
832 case IEEE80211_FC1_DIR_DSTODS
:
833 IEEE80211_ADDR_COPY(eh
->ether_dhost
, wh
.i_addr3
);
834 IEEE80211_ADDR_COPY(eh
->ether_shost
, wh
.i_addr4
);
837 #ifdef ALIGNED_POINTER
838 if (!ALIGNED_POINTER(mtod(m
, char *) + sizeof(*eh
), u_int32_t
)) {
839 struct mbuf
*n
, *n0
, **np
;
846 pktlen
= m
->m_pkthdr
.len
;
847 while (pktlen
> off
) {
849 MGETHDR(n
, M_DONTWAIT
, MT_DATA
);
857 MGET(n
, M_DONTWAIT
, MT_DATA
);
865 if (pktlen
- off
>= MINCLSIZE
) {
866 MCLGET(n
, M_DONTWAIT
);
867 if (n
->m_flags
& M_EXT
)
868 n
->m_len
= n
->m_ext
.ext_size
;
872 (char *)ALIGN(n
->m_data
+ sizeof(*eh
)) -
874 n
->m_len
-= newdata
- n
->m_data
;
877 if (n
->m_len
> pktlen
- off
)
878 n
->m_len
= pktlen
- off
;
879 m_copydata(m
, off
, n
->m_len
, mtod(n
, void *));
887 #endif /* ALIGNED_POINTER */
889 eh
= mtod(m
, struct ether_header
*);
890 eh
->ether_type
= htons(m
->m_pkthdr
.len
- sizeof(*eh
));
896 * Install received rate set information in the node's state block.
899 ieee80211_setup_rates(struct ieee80211_node
*ni
,
900 const u_int8_t
*rates
, const u_int8_t
*xrates
, int flags
)
902 struct ieee80211com
*ic
= ni
->ni_ic
;
903 struct ieee80211_rateset
*rs
= &ni
->ni_rates
;
905 memset(rs
, 0, sizeof(*rs
));
906 rs
->rs_nrates
= rates
[1];
907 memcpy(rs
->rs_rates
, rates
+ 2, rs
->rs_nrates
);
908 if (xrates
!= NULL
) {
911 * Tack on 11g extended supported rate element.
914 if (rs
->rs_nrates
+ nxrates
> IEEE80211_RATE_MAXSIZE
) {
915 nxrates
= IEEE80211_RATE_MAXSIZE
- rs
->rs_nrates
;
916 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_XRATE
,
917 "[%s] extended rate set too large;"
918 " only using %u of %u rates\n",
919 ether_sprintf(ni
->ni_macaddr
), nxrates
, xrates
[1]);
920 ic
->ic_stats
.is_rx_rstoobig
++;
922 memcpy(rs
->rs_rates
+ rs
->rs_nrates
, xrates
+2, nxrates
);
923 rs
->rs_nrates
+= nxrates
;
925 return ieee80211_fix_rate(ni
, flags
);
929 ieee80211_auth_open(struct ieee80211com
*ic
, struct ieee80211_frame
*wh
,
930 struct ieee80211_node
*ni
, int rssi
, u_int32_t rstamp
,
931 u_int16_t seq
, u_int16_t status
)
934 if (ni
->ni_authmode
== IEEE80211_AUTH_SHARED
) {
935 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
936 ni
->ni_macaddr
, "open auth",
937 "bad sta auth mode %u", ni
->ni_authmode
);
938 ic
->ic_stats
.is_rx_bad_auth
++; /* XXX */
939 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) {
940 /* XXX hack to workaround calling convention */
941 ieee80211_send_error(ic
, ni
, wh
->i_addr2
,
942 IEEE80211_FC0_SUBTYPE_AUTH
,
943 (seq
+ 1) | (IEEE80211_STATUS_ALG
<<16));
947 switch (ic
->ic_opmode
) {
948 case IEEE80211_M_IBSS
:
949 case IEEE80211_M_AHDEMO
:
950 case IEEE80211_M_MONITOR
:
951 /* should not come here */
952 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
953 ni
->ni_macaddr
, "open auth",
954 "bad operating mode %u", ic
->ic_opmode
);
957 case IEEE80211_M_HOSTAP
:
958 #ifndef IEEE80211_NO_HOSTAP
959 if (ic
->ic_state
!= IEEE80211_S_RUN
||
960 seq
!= IEEE80211_AUTH_OPEN_REQUEST
) {
961 ic
->ic_stats
.is_rx_bad_auth
++;
964 /* always accept open authentication requests */
965 if (ni
== ic
->ic_bss
) {
966 ni
= ieee80211_dup_bss(&ic
->ic_sta
, wh
->i_addr2
);
969 } else if ((ni
->ni_flags
& IEEE80211_NODE_AREF
) == 0)
970 (void) ieee80211_ref_node(ni
);
972 * Mark the node as referenced to reflect that it's
973 * reference count has been bumped to insure it remains
974 * after the transaction completes.
976 ni
->ni_flags
|= IEEE80211_NODE_AREF
;
978 IEEE80211_SEND_MGMT(ic
, ni
,
979 IEEE80211_FC0_SUBTYPE_AUTH
, seq
+ 1);
980 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_DEBUG
| IEEE80211_MSG_AUTH
,
981 "[%s] station authenticated (open)\n",
982 ether_sprintf(ni
->ni_macaddr
));
984 * When 802.1x is not in use mark the port
985 * authorized at this point so traffic can flow.
987 if (ni
->ni_authmode
!= IEEE80211_AUTH_8021X
)
988 ieee80211_node_authorize(ni
);
989 #endif /* !IEEE80211_NO_HOSTAP */
992 case IEEE80211_M_STA
:
993 if (ic
->ic_state
!= IEEE80211_S_AUTH
||
994 seq
!= IEEE80211_AUTH_OPEN_RESPONSE
) {
995 ic
->ic_stats
.is_rx_bad_auth
++;
999 IEEE80211_DPRINTF(ic
,
1000 IEEE80211_MSG_DEBUG
| IEEE80211_MSG_AUTH
,
1001 "[%s] open auth failed (reason %d)\n",
1002 ether_sprintf(ni
->ni_macaddr
), status
);
1003 /* XXX can this happen? */
1004 if (ni
!= ic
->ic_bss
)
1006 ic
->ic_stats
.is_rx_auth_fail
++;
1007 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, 0);
1009 ieee80211_new_state(ic
, IEEE80211_S_ASSOC
,
1010 wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
);
1016 * Send a management frame error response to the specified
1017 * station. If ni is associated with the station then use
1018 * it; otherwise allocate a temporary node suitable for
1019 * transmitting the frame and then free the reference so
1020 * it will go away as soon as the frame has been transmitted.
1023 ieee80211_send_error(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
1024 const u_int8_t
*mac
, int subtype
, int arg
)
1028 if (ni
== ic
->ic_bss
) {
1029 ni
= ieee80211_tmp_node(ic
, mac
);
1037 IEEE80211_SEND_MGMT(ic
, ni
, subtype
, arg
);
1039 ieee80211_free_node(ni
);
1043 alloc_challenge(struct ieee80211com
*ic
, struct ieee80211_node
*ni
)
1045 if (ni
->ni_challenge
== NULL
)
1046 ni
->ni_challenge
= malloc(IEEE80211_CHALLENGE_LEN
,
1047 M_DEVBUF
, M_NOWAIT
);
1048 if (ni
->ni_challenge
== NULL
) {
1049 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_DEBUG
| IEEE80211_MSG_AUTH
,
1050 "[%s] shared key challenge alloc failed\n",
1051 ether_sprintf(ni
->ni_macaddr
));
1054 return (ni
->ni_challenge
!= NULL
);
1057 /* XXX TODO: add statistics */
1059 ieee80211_auth_shared(struct ieee80211com
*ic
, struct ieee80211_frame
*wh
,
1060 u_int8_t
*frm
, u_int8_t
*efrm
, struct ieee80211_node
*ni
, int rssi
,
1061 u_int32_t rstamp
, u_int16_t seq
, u_int16_t status
)
1063 u_int8_t
*challenge
;
1067 * NB: this can happen as we allow pre-shared key
1068 * authentication to be enabled w/o wep being turned
1069 * on so that configuration of these can be done
1070 * in any order. It may be better to enforce the
1071 * ordering in which case this check would just be
1072 * for sanity/consistency.
1074 if ((ic
->ic_flags
& IEEE80211_F_PRIVACY
) == 0) {
1075 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1076 ni
->ni_macaddr
, "shared key auth",
1077 "%s", " PRIVACY is disabled");
1078 estatus
= IEEE80211_STATUS_ALG
;
1082 * Pre-shared key authentication is evil; accept
1083 * it only if explicitly configured (it is supported
1084 * mainly for compatibility with clients like OS X).
1086 if (ni
->ni_authmode
!= IEEE80211_AUTH_AUTO
&&
1087 ni
->ni_authmode
!= IEEE80211_AUTH_SHARED
) {
1088 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1089 ni
->ni_macaddr
, "shared key auth",
1090 "bad sta auth mode %u", ni
->ni_authmode
);
1091 ic
->ic_stats
.is_rx_bad_auth
++; /* XXX maybe a unique error? */
1092 estatus
= IEEE80211_STATUS_ALG
;
1097 if (frm
+ 1 < efrm
) {
1098 if ((frm
[1] + 2) > (efrm
- frm
)) {
1099 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1100 ni
->ni_macaddr
, "shared key auth",
1101 "ie %d/%d too long",
1102 frm
[0], (frm
[1] + 2) - (efrm
- frm
));
1103 ic
->ic_stats
.is_rx_bad_auth
++;
1104 estatus
= IEEE80211_STATUS_CHALLENGE
;
1107 if (*frm
== IEEE80211_ELEMID_CHALLENGE
)
1112 case IEEE80211_AUTH_SHARED_CHALLENGE
:
1113 case IEEE80211_AUTH_SHARED_RESPONSE
:
1114 if (challenge
== NULL
) {
1115 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1116 ni
->ni_macaddr
, "shared key auth",
1117 "%s", "no challenge");
1118 ic
->ic_stats
.is_rx_bad_auth
++;
1119 estatus
= IEEE80211_STATUS_CHALLENGE
;
1122 if (challenge
[1] != IEEE80211_CHALLENGE_LEN
) {
1123 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1124 ni
->ni_macaddr
, "shared key auth",
1125 "bad challenge len %d", challenge
[1]);
1126 ic
->ic_stats
.is_rx_bad_auth
++;
1127 estatus
= IEEE80211_STATUS_CHALLENGE
;
1133 switch (ic
->ic_opmode
) {
1134 case IEEE80211_M_MONITOR
:
1135 case IEEE80211_M_AHDEMO
:
1136 case IEEE80211_M_IBSS
:
1137 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1138 ni
->ni_macaddr
, "shared key auth",
1139 "bad operating mode %u", ic
->ic_opmode
);
1141 case IEEE80211_M_HOSTAP
:
1142 #ifndef IEEE80211_NO_HOSTAP
1145 if (ic
->ic_state
!= IEEE80211_S_RUN
) {
1146 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1147 ni
->ni_macaddr
, "shared key auth",
1148 "bad state %u", ic
->ic_state
);
1149 estatus
= IEEE80211_STATUS_ALG
; /* XXX */
1153 case IEEE80211_AUTH_SHARED_REQUEST
:
1154 if (ni
== ic
->ic_bss
) {
1155 ni
= ieee80211_dup_bss(&ic
->ic_sta
, wh
->i_addr2
);
1157 /* NB: no way to return an error */
1162 if ((ni
->ni_flags
& IEEE80211_NODE_AREF
) == 0)
1163 (void) ieee80211_ref_node(ni
);
1167 * Mark the node as referenced to reflect that it's
1168 * reference count has been bumped to insure it remains
1169 * after the transaction completes.
1171 ni
->ni_flags
|= IEEE80211_NODE_AREF
;
1173 ni
->ni_rstamp
= rstamp
;
1174 if (!alloc_challenge(ic
, ni
)) {
1175 /* NB: don't return error so they rexmit */
1178 get_random_bytes(ni
->ni_challenge
,
1179 IEEE80211_CHALLENGE_LEN
);
1180 IEEE80211_DPRINTF(ic
,
1181 IEEE80211_MSG_DEBUG
| IEEE80211_MSG_AUTH
,
1182 "[%s] shared key %sauth request\n",
1183 ether_sprintf(ni
->ni_macaddr
),
1184 allocbs
? "" : "re");
1186 case IEEE80211_AUTH_SHARED_RESPONSE
:
1187 if (ni
== ic
->ic_bss
) {
1188 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1189 ni
->ni_macaddr
, "shared key response",
1190 "%s", "unknown station");
1191 /* NB: don't send a response */
1194 if (ni
->ni_challenge
== NULL
) {
1195 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1196 ni
->ni_macaddr
, "shared key response",
1197 "%s", "no challenge recorded");
1198 ic
->ic_stats
.is_rx_bad_auth
++;
1199 estatus
= IEEE80211_STATUS_CHALLENGE
;
1202 if (memcmp(ni
->ni_challenge
, &challenge
[2],
1203 challenge
[1]) != 0) {
1204 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1205 ni
->ni_macaddr
, "shared key response",
1206 "%s", "challenge mismatch");
1207 ic
->ic_stats
.is_rx_auth_fail
++;
1208 estatus
= IEEE80211_STATUS_CHALLENGE
;
1211 IEEE80211_DPRINTF(ic
,
1212 IEEE80211_MSG_DEBUG
| IEEE80211_MSG_AUTH
,
1213 "[%s] station authenticated (shared key)\n",
1214 ether_sprintf(ni
->ni_macaddr
));
1215 ieee80211_node_authorize(ni
);
1218 IEEE80211_DISCARD_MAC(ic
, IEEE80211_MSG_AUTH
,
1219 ni
->ni_macaddr
, "shared key auth",
1221 ic
->ic_stats
.is_rx_bad_auth
++;
1222 estatus
= IEEE80211_STATUS_SEQUENCE
;
1225 IEEE80211_SEND_MGMT(ic
, ni
,
1226 IEEE80211_FC0_SUBTYPE_AUTH
, seq
+ 1);
1228 #endif /* !IEEE80211_NO_HOSTAP */
1231 case IEEE80211_M_STA
:
1232 if (ic
->ic_state
!= IEEE80211_S_AUTH
)
1235 case IEEE80211_AUTH_SHARED_PASS
:
1236 if (ni
->ni_challenge
!= NULL
) {
1237 free(ni
->ni_challenge
, M_DEVBUF
);
1238 ni
->ni_challenge
= NULL
;
1241 IEEE80211_DPRINTF(ic
,
1242 IEEE80211_MSG_DEBUG
| IEEE80211_MSG_AUTH
,
1243 "[%s] shared key auth failed (reason %d)\n",
1244 ether_sprintf(ieee80211_getbssid(ic
, wh
)),
1246 /* XXX can this happen? */
1247 if (ni
!= ic
->ic_bss
)
1249 ic
->ic_stats
.is_rx_auth_fail
++;
1252 ieee80211_new_state(ic
, IEEE80211_S_ASSOC
,
1253 wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
);
1255 case IEEE80211_AUTH_SHARED_CHALLENGE
:
1256 if (!alloc_challenge(ic
, ni
))
1258 /* XXX could optimize by passing recvd challenge */
1259 memcpy(ni
->ni_challenge
, &challenge
[2], challenge
[1]);
1260 IEEE80211_SEND_MGMT(ic
, ni
,
1261 IEEE80211_FC0_SUBTYPE_AUTH
, seq
+ 1);
1264 IEEE80211_DISCARD(ic
, IEEE80211_MSG_AUTH
,
1265 wh
, "shared key auth", "bad seq %d", seq
);
1266 ic
->ic_stats
.is_rx_bad_auth
++;
1273 #ifndef IEEE80211_NO_HOSTAP
1275 * Send an error response; but only when operating as an AP.
1277 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) {
1278 /* XXX hack to workaround calling convention */
1279 ieee80211_send_error(ic
, ni
, wh
->i_addr2
,
1280 IEEE80211_FC0_SUBTYPE_AUTH
,
1281 (seq
+ 1) | (estatus
<<16));
1282 } else if (ic
->ic_opmode
== IEEE80211_M_STA
) {
1284 * Kick the state machine. This short-circuits
1285 * using the mgt frame timeout to trigger the
1288 if (ic
->ic_state
== IEEE80211_S_AUTH
)
1289 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, 0);
1293 #endif /* !IEEE80211_NO_HOSTAP */
1296 /* Verify the existence and length of __elem or get out. */
1297 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
1298 if ((__elem) == NULL) { \
1299 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1300 wh, ieee80211_mgt_subtype_name[subtype >> \
1301 IEEE80211_FC0_SUBTYPE_SHIFT], \
1302 "%s", "no " #__elem ); \
1303 ic->ic_stats.is_rx_elem_missing++; \
1306 if ((__elem)[1] > (__maxlen)) { \
1307 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1308 wh, ieee80211_mgt_subtype_name[subtype >> \
1309 IEEE80211_FC0_SUBTYPE_SHIFT], \
1310 "bad " #__elem " len %d", (__elem)[1]); \
1311 ic->ic_stats.is_rx_elem_toobig++; \
1316 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
1317 if ((_len) < (_minlen)) { \
1318 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1319 wh, ieee80211_mgt_subtype_name[subtype >> \
1320 IEEE80211_FC0_SUBTYPE_SHIFT], \
1321 "%s", "ie too short"); \
1322 ic->ic_stats.is_rx_elem_toosmall++; \
1327 #ifdef IEEE80211_DEBUG
1329 ieee80211_ssid_mismatch(struct ieee80211com
*ic
, const char *tag
,
1330 u_int8_t mac
[IEEE80211_ADDR_LEN
], u_int8_t
*ssid
)
1332 printf("[%s] discard %s frame, ssid mismatch: ",
1333 ether_sprintf(mac
), tag
);
1334 ieee80211_print_essid(ssid
+ 2, ssid
[1]);
1338 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1339 if ((_ssid)[1] != 0 && \
1340 ((_ssid)[1] != (_ni)->ni_esslen || \
1341 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1342 if (ieee80211_msg_input(ic)) \
1343 ieee80211_ssid_mismatch(ic, \
1344 ieee80211_mgt_subtype_name[subtype >> \
1345 IEEE80211_FC0_SUBTYPE_SHIFT], \
1346 wh->i_addr2, _ssid); \
1347 ic->ic_stats.is_rx_ssidmismatch++; \
1351 #else /* !IEEE80211_DEBUG */
1352 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1353 if ((_ssid)[1] != 0 && \
1354 ((_ssid)[1] != (_ni)->ni_esslen || \
1355 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1356 ic->ic_stats.is_rx_ssidmismatch++; \
1360 #endif /* !IEEE80211_DEBUG */
1362 /* unalligned little endian access */
1363 #define LE_READ_2(p) \
1365 ((((const u_int8_t *)(p))[0] ) | \
1366 (((const u_int8_t *)(p))[1] << 8)))
1367 #define LE_READ_4(p) \
1369 ((((const u_int8_t *)(p))[0] ) | \
1370 (((const u_int8_t *)(p))[1] << 8) | \
1371 (((const u_int8_t *)(p))[2] << 16) | \
1372 (((const u_int8_t *)(p))[3] << 24)))
1375 iswpaoui(const u_int8_t
*frm
)
1377 return frm
[1] > 3 && LE_READ_4(frm
+2) == ((WPA_OUI_TYPE
<<24)|WPA_OUI
);
1381 iswmeoui(const u_int8_t
*frm
)
1383 return frm
[1] > 3 && LE_READ_4(frm
+2) == ((WME_OUI_TYPE
<<24)|WME_OUI
);
1387 iswmeparam(const u_int8_t
*frm
)
1389 return frm
[1] > 5 && LE_READ_4(frm
+2) == ((WME_OUI_TYPE
<<24)|WME_OUI
) &&
1390 frm
[6] == WME_PARAM_OUI_SUBTYPE
;
1394 iswmeinfo(const u_int8_t
*frm
)
1396 return frm
[1] > 5 && LE_READ_4(frm
+2) == ((WME_OUI_TYPE
<<24)|WME_OUI
) &&
1397 frm
[6] == WME_INFO_OUI_SUBTYPE
;
1401 isatherosoui(const u_int8_t
*frm
)
1403 return frm
[1] > 3 && LE_READ_4(frm
+2) == ((ATH_OUI_TYPE
<<24)|ATH_OUI
);
1407 * Convert a WPA cipher selector OUI to an internal
1408 * cipher algorithm. Where appropriate we also
1409 * record any key length.
1412 wpa_cipher(u_int8_t
*sel
, u_int8_t
*keylen
)
1414 #define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1415 u_int32_t w
= LE_READ_4(sel
);
1418 case WPA_SEL(WPA_CSE_NULL
):
1419 return IEEE80211_CIPHER_NONE
;
1420 case WPA_SEL(WPA_CSE_WEP40
):
1422 *keylen
= 40 / NBBY
;
1423 return IEEE80211_CIPHER_WEP
;
1424 case WPA_SEL(WPA_CSE_WEP104
):
1426 *keylen
= 104 / NBBY
;
1427 return IEEE80211_CIPHER_WEP
;
1428 case WPA_SEL(WPA_CSE_TKIP
):
1429 return IEEE80211_CIPHER_TKIP
;
1430 case WPA_SEL(WPA_CSE_CCMP
):
1431 return IEEE80211_CIPHER_AES_CCM
;
1433 return 32; /* NB: so 1<< is discarded */
1438 * Convert a WPA key management/authentication algorithm
1439 * to an internal code.
1442 wpa_keymgmt(u_int8_t
*sel
)
1444 #define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1445 u_int32_t w
= LE_READ_4(sel
);
1448 case WPA_SEL(WPA_ASE_8021X_UNSPEC
):
1449 return WPA_ASE_8021X_UNSPEC
;
1450 case WPA_SEL(WPA_ASE_8021X_PSK
):
1451 return WPA_ASE_8021X_PSK
;
1452 case WPA_SEL(WPA_ASE_NONE
):
1453 return WPA_ASE_NONE
;
1455 return 0; /* NB: so is discarded */
1460 * Parse a WPA information element to collect parameters
1461 * and validate the parameters against what has been
1462 * configured for the system.
1465 ieee80211_parse_wpa(struct ieee80211com
*ic
, u_int8_t
*frm
,
1466 struct ieee80211_rsnparms
*rsn
, const struct ieee80211_frame
*wh
)
1468 u_int8_t len
= frm
[1];
1473 * Check the length once for fixed parts: OUI, type,
1474 * version, mcast cipher, and 2 selector counts.
1475 * Other, variable-length data, must be checked separately.
1477 if ((ic
->ic_flags
& IEEE80211_F_WPA1
) == 0) {
1478 IEEE80211_DISCARD_IE(ic
,
1479 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1480 wh
, "WPA", "not WPA, flags 0x%x", ic
->ic_flags
);
1481 return IEEE80211_REASON_IE_INVALID
;
1484 IEEE80211_DISCARD_IE(ic
,
1485 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1486 wh
, "WPA", "too short, len %u", len
);
1487 return IEEE80211_REASON_IE_INVALID
;
1489 frm
+= 6, len
-= 4; /* NB: len is payload only */
1490 /* NB: iswapoui already validated the OUI and type */
1492 if (w
!= WPA_VERSION
) {
1493 IEEE80211_DISCARD_IE(ic
,
1494 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1495 wh
, "WPA", "bad version %u", w
);
1496 return IEEE80211_REASON_IE_INVALID
;
1500 /* multicast/group cipher */
1501 w
= wpa_cipher(frm
, &rsn
->rsn_mcastkeylen
);
1502 if (w
!= rsn
->rsn_mcastcipher
) {
1503 IEEE80211_DISCARD_IE(ic
,
1504 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1505 wh
, "WPA", "mcast cipher mismatch; got %u, expected %u",
1506 w
, rsn
->rsn_mcastcipher
);
1507 return IEEE80211_REASON_IE_INVALID
;
1511 /* unicast ciphers */
1515 IEEE80211_DISCARD_IE(ic
,
1516 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1517 wh
, "WPA", "ucast cipher data too short; len %u, n %u",
1519 return IEEE80211_REASON_IE_INVALID
;
1522 for (; n
> 0; n
--) {
1523 w
|= 1<<wpa_cipher(frm
, &rsn
->rsn_ucastkeylen
);
1526 w
&= rsn
->rsn_ucastcipherset
;
1528 IEEE80211_DISCARD_IE(ic
,
1529 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1530 wh
, "WPA", "%s", "ucast cipher set empty");
1531 return IEEE80211_REASON_IE_INVALID
;
1533 if (w
& (1<<IEEE80211_CIPHER_TKIP
))
1534 rsn
->rsn_ucastcipher
= IEEE80211_CIPHER_TKIP
;
1536 rsn
->rsn_ucastcipher
= IEEE80211_CIPHER_AES_CCM
;
1538 /* key management algorithms */
1542 IEEE80211_DISCARD_IE(ic
,
1543 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1544 wh
, "WPA", "key mgmt alg data too short; len %u, n %u",
1546 return IEEE80211_REASON_IE_INVALID
;
1549 for (; n
> 0; n
--) {
1550 w
|= wpa_keymgmt(frm
);
1553 w
&= rsn
->rsn_keymgmtset
;
1555 IEEE80211_DISCARD_IE(ic
,
1556 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1557 wh
, "WPA", "%s", "no acceptable key mgmt alg");
1558 return IEEE80211_REASON_IE_INVALID
;
1560 if (w
& WPA_ASE_8021X_UNSPEC
)
1561 rsn
->rsn_keymgmt
= WPA_ASE_8021X_UNSPEC
;
1563 rsn
->rsn_keymgmt
= WPA_ASE_8021X_PSK
;
1565 if (len
> 2) /* optional capabilities */
1566 rsn
->rsn_caps
= LE_READ_2(frm
);
1572 * Convert an RSN cipher selector OUI to an internal
1573 * cipher algorithm. Where appropriate we also
1574 * record any key length.
1577 rsn_cipher(u_int8_t
*sel
, u_int8_t
*keylen
)
1579 #define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1580 u_int32_t w
= LE_READ_4(sel
);
1583 case RSN_SEL(RSN_CSE_NULL
):
1584 return IEEE80211_CIPHER_NONE
;
1585 case RSN_SEL(RSN_CSE_WEP40
):
1587 *keylen
= 40 / NBBY
;
1588 return IEEE80211_CIPHER_WEP
;
1589 case RSN_SEL(RSN_CSE_WEP104
):
1591 *keylen
= 104 / NBBY
;
1592 return IEEE80211_CIPHER_WEP
;
1593 case RSN_SEL(RSN_CSE_TKIP
):
1594 return IEEE80211_CIPHER_TKIP
;
1595 case RSN_SEL(RSN_CSE_CCMP
):
1596 return IEEE80211_CIPHER_AES_CCM
;
1597 case RSN_SEL(RSN_CSE_WRAP
):
1598 return IEEE80211_CIPHER_AES_OCB
;
1600 return 32; /* NB: so 1<< is discarded */
1605 * Convert an RSN key management/authentication algorithm
1606 * to an internal code.
1609 rsn_keymgmt(u_int8_t
*sel
)
1611 #define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1612 u_int32_t w
= LE_READ_4(sel
);
1615 case RSN_SEL(RSN_ASE_8021X_UNSPEC
):
1616 return RSN_ASE_8021X_UNSPEC
;
1617 case RSN_SEL(RSN_ASE_8021X_PSK
):
1618 return RSN_ASE_8021X_PSK
;
1619 case RSN_SEL(RSN_ASE_NONE
):
1620 return RSN_ASE_NONE
;
1622 return 0; /* NB: so is discarded */
1627 * Parse a WPA/RSN information element to collect parameters
1628 * and validate the parameters against what has been
1629 * configured for the system.
1632 ieee80211_parse_rsn(struct ieee80211com
*ic
, u_int8_t
*frm
,
1633 struct ieee80211_rsnparms
*rsn
, const struct ieee80211_frame
*wh
)
1635 u_int8_t len
= frm
[1];
1640 * Check the length once for fixed parts:
1641 * version, mcast cipher, and 2 selector counts.
1642 * Other, variable-length data, must be checked separately.
1644 if ((ic
->ic_flags
& IEEE80211_F_WPA2
) == 0) {
1645 IEEE80211_DISCARD_IE(ic
,
1646 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1647 wh
, "WPA", "not RSN, flags 0x%x", ic
->ic_flags
);
1648 return IEEE80211_REASON_IE_INVALID
;
1651 IEEE80211_DISCARD_IE(ic
,
1652 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1653 wh
, "RSN", "too short, len %u", len
);
1654 return IEEE80211_REASON_IE_INVALID
;
1658 if (w
!= RSN_VERSION
) {
1659 IEEE80211_DISCARD_IE(ic
,
1660 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1661 wh
, "RSN", "bad version %u", w
);
1662 return IEEE80211_REASON_IE_INVALID
;
1666 /* multicast/group cipher */
1667 w
= rsn_cipher(frm
, &rsn
->rsn_mcastkeylen
);
1668 if (w
!= rsn
->rsn_mcastcipher
) {
1669 IEEE80211_DISCARD_IE(ic
,
1670 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1671 wh
, "RSN", "mcast cipher mismatch; got %u, expected %u",
1672 w
, rsn
->rsn_mcastcipher
);
1673 return IEEE80211_REASON_IE_INVALID
;
1677 /* unicast ciphers */
1681 IEEE80211_DISCARD_IE(ic
,
1682 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1683 wh
, "RSN", "ucast cipher data too short; len %u, n %u",
1685 return IEEE80211_REASON_IE_INVALID
;
1688 for (; n
> 0; n
--) {
1689 w
|= 1<<rsn_cipher(frm
, &rsn
->rsn_ucastkeylen
);
1692 w
&= rsn
->rsn_ucastcipherset
;
1694 IEEE80211_DISCARD_IE(ic
,
1695 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1696 wh
, "RSN", "%s", "ucast cipher set empty");
1697 return IEEE80211_REASON_IE_INVALID
;
1699 if (w
& (1<<IEEE80211_CIPHER_TKIP
))
1700 rsn
->rsn_ucastcipher
= IEEE80211_CIPHER_TKIP
;
1702 rsn
->rsn_ucastcipher
= IEEE80211_CIPHER_AES_CCM
;
1704 /* key management algorithms */
1708 IEEE80211_DISCARD_IE(ic
,
1709 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1710 wh
, "RSN", "key mgmt alg data too short; len %u, n %u",
1712 return IEEE80211_REASON_IE_INVALID
;
1715 for (; n
> 0; n
--) {
1716 w
|= rsn_keymgmt(frm
);
1719 w
&= rsn
->rsn_keymgmtset
;
1721 IEEE80211_DISCARD_IE(ic
,
1722 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WPA
,
1723 wh
, "RSN", "%s", "no acceptable key mgmt alg");
1724 return IEEE80211_REASON_IE_INVALID
;
1726 if (w
& RSN_ASE_8021X_UNSPEC
)
1727 rsn
->rsn_keymgmt
= RSN_ASE_8021X_UNSPEC
;
1729 rsn
->rsn_keymgmt
= RSN_ASE_8021X_PSK
;
1731 /* optional RSN capabilities */
1733 rsn
->rsn_caps
= LE_READ_2(frm
);
1740 ieee80211_parse_wmeparams(struct ieee80211com
*ic
, u_int8_t
*frm
,
1741 const struct ieee80211_frame
*wh
)
1743 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
1744 struct ieee80211_wme_state
*wme
= &ic
->ic_wme
;
1745 u_int len
= frm
[1], qosinfo
;
1748 if (len
< sizeof(struct ieee80211_wme_param
)-2) {
1749 IEEE80211_DISCARD_IE(ic
,
1750 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_WME
,
1751 wh
, "WME", "too short, len %u", len
);
1754 qosinfo
= frm
[__offsetof(struct ieee80211_wme_param
, param_qosInfo
)];
1755 qosinfo
&= WME_QOSINFO_COUNT
;
1756 /* XXX do proper check for wraparound */
1757 if (qosinfo
== wme
->wme_wmeChanParams
.cap_info
)
1759 frm
+= __offsetof(struct ieee80211_wme_param
, params_acParams
);
1760 for (i
= 0; i
< WME_NUM_AC
; i
++) {
1761 struct wmeParams
*wmep
=
1762 &wme
->wme_wmeChanParams
.cap_wmeParams
[i
];
1763 /* NB: ACI not used */
1764 wmep
->wmep_acm
= MS(frm
[0], WME_PARAM_ACM
);
1765 wmep
->wmep_aifsn
= MS(frm
[0], WME_PARAM_AIFSN
);
1766 wmep
->wmep_logcwmin
= MS(frm
[1], WME_PARAM_LOGCWMIN
);
1767 wmep
->wmep_logcwmax
= MS(frm
[1], WME_PARAM_LOGCWMAX
);
1768 wmep
->wmep_txopLimit
= LE_READ_2(frm
+2);
1771 wme
->wme_wmeChanParams
.cap_info
= qosinfo
;
1777 ieee80211_saveie(u_int8_t
**iep
, const u_int8_t
*ie
)
1779 u_int ielen
= ie
[1]+2;
1781 * Record information element for later use.
1783 if (*iep
== NULL
|| (*iep
)[1] != ie
[1]) {
1785 free(*iep
, M_DEVBUF
);
1786 *iep
= malloc(ielen
, M_DEVBUF
, M_NOWAIT
);
1789 memcpy(*iep
, ie
, ielen
);
1790 /* XXX note failure */
1794 ieee80211_update_adhoc_node(struct ieee80211com
*ic
, struct ieee80211_node
*ni
,
1795 struct ieee80211_frame
*wh
, struct ieee80211_scanparams
*scan
, int rssi
,
1798 if (!IEEE80211_ADDR_EQ(wh
->i_addr2
, ni
->ni_macaddr
)) {
1800 * Create a new entry in the neighbor table.
1803 if ((ni
= ieee80211_add_neighbor(ic
, wh
, scan
)) == NULL
)
1805 } else if (ni
->ni_capinfo
== 0) {
1807 * Initialize a node that was "faked up." Records
1810 * No need to check for a change of BSSID: ni could
1811 * not have been the IBSS (ic_bss)
1813 ieee80211_init_neighbor(ic
, ni
, wh
, scan
, 0);
1815 /* Record TSF for potential resync. */
1816 memcpy(ni
->ni_tstamp
.data
, scan
->tstamp
, sizeof(ni
->ni_tstamp
));
1820 ni
->ni_rstamp
= rstamp
;
1822 /* Mark a neighbor's change of BSSID. */
1823 if (IEEE80211_ADDR_EQ(wh
->i_addr3
, ni
->ni_bssid
))
1826 IEEE80211_ADDR_COPY(ni
->ni_bssid
, wh
->i_addr3
);
1828 if (ni
!= ic
->ic_bss
)
1830 else if (ic
->ic_flags
& IEEE80211_F_DESBSSID
) {
1832 * Now, ni does not represent a network we
1833 * want to belong to, so start a scan.
1835 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, 0);
1839 * A RUN->RUN transition lets the driver
1840 * reprogram its BSSID filter.
1842 * No need to SCAN, we already belong to
1843 * an IBSS that meets our criteria: channel,
1844 * SSID, etc. It could be harmful to scan,
1845 * too: if a scan does not detect nodes
1846 * belonging to my current IBSS, then we
1847 * will create a new IBSS at the end of
1848 * the scan, needlessly splitting the
1851 ieee80211_new_state(ic
, IEEE80211_S_RUN
, 0);
1856 ieee80211_recv_mgmt(struct ieee80211com
*ic
, struct mbuf
*m0
,
1857 struct ieee80211_node
*ni
,
1858 int subtype
, int rssi
, u_int32_t rstamp
)
1860 #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1861 #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
1862 struct ieee80211_frame
*wh
;
1863 u_int8_t
*frm
, *efrm
;
1864 u_int8_t
*ssid
, *rates
, *xrates
, *wpa
, *wme
;
1865 int reassoc
, resp
, allocbs
;
1868 wh
= mtod(m0
, struct ieee80211_frame
*);
1869 frm
= (u_int8_t
*)&wh
[1];
1870 efrm
= mtod(m0
, u_int8_t
*) + m0
->m_len
;
1872 case IEEE80211_FC0_SUBTYPE_PROBE_RESP
:
1873 case IEEE80211_FC0_SUBTYPE_BEACON
: {
1874 struct ieee80211_scanparams scan
;
1877 * We process beacon/probe response frames:
1878 * o when scanning, or
1879 * o station mode when associated (to collect state
1880 * updates such as 802.11g slot time), or
1881 * o adhoc mode (to discover neighbors)
1882 * Frames otherwise received are discarded.
1884 if (!((ic
->ic_flags
& IEEE80211_F_SCAN
) ||
1885 (ic
->ic_opmode
== IEEE80211_M_STA
&& ni
->ni_associd
) ||
1886 ic
->ic_opmode
== IEEE80211_M_IBSS
)) {
1887 ic
->ic_stats
.is_rx_mgtdiscard
++;
1891 * beacon/probe response frame format
1893 * [2] beacon interval
1894 * [2] capability information
1896 * [tlv] supported rates
1897 * [tlv] country information
1898 * [tlv] parameter set (FH/DS)
1899 * [tlv] erp information
1900 * [tlv] extended supported rates
1904 IEEE80211_VERIFY_LENGTH(efrm
- frm
, 12);
1905 memset(&scan
, 0, sizeof(scan
));
1906 scan
.tstamp
= frm
; frm
+= 8;
1907 scan
.bintval
= le16toh(*(u_int16_t
*)frm
); frm
+= 2;
1908 scan
.capinfo
= le16toh(*(u_int16_t
*)frm
); frm
+= 2;
1909 scan
.bchan
= ieee80211_chan2ieee(ic
, ic
->ic_curchan
);
1910 scan
.chan
= scan
.bchan
;
1912 while (frm
< efrm
) {
1914 case IEEE80211_ELEMID_SSID
:
1917 case IEEE80211_ELEMID_RATES
:
1920 case IEEE80211_ELEMID_COUNTRY
:
1923 case IEEE80211_ELEMID_FHPARMS
:
1924 if (ic
->ic_phytype
== IEEE80211_T_FH
) {
1925 scan
.fhdwell
= LE_READ_2(&frm
[2]);
1926 scan
.chan
= IEEE80211_FH_CHAN(frm
[4], frm
[5]);
1927 scan
.fhindex
= frm
[6];
1930 case IEEE80211_ELEMID_DSPARMS
:
1932 * XXX hack this since depending on phytype
1933 * is problematic for multi-mode devices.
1935 if (ic
->ic_phytype
!= IEEE80211_T_FH
)
1938 case IEEE80211_ELEMID_TIM
:
1941 scan
.timoff
= frm
- mtod(m0
, u_int8_t
*);
1943 case IEEE80211_ELEMID_IBSSPARMS
:
1945 case IEEE80211_ELEMID_XRATES
:
1948 case IEEE80211_ELEMID_ERP
:
1950 IEEE80211_DISCARD_IE(ic
,
1951 IEEE80211_MSG_ELEMID
, wh
, "ERP",
1952 "bad len %u", frm
[1]);
1953 ic
->ic_stats
.is_rx_elem_toobig
++;
1958 case IEEE80211_ELEMID_RSN
:
1961 case IEEE80211_ELEMID_VENDOR
:
1964 else if (iswmeparam(frm
) || iswmeinfo(frm
))
1966 /* XXX Atheros OUI support */
1969 IEEE80211_DISCARD_IE(ic
, IEEE80211_MSG_ELEMID
,
1971 "id %u, len %u", *frm
, frm
[1]);
1972 ic
->ic_stats
.is_rx_elem_unknown
++;
1977 IEEE80211_VERIFY_ELEMENT(scan
.rates
, IEEE80211_RATE_MAXSIZE
);
1978 IEEE80211_VERIFY_ELEMENT(scan
.ssid
, IEEE80211_NWID_LEN
);
1980 #if IEEE80211_CHAN_MAX < 255
1981 scan
.chan
> IEEE80211_CHAN_MAX
||
1983 isclr(ic
->ic_chan_active
, scan
.chan
)) {
1984 IEEE80211_DISCARD(ic
,
1985 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_INPUT
,
1986 wh
, ieee80211_mgt_subtype_name
[subtype
>>
1987 IEEE80211_FC0_SUBTYPE_SHIFT
],
1988 "invalid channel %u", scan
.chan
);
1989 ic
->ic_stats
.is_rx_badchan
++;
1992 if (scan
.chan
!= scan
.bchan
&&
1993 ic
->ic_phytype
!= IEEE80211_T_FH
) {
1995 * Frame was received on a channel different from the
1996 * one indicated in the DS params element id;
1997 * silently discard it.
1999 * NB: this can happen due to signal leakage.
2000 * But we should take it for FH phy because
2001 * the rssi value should be correct even for
2002 * different hop pattern in FH.
2004 IEEE80211_DISCARD(ic
,
2005 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_INPUT
,
2006 wh
, ieee80211_mgt_subtype_name
[subtype
>>
2007 IEEE80211_FC0_SUBTYPE_SHIFT
],
2008 "for off-channel %u", scan
.chan
);
2009 ic
->ic_stats
.is_rx_chanmismatch
++;
2012 if (!(IEEE80211_BINTVAL_MIN
<= scan
.bintval
&&
2013 scan
.bintval
<= IEEE80211_BINTVAL_MAX
)) {
2014 IEEE80211_DISCARD(ic
,
2015 IEEE80211_MSG_ELEMID
| IEEE80211_MSG_INPUT
,
2016 wh
, ieee80211_mgt_subtype_name
[subtype
>>
2017 IEEE80211_FC0_SUBTYPE_SHIFT
],
2018 "bogus beacon interval", scan
.bintval
);
2019 ic
->ic_stats
.is_rx_badbintval
++;
2023 if (ni
!= ic
->ic_bss
) {
2024 ni
= ieee80211_refine_node_for_beacon(ic
, ni
,
2025 &ic
->ic_channels
[scan
.chan
], scan
.ssid
);
2028 * Count frame now that we know it's to be processed.
2030 if (subtype
== IEEE80211_FC0_SUBTYPE_BEACON
) {
2031 ic
->ic_stats
.is_rx_beacon
++; /* XXX remove */
2032 IEEE80211_NODE_STAT(ni
, rx_beacons
);
2034 IEEE80211_NODE_STAT(ni
, rx_proberesp
);
2037 * When operating in station mode, check for state updates.
2038 * Be careful to ignore beacons received while doing a
2039 * background scan. We consider only 11g/WMM stuff right now.
2041 if (ic
->ic_opmode
== IEEE80211_M_STA
&&
2042 ni
->ni_associd
!= 0 &&
2043 ((ic
->ic_flags
& IEEE80211_F_SCAN
) == 0 ||
2044 IEEE80211_ADDR_EQ(wh
->i_addr2
, ni
->ni_bssid
))) {
2045 /* record tsf of last beacon */
2046 memcpy(ni
->ni_tstamp
.data
, scan
.tstamp
,
2047 sizeof(ni
->ni_tstamp
));
2048 if (ni
->ni_erp
!= scan
.erp
) {
2049 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
2050 "[%s] erp change: was 0x%x, now 0x%x\n",
2051 ether_sprintf(wh
->i_addr2
),
2052 ni
->ni_erp
, scan
.erp
);
2053 if (ic
->ic_curmode
== IEEE80211_MODE_11G
&&
2054 (ni
->ni_erp
& IEEE80211_ERP_USE_PROTECTION
))
2055 ic
->ic_flags
|= IEEE80211_F_USEPROT
;
2057 ic
->ic_flags
&= ~IEEE80211_F_USEPROT
;
2058 ni
->ni_erp
= scan
.erp
;
2061 if ((ni
->ni_capinfo
^ scan
.capinfo
) & IEEE80211_CAPINFO_SHORT_SLOTTIME
) {
2062 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
2063 "[%s] capabilities change: before 0x%x,"
2065 ether_sprintf(wh
->i_addr2
),
2066 ni
->ni_capinfo
, scan
.capinfo
);
2068 * NB: we assume short preamble doesn't
2069 * change dynamically
2071 ieee80211_set_shortslottime(ic
,
2072 ic
->ic_curmode
== IEEE80211_MODE_11A
||
2073 (ni
->ni_capinfo
& IEEE80211_CAPINFO_SHORT_SLOTTIME
));
2074 ni
->ni_capinfo
= scan
.capinfo
;
2077 if (scan
.wme
!= NULL
&&
2078 (ni
->ni_flags
& IEEE80211_NODE_QOS
) &&
2079 ieee80211_parse_wmeparams(ic
, scan
.wme
, wh
) > 0)
2080 ieee80211_wme_updateparams(ic
);
2081 if (scan
.tim
!= NULL
) {
2082 struct ieee80211_tim_ie
*ie
=
2083 (struct ieee80211_tim_ie
*) scan
.tim
;
2085 ni
->ni_dtim_count
= ie
->tim_count
;
2086 ni
->ni_dtim_period
= ie
->tim_period
;
2088 if (ic
->ic_flags
& IEEE80211_F_SCAN
)
2089 ieee80211_add_scan(ic
, &scan
, wh
,
2090 subtype
, rssi
, rstamp
);
2091 ic
->ic_bmiss_count
= 0;
2095 * If scanning, just pass information to the scan module.
2097 if (ic
->ic_flags
& IEEE80211_F_SCAN
) {
2098 if (ic
->ic_flags_ext
& IEEE80211_FEXT_PROBECHAN
) {
2100 * Actively scanning a channel marked passive;
2101 * send a probe request now that we know there
2102 * is 802.11 traffic present.
2104 * XXX check if the beacon we recv'd gives
2105 * us what we need and suppress the probe req
2107 ieee80211_probe_curchan(ic
, 1);
2108 ic
->ic_flags_ext
&= ~IEEE80211_FEXT_PROBECHAN
;
2110 ieee80211_add_scan(ic
, &scan
, wh
,
2111 subtype
, rssi
, rstamp
);
2114 if (scan
.capinfo
& IEEE80211_CAPINFO_IBSS
)
2115 ieee80211_update_adhoc_node(ic
, ni
, wh
, &scan
, rssi
,
2120 case IEEE80211_FC0_SUBTYPE_PROBE_REQ
:
2121 if (ic
->ic_opmode
== IEEE80211_M_STA
||
2122 ic
->ic_state
!= IEEE80211_S_RUN
) {
2123 ic
->ic_stats
.is_rx_mgtdiscard
++;
2126 if (IEEE80211_IS_MULTICAST(wh
->i_addr2
)) {
2127 /* frame must be directed */
2128 ic
->ic_stats
.is_rx_mgtdiscard
++; /* XXX stat */
2133 * prreq frame format
2135 * [tlv] supported rates
2136 * [tlv] extended supported rates
2138 ssid
= rates
= xrates
= NULL
;
2139 while (frm
< efrm
) {
2141 case IEEE80211_ELEMID_SSID
:
2144 case IEEE80211_ELEMID_RATES
:
2147 case IEEE80211_ELEMID_XRATES
:
2153 IEEE80211_VERIFY_ELEMENT(rates
, IEEE80211_RATE_MAXSIZE
);
2154 IEEE80211_VERIFY_ELEMENT(ssid
, IEEE80211_NWID_LEN
);
2155 IEEE80211_VERIFY_SSID(ic
->ic_bss
, ssid
);
2156 if ((ic
->ic_flags
& IEEE80211_F_HIDESSID
) && ssid
[1] == 0) {
2157 IEEE80211_DISCARD(ic
, IEEE80211_MSG_INPUT
,
2158 wh
, ieee80211_mgt_subtype_name
[subtype
>>
2159 IEEE80211_FC0_SUBTYPE_SHIFT
],
2160 "%s", "no ssid with ssid suppression enabled");
2161 ic
->ic_stats
.is_rx_ssidmismatch
++; /*XXX*/
2165 if (ni
== ic
->ic_bss
) {
2166 if (ic
->ic_opmode
!= IEEE80211_M_IBSS
)
2167 ni
= ieee80211_tmp_node(ic
, wh
->i_addr2
);
2168 else if (IEEE80211_ADDR_EQ(wh
->i_addr2
, ni
->ni_macaddr
))
2172 * XXX Cannot tell if the sender is operating
2173 * in ibss mode. But we need a new node to
2174 * send the response so blindly add them to the
2177 ni
= ieee80211_fakeup_adhoc_node(&ic
->ic_sta
,
2185 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
2186 "[%s] recv probe req\n", ether_sprintf(wh
->i_addr2
));
2188 ni
->ni_rstamp
= rstamp
;
2189 rate
= ieee80211_setup_rates(ni
, rates
, xrates
,
2190 IEEE80211_F_DOSORT
| IEEE80211_F_DOFRATE
2191 | IEEE80211_F_DONEGO
| IEEE80211_F_DODEL
);
2192 if (rate
& IEEE80211_RATE_BASIC
) {
2193 IEEE80211_DISCARD(ic
, IEEE80211_MSG_XRATE
,
2194 wh
, ieee80211_mgt_subtype_name
[subtype
>>
2195 IEEE80211_FC0_SUBTYPE_SHIFT
],
2196 "%s", "recv'd rate set invalid");
2198 IEEE80211_SEND_MGMT(ic
, ni
,
2199 IEEE80211_FC0_SUBTYPE_PROBE_RESP
, 0);
2201 if (allocbs
&& ic
->ic_opmode
!= IEEE80211_M_IBSS
) {
2202 /* reclaim immediately */
2203 ieee80211_free_node(ni
);
2207 case IEEE80211_FC0_SUBTYPE_AUTH
: {
2208 u_int16_t algo
, seq
, status
;
2216 IEEE80211_VERIFY_LENGTH(efrm
- frm
, 6);
2217 algo
= le16toh(*(u_int16_t
*)frm
);
2218 seq
= le16toh(*(u_int16_t
*)(frm
+ 2));
2219 status
= le16toh(*(u_int16_t
*)(frm
+ 4));
2220 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_AUTH
,
2221 "[%s] recv auth frame with algorithm %d seq %d\n",
2222 ether_sprintf(wh
->i_addr2
), algo
, seq
);
2224 * Consult the ACL policy module if setup.
2226 if (ic
->ic_acl
!= NULL
&&
2227 !ic
->ic_acl
->iac_check(ic
, wh
->i_addr2
)) {
2228 IEEE80211_DISCARD(ic
, IEEE80211_MSG_ACL
,
2229 wh
, "auth", "%s", "disallowed by ACL");
2230 ic
->ic_stats
.is_rx_acl
++;
2231 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) {
2232 IEEE80211_SEND_MGMT(ic
, ni
,
2233 IEEE80211_FC0_SUBTYPE_AUTH
,
2234 (seq
+1) | (IEEE80211_STATUS_UNSPECIFIED
<<16));
2238 if (ic
->ic_flags
& IEEE80211_F_COUNTERM
) {
2239 IEEE80211_DISCARD(ic
,
2240 IEEE80211_MSG_AUTH
| IEEE80211_MSG_CRYPTO
,
2241 wh
, "auth", "%s", "TKIP countermeasures enabled");
2242 ic
->ic_stats
.is_rx_auth_countermeasures
++;
2243 #ifndef IEEE80211_NO_HOSTAP
2244 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) {
2245 IEEE80211_SEND_MGMT(ic
, ni
,
2246 IEEE80211_FC0_SUBTYPE_AUTH
,
2247 IEEE80211_REASON_MIC_FAILURE
);
2249 #endif /* !IEEE80211_NO_HOSTAP */
2252 if (algo
== IEEE80211_AUTH_ALG_SHARED
)
2253 ieee80211_auth_shared(ic
, wh
, frm
+ 6, efrm
, ni
, rssi
,
2254 rstamp
, seq
, status
);
2255 else if (algo
== IEEE80211_AUTH_ALG_OPEN
)
2256 ieee80211_auth_open(ic
, wh
, ni
, rssi
, rstamp
, seq
,
2259 IEEE80211_DISCARD(ic
, IEEE80211_MSG_ANY
,
2260 wh
, "auth", "unsupported alg %d", algo
);
2261 ic
->ic_stats
.is_rx_auth_unsupported
++;
2262 #ifndef IEEE80211_NO_HOSTAP
2263 if (ic
->ic_opmode
== IEEE80211_M_HOSTAP
) {
2265 IEEE80211_SEND_MGMT(ic
, ni
,
2266 IEEE80211_FC0_SUBTYPE_AUTH
,
2267 (seq
+1) | (IEEE80211_STATUS_ALG
<<16));
2269 #endif /* !IEEE80211_NO_HOSTAP */
2275 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ
:
2276 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ
: {
2277 u_int16_t capinfo
, lintval
;
2278 struct ieee80211_rsnparms rsn
;
2281 if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
||
2282 ic
->ic_state
!= IEEE80211_S_RUN
) {
2283 ic
->ic_stats
.is_rx_mgtdiscard
++;
2287 if (subtype
== IEEE80211_FC0_SUBTYPE_REASSOC_REQ
) {
2289 resp
= IEEE80211_FC0_SUBTYPE_REASSOC_RESP
;
2292 resp
= IEEE80211_FC0_SUBTYPE_ASSOC_RESP
;
2295 * asreq frame format
2296 * [2] capability information
2297 * [2] listen interval
2298 * [6*] current AP address (reassoc only)
2300 * [tlv] supported rates
2301 * [tlv] extended supported rates
2304 IEEE80211_VERIFY_LENGTH(efrm
- frm
, (reassoc
? 10 : 4));
2305 if (!IEEE80211_ADDR_EQ(wh
->i_addr3
, ic
->ic_bss
->ni_bssid
)) {
2306 IEEE80211_DISCARD(ic
, IEEE80211_MSG_ANY
,
2307 wh
, ieee80211_mgt_subtype_name
[subtype
>>
2308 IEEE80211_FC0_SUBTYPE_SHIFT
],
2309 "%s", "wrong bssid");
2310 ic
->ic_stats
.is_rx_assoc_bss
++;
2313 capinfo
= le16toh(*(u_int16_t
*)frm
); frm
+= 2;
2314 lintval
= le16toh(*(u_int16_t
*)frm
); frm
+= 2;
2316 frm
+= 6; /* ignore current AP info */
2317 ssid
= rates
= xrates
= wpa
= wme
= NULL
;
2318 while (frm
< efrm
) {
2320 case IEEE80211_ELEMID_SSID
:
2323 case IEEE80211_ELEMID_RATES
:
2326 case IEEE80211_ELEMID_XRATES
:
2329 /* XXX verify only one of RSN and WPA ie's? */
2330 case IEEE80211_ELEMID_RSN
:
2333 case IEEE80211_ELEMID_VENDOR
:
2336 else if (iswmeinfo(frm
))
2338 /* XXX Atheros OUI support */
2343 IEEE80211_VERIFY_ELEMENT(rates
, IEEE80211_RATE_MAXSIZE
);
2344 IEEE80211_VERIFY_ELEMENT(ssid
, IEEE80211_NWID_LEN
);
2345 IEEE80211_VERIFY_SSID(ic
->ic_bss
, ssid
);
2347 if (ni
== ic
->ic_bss
) {
2348 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ANY
,
2349 "[%s] deny %s request, sta not authenticated\n",
2350 ether_sprintf(wh
->i_addr2
),
2351 reassoc
? "reassoc" : "assoc");
2352 ieee80211_send_error(ic
, ni
, wh
->i_addr2
,
2353 IEEE80211_FC0_SUBTYPE_DEAUTH
,
2354 IEEE80211_REASON_ASSOC_NOT_AUTHED
);
2355 ic
->ic_stats
.is_rx_assoc_notauth
++;
2358 /* assert right associstion security credentials */
2359 if (wpa
== NULL
&& (ic
->ic_flags
& IEEE80211_F_WPA
)) {
2360 IEEE80211_DPRINTF(ic
,
2361 IEEE80211_MSG_ASSOC
| IEEE80211_MSG_WPA
,
2362 "[%s] no WPA/RSN IE in association request\n",
2363 ether_sprintf(wh
->i_addr2
));
2364 IEEE80211_SEND_MGMT(ic
, ni
,
2365 IEEE80211_FC0_SUBTYPE_DEAUTH
,
2366 IEEE80211_REASON_RSN_REQUIRED
);
2367 ieee80211_node_leave(ic
, ni
);
2368 /* XXX distinguish WPA/RSN? */
2369 ic
->ic_stats
.is_rx_assoc_badwpaie
++;
2374 * Parse WPA information element. Note that
2375 * we initialize the param block from the node
2376 * state so that information in the IE overrides
2377 * our defaults. The resulting parameters are
2378 * installed below after the association is assured.
2381 if (wpa
[0] != IEEE80211_ELEMID_RSN
)
2382 reason
= ieee80211_parse_wpa(ic
, wpa
, &rsn
, wh
);
2384 reason
= ieee80211_parse_rsn(ic
, wpa
, &rsn
, wh
);
2386 IEEE80211_SEND_MGMT(ic
, ni
,
2387 IEEE80211_FC0_SUBTYPE_DEAUTH
, reason
);
2388 ieee80211_node_leave(ic
, ni
);
2389 /* XXX distinguish WPA/RSN? */
2390 ic
->ic_stats
.is_rx_assoc_badwpaie
++;
2393 IEEE80211_DPRINTF(ic
,
2394 IEEE80211_MSG_ASSOC
| IEEE80211_MSG_WPA
,
2395 "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n",
2396 ether_sprintf(wh
->i_addr2
),
2397 wpa
[0] != IEEE80211_ELEMID_RSN
? "WPA" : "RSN",
2398 rsn
.rsn_mcastcipher
, rsn
.rsn_mcastkeylen
,
2399 rsn
.rsn_ucastcipher
, rsn
.rsn_ucastkeylen
,
2400 rsn
.rsn_keymgmt
, rsn
.rsn_caps
);
2402 /* discard challenge after association */
2403 if (ni
->ni_challenge
!= NULL
) {
2404 free(ni
->ni_challenge
, M_DEVBUF
);
2405 ni
->ni_challenge
= NULL
;
2407 /* NB: 802.11 spec says to ignore station's privacy bit */
2408 if ((capinfo
& IEEE80211_CAPINFO_ESS
) == 0) {
2409 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ANY
,
2410 "[%s] deny %s request, capability mismatch 0x%x\n",
2411 ether_sprintf(wh
->i_addr2
),
2412 reassoc
? "reassoc" : "assoc", capinfo
);
2413 IEEE80211_SEND_MGMT(ic
, ni
, resp
,
2414 IEEE80211_STATUS_CAPINFO
);
2415 ieee80211_node_leave(ic
, ni
);
2416 ic
->ic_stats
.is_rx_assoc_capmismatch
++;
2419 rate
= ieee80211_setup_rates(ni
, rates
, xrates
,
2420 IEEE80211_F_DOSORT
| IEEE80211_F_DOFRATE
|
2421 IEEE80211_F_DONEGO
| IEEE80211_F_DODEL
);
2423 * If constrained to 11g-only stations reject an
2424 * 11b-only station. We cheat a bit here by looking
2425 * at the max negotiated xmit rate and assuming anyone
2426 * with a best rate <24Mb/s is an 11b station.
2428 if ((rate
& IEEE80211_RATE_BASIC
) ||
2429 ((ic
->ic_flags
& IEEE80211_F_PUREG
) && rate
< 48)) {
2430 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ANY
,
2431 "[%s] deny %s request, rate set mismatch\n",
2432 ether_sprintf(wh
->i_addr2
),
2433 reassoc
? "reassoc" : "assoc");
2434 IEEE80211_SEND_MGMT(ic
, ni
, resp
,
2435 IEEE80211_STATUS_BASIC_RATE
);
2436 ieee80211_node_leave(ic
, ni
);
2437 ic
->ic_stats
.is_rx_assoc_norate
++;
2441 ni
->ni_rstamp
= rstamp
;
2442 ni
->ni_intval
= lintval
;
2443 ni
->ni_capinfo
= capinfo
;
2444 ni
->ni_chan
= ic
->ic_bss
->ni_chan
;
2445 ni
->ni_fhdwell
= ic
->ic_bss
->ni_fhdwell
;
2446 ni
->ni_fhindex
= ic
->ic_bss
->ni_fhindex
;
2449 * Record WPA/RSN parameters for station, mark
2450 * node as using WPA and record information element
2451 * for applications that require it.
2454 ieee80211_saveie(&ni
->ni_wpa_ie
, wpa
);
2455 } else if (ni
->ni_wpa_ie
!= NULL
) {
2457 * Flush any state from a previous association.
2459 free(ni
->ni_wpa_ie
, M_DEVBUF
);
2460 ni
->ni_wpa_ie
= NULL
;
2464 * Record WME parameters for station, mark node
2465 * as capable of QoS and record information
2466 * element for applications that require it.
2468 ieee80211_saveie(&ni
->ni_wme_ie
, wme
);
2469 ni
->ni_flags
|= IEEE80211_NODE_QOS
;
2470 } else if (ni
->ni_wme_ie
!= NULL
) {
2472 * Flush any state from a previous association.
2474 free(ni
->ni_wme_ie
, M_DEVBUF
);
2475 ni
->ni_wme_ie
= NULL
;
2476 ni
->ni_flags
&= ~IEEE80211_NODE_QOS
;
2478 ieee80211_node_join(ic
, ni
, resp
);
2482 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP
:
2483 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP
: {
2484 u_int16_t capinfo
, associd
;
2487 if (ic
->ic_opmode
!= IEEE80211_M_STA
||
2488 ic
->ic_state
!= IEEE80211_S_ASSOC
) {
2489 ic
->ic_stats
.is_rx_mgtdiscard
++;
2494 * asresp frame format
2495 * [2] capability information
2497 * [2] association ID
2498 * [tlv] supported rates
2499 * [tlv] extended supported rates
2502 IEEE80211_VERIFY_LENGTH(efrm
- frm
, 6);
2504 capinfo
= le16toh(*(u_int16_t
*)frm
);
2506 status
= le16toh(*(u_int16_t
*)frm
);
2509 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
2510 "[%s] %sassoc failed (reason %d)\n",
2511 ether_sprintf(wh
->i_addr2
),
2512 ISREASSOC(subtype
) ? "re" : "", status
);
2513 if (ni
!= ic
->ic_bss
) /* XXX never true? */
2515 ic
->ic_stats
.is_rx_auth_fail
++; /* XXX */
2518 associd
= le16toh(*(u_int16_t
*)frm
);
2521 rates
= xrates
= wpa
= wme
= NULL
;
2522 while (frm
< efrm
) {
2524 case IEEE80211_ELEMID_RATES
:
2527 case IEEE80211_ELEMID_XRATES
:
2530 case IEEE80211_ELEMID_VENDOR
:
2533 /* XXX Atheros OUI support */
2539 IEEE80211_VERIFY_ELEMENT(rates
, IEEE80211_RATE_MAXSIZE
);
2540 rate
= ieee80211_setup_rates(ni
, rates
, xrates
,
2541 IEEE80211_F_DOSORT
| IEEE80211_F_DOFRATE
|
2542 IEEE80211_F_DONEGO
| IEEE80211_F_DODEL
);
2543 if (rate
& IEEE80211_RATE_BASIC
) {
2544 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
2545 "[%s] %sassoc failed (rate set mismatch)\n",
2546 ether_sprintf(wh
->i_addr2
),
2547 ISREASSOC(subtype
) ? "re" : "");
2548 if (ni
!= ic
->ic_bss
) /* XXX never true? */
2550 ic
->ic_stats
.is_rx_assoc_norate
++;
2551 ieee80211_new_state(ic
, IEEE80211_S_SCAN
, 0);
2555 ni
->ni_capinfo
= capinfo
;
2556 ni
->ni_associd
= associd
;
2558 ieee80211_parse_wmeparams(ic
, wme
, wh
) >= 0) {
2559 ni
->ni_flags
|= IEEE80211_NODE_QOS
;
2560 ieee80211_wme_updateparams(ic
);
2562 ni
->ni_flags
&= ~IEEE80211_NODE_QOS
;
2564 * Configure state now that we are associated.
2566 * XXX may need different/additional driver callbacks?
2568 if (ic
->ic_curmode
== IEEE80211_MODE_11A
||
2569 (ni
->ni_capinfo
& IEEE80211_CAPINFO_SHORT_PREAMBLE
)) {
2570 ic
->ic_flags
|= IEEE80211_F_SHPREAMBLE
;
2571 ic
->ic_flags
&= ~IEEE80211_F_USEBARKER
;
2573 ic
->ic_flags
&= ~IEEE80211_F_SHPREAMBLE
;
2574 ic
->ic_flags
|= IEEE80211_F_USEBARKER
;
2576 ieee80211_set_shortslottime(ic
,
2577 ic
->ic_curmode
== IEEE80211_MODE_11A
||
2578 (ni
->ni_capinfo
& IEEE80211_CAPINFO_SHORT_SLOTTIME
));
2580 * Honor ERP protection.
2582 * NB: ni_erp should zero for non-11g operation.
2583 * XXX check ic_curmode anyway?
2585 if (ic
->ic_curmode
== IEEE80211_MODE_11G
&&
2586 (ni
->ni_erp
& IEEE80211_ERP_USE_PROTECTION
))
2587 ic
->ic_flags
|= IEEE80211_F_USEPROT
;
2589 ic
->ic_flags
&= ~IEEE80211_F_USEPROT
;
2590 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
2591 "[%s] %sassoc success: %s preamble, %s slot time%s%s\n",
2592 ether_sprintf(wh
->i_addr2
),
2593 ISREASSOC(subtype
) ? "re" : "",
2594 ic
->ic_flags
&IEEE80211_F_SHPREAMBLE
? "short" : "long",
2595 ic
->ic_flags
&IEEE80211_F_SHSLOT
? "short" : "long",
2596 ic
->ic_flags
&IEEE80211_F_USEPROT
? ", protection" : "",
2597 ni
->ni_flags
& IEEE80211_NODE_QOS
? ", QoS" : ""
2599 ieee80211_new_state(ic
, IEEE80211_S_RUN
, subtype
);
2603 case IEEE80211_FC0_SUBTYPE_DEAUTH
: {
2606 if (ic
->ic_state
== IEEE80211_S_SCAN
) {
2607 ic
->ic_stats
.is_rx_mgtdiscard
++;
2611 * deauth frame format
2614 IEEE80211_VERIFY_LENGTH(efrm
- frm
, 2);
2615 reason
= le16toh(*(u_int16_t
*)frm
);
2616 ic
->ic_stats
.is_rx_deauth
++;
2617 IEEE80211_NODE_STAT(ni
, rx_deauth
);
2619 if (!IEEE80211_ADDR_EQ(wh
->i_addr1
, ic
->ic_myaddr
)) {
2620 /* Not intended for this station. */
2621 ic
->ic_stats
.is_rx_mgtdiscard
++;
2624 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_AUTH
,
2625 "[%s] recv deauthenticate (reason %d)\n",
2626 ether_sprintf(ni
->ni_macaddr
), reason
);
2627 switch (ic
->ic_opmode
) {
2628 case IEEE80211_M_STA
:
2629 ieee80211_new_state(ic
, IEEE80211_S_AUTH
,
2630 wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
);
2632 case IEEE80211_M_HOSTAP
:
2633 #ifndef IEEE80211_NO_HOSTAP
2634 if (ni
!= ic
->ic_bss
)
2635 ieee80211_node_leave(ic
, ni
);
2636 #endif /* !IEEE80211_NO_HOSTAP */
2639 ic
->ic_stats
.is_rx_mgtdiscard
++;
2645 case IEEE80211_FC0_SUBTYPE_DISASSOC
: {
2648 if (ic
->ic_state
!= IEEE80211_S_RUN
&&
2649 ic
->ic_state
!= IEEE80211_S_ASSOC
&&
2650 ic
->ic_state
!= IEEE80211_S_AUTH
) {
2651 ic
->ic_stats
.is_rx_mgtdiscard
++;
2655 * disassoc frame format
2658 IEEE80211_VERIFY_LENGTH(efrm
- frm
, 2);
2659 reason
= le16toh(*(u_int16_t
*)frm
);
2660 ic
->ic_stats
.is_rx_disassoc
++;
2661 IEEE80211_NODE_STAT(ni
, rx_disassoc
);
2663 if (!IEEE80211_ADDR_EQ(wh
->i_addr1
, ic
->ic_myaddr
)) {
2664 /* Not intended for this station. */
2665 ic
->ic_stats
.is_rx_mgtdiscard
++;
2668 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_ASSOC
,
2669 "[%s] recv disassociate (reason %d)\n",
2670 ether_sprintf(ni
->ni_macaddr
), reason
);
2671 switch (ic
->ic_opmode
) {
2672 case IEEE80211_M_STA
:
2673 ieee80211_new_state(ic
, IEEE80211_S_ASSOC
,
2674 wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
);
2676 case IEEE80211_M_HOSTAP
:
2677 #ifndef IEEE80211_NO_HOSTAP
2678 if (ni
!= ic
->ic_bss
)
2679 ieee80211_node_leave(ic
, ni
);
2680 #endif /* !IEEE80211_NO_HOSTAP */
2683 ic
->ic_stats
.is_rx_mgtdiscard
++;
2689 IEEE80211_DISCARD(ic
, IEEE80211_MSG_ANY
,
2690 wh
, "mgt", "subtype 0x%x not handled", subtype
);
2691 ic
->ic_stats
.is_rx_badsubtype
++;
2697 #undef IEEE80211_VERIFY_LENGTH
2698 #undef IEEE80211_VERIFY_ELEMENT
2700 #ifndef IEEE80211_NO_HOSTAP
2702 * Handle station power-save state change.
2705 ieee80211_node_pwrsave(struct ieee80211_node
*ni
, int enable
)
2707 struct ieee80211com
*ic
= ni
->ni_ic
;
2711 if ((ni
->ni_flags
& IEEE80211_NODE_PWR_MGT
) == 0)
2713 ni
->ni_flags
|= IEEE80211_NODE_PWR_MGT
;
2714 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
2715 "[%s] power save mode on, %u sta's in ps mode\n",
2716 ether_sprintf(ni
->ni_macaddr
), ic
->ic_ps_sta
);
2720 if (ni
->ni_flags
& IEEE80211_NODE_PWR_MGT
)
2722 ni
->ni_flags
&= ~IEEE80211_NODE_PWR_MGT
;
2723 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
2724 "[%s] power save mode off, %u sta's in ps mode\n",
2725 ether_sprintf(ni
->ni_macaddr
), ic
->ic_ps_sta
);
2726 /* XXX if no stations in ps mode, flush mc frames */
2729 * Flush queued unicast frames.
2731 if (IEEE80211_NODE_SAVEQ_QLEN(ni
) == 0) {
2732 if (ic
->ic_set_tim
!= NULL
)
2733 ic
->ic_set_tim(ni
, 0); /* just in case */
2736 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
2737 "[%s] flush ps queue, %u packets queued\n",
2738 ether_sprintf(ni
->ni_macaddr
), IEEE80211_NODE_SAVEQ_QLEN(ni
));
2742 IEEE80211_NODE_SAVEQ_DEQUEUE(ni
, m
, qlen
);
2746 * If this is the last packet, turn off the TIM bit.
2747 * If there are more packets, set the more packets bit
2748 * in the mbuf so ieee80211_encap will mark the 802.11
2749 * head to indicate more data frames will follow.
2752 m
->m_flags
|= M_MORE_DATA
;
2753 /* XXX need different driver interface */
2754 /* XXX bypasses q max */
2755 IF_ENQUEUE(&ic
->ic_ifp
->if_snd
, m
);
2757 if (ic
->ic_set_tim
!= NULL
)
2758 ic
->ic_set_tim(ni
, 0);
2762 * Process a received ps-poll frame.
2765 ieee80211_recv_pspoll(struct ieee80211com
*ic
,
2766 struct ieee80211_node
*ni
, struct mbuf
*m0
)
2768 struct ieee80211_frame_min
*wh
;
2773 wh
= mtod(m0
, struct ieee80211_frame_min
*);
2774 if (ni
->ni_associd
== 0) {
2775 IEEE80211_DISCARD(ic
, IEEE80211_MSG_POWER
| IEEE80211_MSG_DEBUG
,
2776 (struct ieee80211_frame
*) wh
, "ps-poll",
2777 "%s", "unassociated station");
2778 ic
->ic_stats
.is_ps_unassoc
++;
2779 IEEE80211_SEND_MGMT(ic
, ni
, IEEE80211_FC0_SUBTYPE_DEAUTH
,
2780 IEEE80211_REASON_NOT_ASSOCED
);
2784 aid
= le16toh(*(u_int16_t
*)wh
->i_dur
);
2785 if (aid
!= ni
->ni_associd
) {
2786 IEEE80211_DISCARD(ic
, IEEE80211_MSG_POWER
| IEEE80211_MSG_DEBUG
,
2787 (struct ieee80211_frame
*) wh
, "ps-poll",
2788 "aid mismatch: sta aid 0x%x poll aid 0x%x",
2789 ni
->ni_associd
, aid
);
2790 ic
->ic_stats
.is_ps_badaid
++;
2791 IEEE80211_SEND_MGMT(ic
, ni
, IEEE80211_FC0_SUBTYPE_DEAUTH
,
2792 IEEE80211_REASON_NOT_ASSOCED
);
2796 /* Okay, take the first queued packet and put it out... */
2797 IEEE80211_NODE_SAVEQ_DEQUEUE(ni
, m
, qlen
);
2799 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
2800 "[%s] recv ps-poll, but queue empty\n",
2801 ether_sprintf(wh
->i_addr2
));
2802 ieee80211_send_nulldata(ieee80211_ref_node(ni
));
2803 ic
->ic_stats
.is_ps_qempty
++; /* XXX node stat */
2804 if (ic
->ic_set_tim
!= NULL
)
2805 ic
->ic_set_tim(ni
, 0); /* just in case */
2809 * If there are more packets, set the more packets bit
2810 * in the packet dispatched to the station; otherwise
2811 * turn off the TIM bit.
2814 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
2815 "[%s] recv ps-poll, send packet, %u still queued\n",
2816 ether_sprintf(ni
->ni_macaddr
), qlen
);
2817 m
->m_flags
|= M_MORE_DATA
;
2819 IEEE80211_DPRINTF(ic
, IEEE80211_MSG_POWER
,
2820 "[%s] recv ps-poll, send packet, queue empty\n",
2821 ether_sprintf(ni
->ni_macaddr
));
2822 if (ic
->ic_set_tim
!= NULL
)
2823 ic
->ic_set_tim(ni
, 0);
2825 m
->m_flags
|= M_PWR_SAV
; /* bypass PS handling */
2826 IF_ENQUEUE(&ic
->ic_ifp
->if_snd
, m
);
2828 #endif /* !IEEE80211_NO_HOSTAP */
2830 #ifdef IEEE80211_DEBUG
2832 * Debugging support.
2836 * Return the bssid of a frame.
2838 static const u_int8_t
*
2839 ieee80211_getbssid(struct ieee80211com
*ic
, const struct ieee80211_frame
*wh
)
2841 if (ic
->ic_opmode
== IEEE80211_M_STA
)
2843 if ((wh
->i_fc
[1] & IEEE80211_FC1_DIR_MASK
) != IEEE80211_FC1_DIR_NODS
)
2845 if ((wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
) == IEEE80211_FC0_SUBTYPE_PS_POLL
)
2851 ieee80211_note(struct ieee80211com
*ic
, const char *fmt
, ...)
2853 char buf
[128]; /* XXX */
2857 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
2860 if_printf(ic
->ic_ifp
, "%s", buf
); /* NB: no \n */
2864 ieee80211_note_frame(struct ieee80211com
*ic
,
2865 const struct ieee80211_frame
*wh
,
2866 const char *fmt
, ...)
2868 char buf
[128]; /* XXX */
2872 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
2874 if_printf(ic
->ic_ifp
, "[%s] %s\n",
2875 ether_sprintf(ieee80211_getbssid(ic
, wh
)), buf
);
2879 ieee80211_note_mac(struct ieee80211com
*ic
,
2880 const u_int8_t mac
[IEEE80211_ADDR_LEN
],
2881 const char *fmt
, ...)
2883 char buf
[128]; /* XXX */
2887 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
2889 if_printf(ic
->ic_ifp
, "[%s] %s\n", ether_sprintf(mac
), buf
);
2893 ieee80211_discard_frame(struct ieee80211com
*ic
,
2894 const struct ieee80211_frame
*wh
,
2895 const char *type
, const char *fmt
, ...)
2899 printf("[%s:%s] discard ", ic
->ic_ifp
->if_xname
,
2900 ether_sprintf(ieee80211_getbssid(ic
, wh
)));
2902 printf("%s frame, ", type
);
2912 ieee80211_discard_ie(struct ieee80211com
*ic
,
2913 const struct ieee80211_frame
*wh
,
2914 const char *type
, const char *fmt
, ...)
2918 printf("[%s:%s] discard ", ic
->ic_ifp
->if_xname
,
2919 ether_sprintf(ieee80211_getbssid(ic
, wh
)));
2921 printf("%s information element, ", type
);
2923 printf("information element, ");
2931 ieee80211_discard_mac(struct ieee80211com
*ic
,
2932 const u_int8_t mac
[IEEE80211_ADDR_LEN
],
2933 const char *type
, const char *fmt
, ...)
2937 printf("[%s:%s] discard ", ic
->ic_ifp
->if_xname
, ether_sprintf(mac
));
2939 printf("%s frame, ", type
);
2947 #endif /* IEEE80211_DEBUG */