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_input.c,v 1.62.2.12 2006/03/14 23:24:02 sam Exp $
33 * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_input.c,v 1.4 2006/05/18 13:51:46 sephe Exp $
36 #include <sys/param.h>
37 #include <sys/systm.h>
39 #include <sys/malloc.h>
40 #include <sys/endian.h>
41 #include <sys/kernel.h>
42 #include <sys/serialize.h>
44 #include <sys/socket.h>
47 #include <net/if_arp.h>
48 #include <net/ifq_var.h>
49 #include <net/if_media.h>
50 #include <net/ethernet.h>
51 #include <net/if_llc.h>
52 #include <net/vlan/if_vlan_var.h>
54 #include <netproto/802_11/ieee80211_var.h>
58 #ifdef IEEE80211_DEBUG
59 #include <machine/stdarg.h>
62 * Decide if a received management frame should be
63 * printed when debugging is enabled. This filters some
64 * of the less interesting frames that come frequently
68 doprint(struct ieee80211com *ic, int subtype)
71 case IEEE80211_FC0_SUBTYPE_BEACON:
72 return (ic->ic_flags & IEEE80211_F_SCAN);
73 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
74 return (ic->ic_opmode == IEEE80211_M_IBSS);
80 * Emit a debug message about discarding a frame or information
81 * element. One format is for extracting the mac address from
82 * the frame header; the other is for when a header is not
83 * available or otherwise appropriate.
85 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) do { \
86 if ((_ic)->ic_debug & (_m)) \
87 ieee80211_discard_frame(_ic, _wh, _type, _fmt, __VA_ARGS__);\
89 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) do { \
90 if ((_ic)->ic_debug & (_m)) \
91 ieee80211_discard_ie(_ic, _wh, _type, _fmt, __VA_ARGS__);\
93 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) do { \
94 if ((_ic)->ic_debug & (_m)) \
95 ieee80211_discard_mac(_ic, _mac, _type, _fmt, __VA_ARGS__);\
98 static const uint8_t *ieee80211_getbssid(struct ieee80211com *,
99 const struct ieee80211_frame *);
100 static void ieee80211_discard_frame(struct ieee80211com *,
101 const struct ieee80211_frame *, const char *type, const char *fmt, ...);
102 static void ieee80211_discard_ie(struct ieee80211com *,
103 const struct ieee80211_frame *, const char *type, const char *fmt, ...);
104 static void ieee80211_discard_mac(struct ieee80211com *,
105 const uint8_t mac[IEEE80211_ADDR_LEN], const char *type,
106 const char *fmt, ...);
108 #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...)
109 #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...)
110 #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...)
111 #endif /* IEEE80211_DEBUG */
113 static struct mbuf *ieee80211_defrag(struct ieee80211com *,
114 struct ieee80211_node *, struct mbuf *, int);
115 static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *, int);
116 static void ieee80211_send_error(struct ieee80211com *, struct ieee80211_node *,
117 const uint8_t *mac, int subtype, int arg);
118 static void ieee80211_deliver_data(struct ieee80211com *,
119 struct ieee80211_node *, struct mbuf *);
120 static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
121 static void ieee80211_recv_pspoll(struct ieee80211com *,
122 struct ieee80211_node *, struct mbuf *);
125 * Process a received frame. The node associated with the sender
126 * should be supplied. If nothing was found in the node table then
127 * the caller is assumed to supply a reference to ic_bss instead.
128 * The RSSI and a timestamp are also supplied. The RSSI data is used
129 * during AP scanning to select a AP to associate with; it can have
130 * any units so long as values have consistent units and higher values
131 * mean ``better signal''. The receive timestamp is currently not used
132 * by the 802.11 layer.
135 ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
136 struct ieee80211_node *ni, int rssi, uint32_t rstamp)
138 #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
139 #define HAS_SEQ(type) ((type & 0x4) == 0)
140 struct ifnet *ifp = ic->ic_ifp;
141 struct ieee80211_frame *wh;
142 struct ieee80211_key *key;
143 struct ether_header *eh;
145 uint8_t dir, type, subtype;
149 ASSERT_SERIALIZED(ifp->if_serializer);
151 KASSERT(ni != NULL, ("null node"));
152 ni->ni_inact = ni->ni_inact_reload;
155 /* trim CRC here so WEP can find its own CRC at the end of packet. */
156 if (m->m_flags & M_HASFCS) {
157 m_adj(m, -IEEE80211_CRC_LEN);
158 m->m_flags &= ~M_HASFCS;
162 type = -1; /* undefined */
164 * In monitor mode, send everything directly to bpf.
165 * XXX may want to include the CRC
167 if (ic->ic_opmode == IEEE80211_M_MONITOR)
170 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
171 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
172 ni->ni_macaddr, NULL,
173 "too short (1): len %u", m->m_pkthdr.len);
174 ic->ic_stats.is_rx_tooshort++;
178 * Bit of a cheat here, we use a pointer for a 3-address
179 * frame format but don't reference fields past outside
180 * ieee80211_frame_min w/o first validating the data is
183 wh = mtod(m, struct ieee80211_frame *);
185 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
186 IEEE80211_FC0_VERSION_0) {
187 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
188 ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]);
189 ic->ic_stats.is_rx_badversion++;
193 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
194 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
195 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
196 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
197 switch (ic->ic_opmode) {
198 case IEEE80211_M_STA:
200 if (!IEEE80211_ADDR_EQ(bssid, ni->ni_bssid)) {
201 /* not interested in */
202 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
203 bssid, NULL, "%s", "not to bss");
204 ic->ic_stats.is_rx_wrongbss++;
208 case IEEE80211_M_IBSS:
209 case IEEE80211_M_AHDEMO:
210 case IEEE80211_M_HOSTAP:
211 if (dir != IEEE80211_FC1_DIR_NODS)
213 else if (type == IEEE80211_FC0_TYPE_CTL)
216 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
217 IEEE80211_DISCARD_MAC(ic,
218 IEEE80211_MSG_ANY, ni->ni_macaddr,
219 NULL, "too short (2): len %u",
221 ic->ic_stats.is_rx_tooshort++;
226 if (type != IEEE80211_FC0_TYPE_DATA)
229 * Data frame, validate the bssid.
231 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) &&
232 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
233 /* not interested in */
234 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
235 bssid, NULL, "%s", "not to bss");
236 ic->ic_stats.is_rx_wrongbss++;
240 * For adhoc mode we cons up a node when it doesn't
241 * exist. This should probably done after an ACL check.
243 if (ni == ic->ic_bss &&
244 ic->ic_opmode != IEEE80211_M_HOSTAP &&
245 !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
247 * Fake up a node for this newly
248 * discovered member of the IBSS.
250 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
253 /* NB: stat kept for alloc failure */
262 ni->ni_rstamp = rstamp;
265 if (IEEE80211_QOS_HAS_SEQ(wh)) {
266 tid = ((struct ieee80211_qosframe *)wh)->
267 i_qos[0] & IEEE80211_QOS_TID;
268 if (TID_TO_WME_AC(tid) >= WME_AC_VI)
269 ic->ic_wme.wme_hipri_traffic++;
273 rxseq = le16toh(*(uint16_t *)wh->i_seq);
274 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
275 SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
276 /* duplicate, discard */
277 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
279 "seqno <%u,%u> fragno <%u,%u> tid %u",
280 rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
281 ni->ni_rxseqs[tid] >>
282 IEEE80211_SEQ_SEQ_SHIFT,
283 rxseq & IEEE80211_SEQ_FRAG_MASK,
285 IEEE80211_SEQ_FRAG_MASK,
287 ic->ic_stats.is_rx_dup++;
288 IEEE80211_NODE_STAT(ni, rx_dup);
291 ni->ni_rxseqs[tid] = rxseq;
296 case IEEE80211_FC0_TYPE_DATA:
297 hdrspace = ieee80211_hdrspace(ic, wh);
298 if (m->m_len < hdrspace &&
299 (m = m_pullup(m, hdrspace)) == NULL) {
300 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
301 ni->ni_macaddr, NULL,
302 "data too short: expecting %u", hdrspace);
303 ic->ic_stats.is_rx_tooshort++;
306 switch (ic->ic_opmode) {
307 case IEEE80211_M_STA:
308 if (dir != IEEE80211_FC1_DIR_FROMDS) {
309 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
310 wh, "data", "%s", "unknown dir 0x%x", dir);
311 ic->ic_stats.is_rx_wrongdir++;
314 if ((ifp->if_flags & IFF_SIMPLEX) &&
315 IEEE80211_IS_MULTICAST(wh->i_addr1) &&
316 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
318 * In IEEE802.11 network, multicast packet
319 * sent from me is broadcasted from AP.
320 * It should be silently discarded for
323 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
324 wh, NULL, "%s", "multicast echo");
325 ic->ic_stats.is_rx_mcastecho++;
329 case IEEE80211_M_IBSS:
330 case IEEE80211_M_AHDEMO:
331 if (dir != IEEE80211_FC1_DIR_NODS) {
332 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
333 wh, "data", "%s", "unknown dir 0x%x", dir);
334 ic->ic_stats.is_rx_wrongdir++;
337 /* XXX no power-save support */
339 case IEEE80211_M_HOSTAP:
340 if (dir != IEEE80211_FC1_DIR_TODS) {
341 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
342 wh, "data", "%s", "unknown dir 0x%x", dir);
343 ic->ic_stats.is_rx_wrongdir++;
346 /* check if source STA is associated */
347 if (ni == ic->ic_bss) {
348 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
349 wh, "data", "%s", "unknown src");
350 ieee80211_send_error(ic, ni, wh->i_addr2,
351 IEEE80211_FC0_SUBTYPE_DEAUTH,
352 IEEE80211_REASON_NOT_AUTHED);
353 ic->ic_stats.is_rx_notassoc++;
356 if (ni->ni_associd == 0) {
357 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
358 wh, "data", "%s", "unassoc src");
359 IEEE80211_SEND_MGMT(ic, ni,
360 IEEE80211_FC0_SUBTYPE_DISASSOC,
361 IEEE80211_REASON_NOT_ASSOCED);
362 ic->ic_stats.is_rx_notassoc++;
367 * Check for power save state change.
369 if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^
370 (ni->ni_flags & IEEE80211_NODE_PWR_MGT)))
371 ieee80211_node_pwrsave(ni,
372 wh->i_fc[1] & IEEE80211_FC1_PWR_MGT);
375 /* XXX here to keep compiler happy */
380 * Handle privacy requirements. Note that we
381 * must not be preempted from here until after
382 * we (potentially) call ieee80211_crypto_demic;
383 * otherwise we may violate assumptions in the
384 * crypto cipher modules used to do delayed update
385 * of replay sequence numbers.
387 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
388 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
390 * Discard encrypted frames when privacy is off.
392 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
393 wh, "WEP", "%s", "PRIVACY off");
394 ic->ic_stats.is_rx_noprivacy++;
395 IEEE80211_NODE_STAT(ni, rx_noprivacy);
398 key = ieee80211_crypto_decap(ic, ni, m, hdrspace);
400 /* NB: stats+msgs handled in crypto_decap */
401 IEEE80211_NODE_STAT(ni, rx_wepfail);
404 wh = mtod(m, struct ieee80211_frame *);
405 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
411 * Next up, any fragmentation.
413 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
414 m = ieee80211_defrag(ic, ni, m, hdrspace);
416 /* Fragment dropped or frame not complete yet */
420 wh = NULL; /* no longer valid, catch any uses */
423 * Next strip any MSDU crypto bits.
425 if (key != NULL && !ieee80211_crypto_demic(ic, key, m, 0)) {
426 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
427 ni->ni_macaddr, "data", "%s", "demic error");
428 IEEE80211_NODE_STAT(ni, rx_demicfail);
432 /* copy to listener after decrypt */
434 bpf_mtap(ic->ic_rawbpf, m);
437 * Finally, strip the 802.11 header.
439 m = ieee80211_decap(ic, m, hdrspace);
441 /* don't count Null data frames as errors */
442 if (subtype == IEEE80211_FC0_SUBTYPE_NODATA)
444 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
445 ni->ni_macaddr, "data", "%s", "decap error");
446 ic->ic_stats.is_rx_decap++;
447 IEEE80211_NODE_STAT(ni, rx_decap);
450 eh = mtod(m, struct ether_header *);
451 if (!ieee80211_node_is_authorized(ni)) {
453 * Deny any non-PAE frames received prior to
454 * authorization. For open/shared-key
455 * authentication the port is mark authorized
456 * after authentication completes. For 802.1x
457 * the port is not marked authorized by the
458 * authenticator until the handshake has completed.
460 if (eh->ether_type != htons(ETHERTYPE_PAE)) {
461 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
462 eh->ether_shost, "data",
463 "unauthorized port: ether type 0x%x len %u",
464 eh->ether_type, m->m_pkthdr.len);
465 ic->ic_stats.is_rx_unauth++;
466 IEEE80211_NODE_STAT(ni, rx_unauth);
471 * When denying unencrypted frames, discard
472 * any non-PAE frames received without encryption.
474 if ((ic->ic_flags & IEEE80211_F_DROPUNENC) &&
476 eh->ether_type != htons(ETHERTYPE_PAE)) {
478 * Drop unencrypted frames.
480 ic->ic_stats.is_rx_unencrypted++;
481 IEEE80211_NODE_STAT(ni, rx_unencrypted);
486 IEEE80211_NODE_STAT(ni, rx_data);
487 IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len);
489 ieee80211_deliver_data(ic, ni, m);
490 return IEEE80211_FC0_TYPE_DATA;
492 case IEEE80211_FC0_TYPE_MGT:
493 IEEE80211_NODE_STAT(ni, rx_mgmt);
494 if (dir != IEEE80211_FC1_DIR_NODS) {
495 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
496 wh, "data", "%s", "unknown dir 0x%x", dir);
497 ic->ic_stats.is_rx_wrongdir++;
500 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
501 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
502 ni->ni_macaddr, "mgt", "too short: len %u",
504 ic->ic_stats.is_rx_tooshort++;
507 #ifdef IEEE80211_DEBUG
508 if ((ieee80211_msg_debug(ic) && doprint(ic, subtype)) ||
509 ieee80211_msg_dumppkts(ic)) {
510 if_printf(ic->ic_ifp, "received %s from %6D rssi %d\n",
511 ieee80211_mgt_subtype_name[subtype >>
512 IEEE80211_FC0_SUBTYPE_SHIFT],
513 wh->i_addr2, ":", rssi);
516 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
517 if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) {
519 * Only shared key auth frames with a challenge
520 * should be encrypted, discard all others.
522 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
523 wh, ieee80211_mgt_subtype_name[subtype >>
524 IEEE80211_FC0_SUBTYPE_SHIFT],
525 "%s", "WEP set but not permitted");
526 ic->ic_stats.is_rx_mgtdiscard++; /* XXX */
529 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
531 * Discard encrypted frames when privacy is off.
533 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
534 wh, "mgt", "%s", "WEP set but PRIVACY off");
535 ic->ic_stats.is_rx_noprivacy++;
538 hdrspace = ieee80211_hdrspace(ic, wh);
539 key = ieee80211_crypto_decap(ic, ni, m, hdrspace);
541 /* NB: stats+msgs handled in crypto_decap */
544 wh = mtod(m, struct ieee80211_frame *);
545 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
548 bpf_mtap(ic->ic_rawbpf, m);
549 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
553 case IEEE80211_FC0_TYPE_CTL:
554 IEEE80211_NODE_STAT(ni, rx_ctrl);
555 ic->ic_stats.is_rx_ctl++;
556 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
558 case IEEE80211_FC0_SUBTYPE_PS_POLL:
559 ieee80211_recv_pspoll(ic, ni, m);
565 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
566 wh, NULL, "bad frame type 0x%x", type);
567 /* should not come here */
575 bpf_mtap(ic->ic_rawbpf, m);
583 * This function reassemble fragments.
586 ieee80211_defrag(struct ieee80211com *ic, struct ieee80211_node *ni,
587 struct mbuf *m, int hdrspace)
589 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
590 struct ieee80211_frame *lwh;
593 uint8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
596 KASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?"));
598 rxseq = le16toh(*(uint16_t *)wh->i_seq);
599 fragno = rxseq & IEEE80211_SEQ_FRAG_MASK;
601 /* Quick way out, if there's nothing to defragment */
602 if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL)
606 * Remove frag to insure it doesn't get reaped by timer.
608 if (ni->ni_table == NULL) {
610 * Should never happen. If the node is orphaned (not in
611 * the table) then input packets should not reach here.
612 * Otherwise, a concurrent request that yanks the table
613 * should be blocked by other interlocking and/or by first
614 * shutting the driver down. Regardless, be defensive
617 /* XXX need msg+stat */
621 mfrag = ni->ni_rxfrag[0];
622 ni->ni_rxfrag[0] = NULL;
625 * Validate new fragment is in order and
626 * related to the previous ones.
631 lwh = mtod(mfrag, struct ieee80211_frame *);
632 last_rxseq = le16toh(*(uint16_t *)lwh->i_seq);
633 /* NB: check seq # and frag together */
634 if (rxseq != last_rxseq+1 ||
635 !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) ||
636 !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) {
638 * Unrelated fragment or no space for it,
639 * clear current fragments.
647 if (fragno != 0) { /* !first fragment, discard */
648 IEEE80211_NODE_STAT(ni, rx_defrag);
653 } else { /* concatenate */
654 m_adj(m, hdrspace); /* strip header */
656 /* NB: m_cat doesn't update the packet header */
657 mfrag->m_pkthdr.len += m->m_pkthdr.len;
658 /* track last seqnum and fragno */
659 lwh = mtod(mfrag, struct ieee80211_frame *);
660 *(uint16_t *) lwh->i_seq = *(uint16_t *) wh->i_seq;
662 if (more_frag) { /* more to come, save */
663 ni->ni_rxfragstamp = ticks;
664 ni->ni_rxfrag[0] = mfrag;
671 ieee80211_deliver_data(struct ieee80211com *ic,
672 struct ieee80211_node *ni, struct mbuf *m)
674 struct ether_header *eh = mtod(m, struct ether_header *);
675 struct ifnet *ifp = ic->ic_ifp;
677 /* perform as a bridge within the AP */
678 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
679 (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) {
680 struct mbuf *m1 = NULL;
682 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
683 m1 = m_dup(m, MB_DONTWAIT);
687 m1->m_flags |= M_MCAST;
690 * Check if the destination is known; if so
691 * and the port is authorized dispatch directly.
693 struct ieee80211_node *sta =
694 ieee80211_find_node(&ic->ic_sta, eh->ether_dhost);
696 if (ieee80211_node_is_authorized(sta)) {
698 * Beware of sending to ourself; this
699 * needs to happen via the normal
702 if (sta != ic->ic_bss) {
707 ic->ic_stats.is_rx_unauth++;
708 IEEE80211_NODE_STAT(sta, rx_unauth);
710 ieee80211_free_node(sta);
714 /* XXX bypasses ALTQ */
715 ifq_handoff(ifp, m1, NULL);
720 if (ni->ni_vlan != 0) {
721 /* attach vlan tag */
722 VLAN_INPUT_TAG_NEW(ifp, m, ni->ni_vlan);
724 goto out; /* XXX goto err? */
727 ifp->if_input(ifp, m);
735 bpf_mtap(ic->ic_rawbpf, m);
742 ieee80211_decap(struct ieee80211com *ic, struct mbuf *m, int hdrlen)
744 struct ieee80211_qosframe_addr4 wh; /* Max size address frames */
745 struct ether_header *eh;
748 if (m->m_len < hdrlen + sizeof(*llc) &&
749 (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) {
753 memcpy(&wh, mtod(m, caddr_t), hdrlen);
754 llc = (struct llc *)(mtod(m, caddr_t) + hdrlen);
755 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
756 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
757 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
758 m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh));
761 m_adj(m, hdrlen - sizeof(*eh));
763 eh = mtod(m, struct ether_header *);
764 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
765 case IEEE80211_FC1_DIR_NODS:
766 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
767 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
769 case IEEE80211_FC1_DIR_TODS:
770 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
771 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
773 case IEEE80211_FC1_DIR_FROMDS:
774 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
775 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
777 case IEEE80211_FC1_DIR_DSTODS:
778 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
779 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4);
782 #ifdef ALIGNED_POINTER
783 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), uint32_t)) {
784 struct mbuf *n, *n0, **np;
791 pktlen = m->m_pkthdr.len;
792 while (pktlen > off) {
794 MGETHDR(n, M_DONTWAIT, MT_DATA);
802 MGET(n, M_DONTWAIT, MT_DATA);
810 if (pktlen - off >= MINCLSIZE) {
811 MCLGET(n, M_DONTWAIT);
812 if (n->m_flags & M_EXT)
813 n->m_len = n->m_ext.ext_size;
817 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) -
819 n->m_len -= newdata - n->m_data;
822 if (n->m_len > pktlen - off)
823 n->m_len = pktlen - off;
824 m_copydata(m, off, n->m_len, mtod(n, caddr_t));
832 #endif /* ALIGNED_POINTER */
834 eh = mtod(m, struct ether_header *);
835 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh));
841 * Install received rate set information in the node's state block.
844 ieee80211_setup_rates(struct ieee80211_node *ni,
845 const uint8_t *rates, const uint8_t *xrates, int flags)
847 struct ieee80211com *ic = ni->ni_ic;
848 struct ieee80211_rateset *rs = &ni->ni_rates;
850 memset(rs, 0, sizeof(*rs));
851 rs->rs_nrates = rates[1];
852 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates);
853 if (xrates != NULL) {
856 * Tack on 11g extended supported rate element.
859 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
860 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
861 IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE,
862 "[%6D] extended rate set too large;"
863 " only using %u of %u rates\n",
864 ni->ni_macaddr, ":", nxrates, xrates[1]);
865 ic->ic_stats.is_rx_rstoobig++;
867 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
868 rs->rs_nrates += nxrates;
870 return ieee80211_fix_rate(ni, flags);
874 ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh,
875 struct ieee80211_node *ni, int rssi, uint32_t rstamp, uint16_t seq,
879 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
880 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
881 ni->ni_macaddr, "open auth",
882 "bad sta auth mode %u", ni->ni_authmode);
883 ic->ic_stats.is_rx_bad_auth++; /* XXX */
884 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
885 /* XXX hack to workaround calling convention */
886 ieee80211_send_error(ic, ni, wh->i_addr2,
887 IEEE80211_FC0_SUBTYPE_AUTH,
888 (seq + 1) | (IEEE80211_STATUS_ALG<<16));
892 switch (ic->ic_opmode) {
893 case IEEE80211_M_IBSS:
894 case IEEE80211_M_AHDEMO:
895 case IEEE80211_M_MONITOR:
896 /* should not come here */
897 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
898 ni->ni_macaddr, "open auth",
899 "bad operating mode %u", ic->ic_opmode);
902 case IEEE80211_M_HOSTAP:
903 if (ic->ic_state != IEEE80211_S_RUN ||
904 seq != IEEE80211_AUTH_OPEN_REQUEST) {
905 ic->ic_stats.is_rx_bad_auth++;
908 /* always accept open authentication requests */
909 if (ni == ic->ic_bss) {
910 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
913 } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)
914 (void) ieee80211_ref_node(ni);
916 * Mark the node as referenced to reflect that it's
917 * reference count has been bumped to insure it remains
918 * after the transaction completes.
920 ni->ni_flags |= IEEE80211_NODE_AREF;
922 IEEE80211_SEND_MGMT(ic, ni,
923 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
924 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
925 "[%6D] station authenticated (open)\n",
926 ni->ni_macaddr, ":");
928 * When 802.1x is not in use mark the port
929 * authorized at this point so traffic can flow.
931 if (ni->ni_authmode != IEEE80211_AUTH_8021X)
932 ieee80211_node_authorize(ni);
935 case IEEE80211_M_STA:
936 if (ic->ic_state != IEEE80211_S_AUTH ||
937 seq != IEEE80211_AUTH_OPEN_RESPONSE) {
938 ic->ic_stats.is_rx_bad_auth++;
942 IEEE80211_DPRINTF(ic,
943 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
944 "[%6D] open auth failed (reason %d)\n",
945 ni->ni_macaddr, ":", status);
946 /* XXX can this happen? */
947 if (ni != ic->ic_bss)
949 ic->ic_stats.is_rx_auth_fail++;
950 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
952 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
953 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
959 * Send a management frame error response to the specified
960 * station. If ni is associated with the station then use
961 * it; otherwise allocate a temporary node suitable for
962 * transmitting the frame and then free the reference so
963 * it will go away as soon as the frame has been transmitted.
966 ieee80211_send_error(struct ieee80211com *ic, struct ieee80211_node *ni,
967 const uint8_t *mac, int subtype, int arg)
971 if (ni == ic->ic_bss) {
972 ni = ieee80211_tmp_node(ic, mac);
980 IEEE80211_SEND_MGMT(ic, ni, subtype, arg);
982 ieee80211_free_node(ni);
986 alloc_challenge(struct ieee80211com *ic, struct ieee80211_node *ni)
988 if (ni->ni_challenge == NULL)
989 MALLOC(ni->ni_challenge, uint32_t*, IEEE80211_CHALLENGE_LEN,
991 if (ni->ni_challenge == NULL) {
992 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
993 "[%6D] shared key challenge alloc failed\n",
994 ni->ni_macaddr, ":");
997 return (ni->ni_challenge != NULL);
1000 /* XXX TODO: add statistics */
1002 ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh,
1003 uint8_t *frm, uint8_t *efrm, struct ieee80211_node *ni, int rssi,
1004 uint32_t rstamp, uint16_t seq, uint16_t status)
1007 int allocbs, estatus;
1010 * NB: this can happen as we allow pre-shared key
1011 * authentication to be enabled w/o wep being turned
1012 * on so that configuration of these can be done
1013 * in any order. It may be better to enforce the
1014 * ordering in which case this check would just be
1015 * for sanity/consistency.
1017 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
1018 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1019 ni->ni_macaddr, "shared key auth",
1020 "%s", " PRIVACY is disabled");
1021 estatus = IEEE80211_STATUS_ALG;
1025 * Pre-shared key authentication is evil; accept
1026 * it only if explicitly configured (it is supported
1027 * mainly for compatibility with clients like OS X).
1029 if (ni->ni_authmode != IEEE80211_AUTH_AUTO &&
1030 ni->ni_authmode != IEEE80211_AUTH_SHARED) {
1031 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1032 ni->ni_macaddr, "shared key auth",
1033 "bad sta auth mode %u", ni->ni_authmode);
1034 ic->ic_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */
1035 estatus = IEEE80211_STATUS_ALG;
1040 if (frm + 1 < efrm) {
1041 if ((frm[1] + 2) > (efrm - frm)) {
1042 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1043 ni->ni_macaddr, "shared key auth",
1044 "ie %d/%d too long",
1045 frm[0], (frm[1] + 2) - (efrm - frm));
1046 ic->ic_stats.is_rx_bad_auth++;
1047 estatus = IEEE80211_STATUS_CHALLENGE;
1050 if (*frm == IEEE80211_ELEMID_CHALLENGE)
1055 case IEEE80211_AUTH_SHARED_CHALLENGE:
1056 case IEEE80211_AUTH_SHARED_RESPONSE:
1057 if (challenge == NULL) {
1058 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1059 ni->ni_macaddr, "shared key auth",
1060 "%s", "no challenge");
1061 ic->ic_stats.is_rx_bad_auth++;
1062 estatus = IEEE80211_STATUS_CHALLENGE;
1065 if (challenge[1] != IEEE80211_CHALLENGE_LEN) {
1066 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1067 ni->ni_macaddr, "shared key auth",
1068 "bad challenge len %d", challenge[1]);
1069 ic->ic_stats.is_rx_bad_auth++;
1070 estatus = IEEE80211_STATUS_CHALLENGE;
1076 switch (ic->ic_opmode) {
1077 case IEEE80211_M_MONITOR:
1078 case IEEE80211_M_AHDEMO:
1079 case IEEE80211_M_IBSS:
1080 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1081 ni->ni_macaddr, "shared key auth",
1082 "bad operating mode %u", ic->ic_opmode);
1084 case IEEE80211_M_HOSTAP:
1085 if (ic->ic_state != IEEE80211_S_RUN) {
1086 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1087 ni->ni_macaddr, "shared key auth",
1088 "bad state %u", ic->ic_state);
1089 estatus = IEEE80211_STATUS_ALG; /* XXX */
1093 case IEEE80211_AUTH_SHARED_REQUEST:
1094 if (ni == ic->ic_bss) {
1095 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
1097 /* NB: no way to return an error */
1102 if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)
1103 (void) ieee80211_ref_node(ni);
1107 * Mark the node as referenced to reflect that it's
1108 * reference count has been bumped to insure it remains
1109 * after the transaction completes.
1111 ni->ni_flags |= IEEE80211_NODE_AREF;
1113 ni->ni_rstamp = rstamp;
1114 if (!alloc_challenge(ic, ni)) {
1115 /* NB: don't return error so they rexmit */
1118 get_random_bytes(ni->ni_challenge,
1119 IEEE80211_CHALLENGE_LEN);
1120 IEEE80211_DPRINTF(ic,
1121 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1122 "[%6D] shared key %sauth request\n",
1123 ni->ni_macaddr, ":",
1124 allocbs ? "" : "re");
1126 case IEEE80211_AUTH_SHARED_RESPONSE:
1127 if (ni == ic->ic_bss) {
1128 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1129 ni->ni_macaddr, "shared key response",
1130 "%s", "unknown station");
1131 /* NB: don't send a response */
1134 if (ni->ni_challenge == NULL) {
1135 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1136 ni->ni_macaddr, "shared key response",
1137 "%s", "no challenge recorded");
1138 ic->ic_stats.is_rx_bad_auth++;
1139 estatus = IEEE80211_STATUS_CHALLENGE;
1142 if (memcmp(ni->ni_challenge, &challenge[2],
1143 challenge[1]) != 0) {
1144 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1145 ni->ni_macaddr, "shared key response",
1146 "%s", "challenge mismatch");
1147 ic->ic_stats.is_rx_auth_fail++;
1148 estatus = IEEE80211_STATUS_CHALLENGE;
1151 IEEE80211_DPRINTF(ic,
1152 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1153 "[%6D] station authenticated (shared key)\n",
1154 ni->ni_macaddr, ":");
1155 ieee80211_node_authorize(ni);
1158 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1159 ni->ni_macaddr, "shared key auth",
1161 ic->ic_stats.is_rx_bad_auth++;
1162 estatus = IEEE80211_STATUS_SEQUENCE;
1165 IEEE80211_SEND_MGMT(ic, ni,
1166 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
1169 case IEEE80211_M_STA:
1170 if (ic->ic_state != IEEE80211_S_AUTH)
1173 case IEEE80211_AUTH_SHARED_PASS:
1174 if (ni->ni_challenge != NULL) {
1175 FREE(ni->ni_challenge, M_DEVBUF);
1176 ni->ni_challenge = NULL;
1179 IEEE80211_DPRINTF(ic,
1180 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1181 "[%6D] shared key auth failed (reason %d)\n",
1182 ieee80211_getbssid(ic, wh), ":", status);
1183 /* XXX can this happen? */
1184 if (ni != ic->ic_bss)
1186 ic->ic_stats.is_rx_auth_fail++;
1189 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
1190 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1192 case IEEE80211_AUTH_SHARED_CHALLENGE:
1193 if (!alloc_challenge(ic, ni))
1195 /* XXX could optimize by passing recvd challenge */
1196 memcpy(ni->ni_challenge, &challenge[2], challenge[1]);
1197 IEEE80211_SEND_MGMT(ic, ni,
1198 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
1201 IEEE80211_DISCARD(ic, IEEE80211_MSG_AUTH,
1202 wh, "shared key auth", "bad seq %d", seq);
1203 ic->ic_stats.is_rx_bad_auth++;
1211 * Send an error response; but only when operating as an AP.
1213 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1214 /* XXX hack to workaround calling convention */
1215 ieee80211_send_error(ic, ni, wh->i_addr2,
1216 IEEE80211_FC0_SUBTYPE_AUTH,
1217 (seq + 1) | (estatus<<16));
1218 } else if (ic->ic_opmode == IEEE80211_M_STA) {
1220 * Kick the state machine. This short-circuits
1221 * using the mgt frame timeout to trigger the
1224 if (ic->ic_state == IEEE80211_S_AUTH)
1225 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
1229 /* Verify the existence and length of __elem or get out. */
1230 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
1231 if ((__elem) == NULL) { \
1232 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1233 wh, ieee80211_mgt_subtype_name[subtype >> \
1234 IEEE80211_FC0_SUBTYPE_SHIFT], \
1235 "%s", "no " #__elem ); \
1236 ic->ic_stats.is_rx_elem_missing++; \
1239 if ((__elem)[1] > (__maxlen)) { \
1240 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1241 wh, ieee80211_mgt_subtype_name[subtype >> \
1242 IEEE80211_FC0_SUBTYPE_SHIFT], \
1243 "bad " #__elem " len %d", (__elem)[1]); \
1244 ic->ic_stats.is_rx_elem_toobig++; \
1249 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
1250 if ((_len) < (_minlen)) { \
1251 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1252 wh, ieee80211_mgt_subtype_name[subtype >> \
1253 IEEE80211_FC0_SUBTYPE_SHIFT], \
1254 "%s", "ie too short"); \
1255 ic->ic_stats.is_rx_elem_toosmall++; \
1260 #ifdef IEEE80211_DEBUG
1262 ieee80211_ssid_mismatch(struct ieee80211com *ic, const char *tag,
1263 uint8_t mac[IEEE80211_ADDR_LEN], uint8_t *ssid)
1265 printf("[%6D] discard %s frame, ssid mismatch: ", mac, ":", tag);
1266 ieee80211_print_essid(ssid + 2, ssid[1]);
1270 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1271 if ((_ssid)[1] != 0 && \
1272 ((_ssid)[1] != (_ni)->ni_esslen || \
1273 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1274 if (ieee80211_msg_input(ic)) \
1275 ieee80211_ssid_mismatch(ic, \
1276 ieee80211_mgt_subtype_name[subtype >> \
1277 IEEE80211_FC0_SUBTYPE_SHIFT], \
1278 wh->i_addr2, _ssid); \
1279 ic->ic_stats.is_rx_ssidmismatch++; \
1283 #else /* !IEEE80211_DEBUG */
1284 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1285 if ((_ssid)[1] != 0 && \
1286 ((_ssid)[1] != (_ni)->ni_esslen || \
1287 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1288 ic->ic_stats.is_rx_ssidmismatch++; \
1292 #endif /* !IEEE80211_DEBUG */
1294 /* unalligned little endian access */
1295 #define LE_READ_2(p) \
1297 ((((const uint8_t *)(p))[0] ) | \
1298 (((const uint8_t *)(p))[1] << 8)))
1299 #define LE_READ_4(p) \
1301 ((((const uint8_t *)(p))[0] ) | \
1302 (((const uint8_t *)(p))[1] << 8) | \
1303 (((const uint8_t *)(p))[2] << 16) | \
1304 (((const uint8_t *)(p))[3] << 24)))
1307 iswpaoui(const uint8_t *frm)
1309 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
1313 iswmeoui(const uint8_t *frm)
1315 return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI);
1319 iswmeparam(const uint8_t *frm)
1321 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1322 frm[6] == WME_PARAM_OUI_SUBTYPE;
1326 iswmeinfo(const uint8_t *frm)
1328 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1329 frm[6] == WME_INFO_OUI_SUBTYPE;
1333 isatherosoui(const uint8_t *frm)
1335 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
1339 * Convert a WPA cipher selector OUI to an internal
1340 * cipher algorithm. Where appropriate we also
1341 * record any key length.
1344 wpa_cipher(uint8_t *sel, uint8_t *keylen)
1346 #define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1347 uint32_t w = LE_READ_4(sel);
1350 case WPA_SEL(WPA_CSE_NULL):
1351 return IEEE80211_CIPHER_NONE;
1352 case WPA_SEL(WPA_CSE_WEP40):
1354 *keylen = 40 / NBBY;
1355 return IEEE80211_CIPHER_WEP;
1356 case WPA_SEL(WPA_CSE_WEP104):
1358 *keylen = 104 / NBBY;
1359 return IEEE80211_CIPHER_WEP;
1360 case WPA_SEL(WPA_CSE_TKIP):
1361 return IEEE80211_CIPHER_TKIP;
1362 case WPA_SEL(WPA_CSE_CCMP):
1363 return IEEE80211_CIPHER_AES_CCM;
1365 return 32; /* NB: so 1<< is discarded */
1370 * Convert a WPA key management/authentication algorithm
1371 * to an internal code.
1374 wpa_keymgmt(uint8_t *sel)
1376 #define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1377 uint32_t w = LE_READ_4(sel);
1380 case WPA_SEL(WPA_ASE_8021X_UNSPEC):
1381 return WPA_ASE_8021X_UNSPEC;
1382 case WPA_SEL(WPA_ASE_8021X_PSK):
1383 return WPA_ASE_8021X_PSK;
1384 case WPA_SEL(WPA_ASE_NONE):
1385 return WPA_ASE_NONE;
1387 return 0; /* NB: so is discarded */
1392 * Parse a WPA information element to collect parameters
1393 * and validate the parameters against what has been
1394 * configured for the system.
1397 ieee80211_parse_wpa(struct ieee80211com *ic, uint8_t *frm,
1398 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh)
1400 uint8_t len = frm[1];
1405 * Check the length once for fixed parts: OUI, type,
1406 * version, mcast cipher, and 2 selector counts.
1407 * Other, variable-length data, must be checked separately.
1409 if ((ic->ic_flags & IEEE80211_F_WPA1) == 0) {
1410 IEEE80211_DISCARD_IE(ic,
1411 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1412 wh, "WPA", "not WPA, flags 0x%x", ic->ic_flags);
1413 return IEEE80211_REASON_IE_INVALID;
1416 IEEE80211_DISCARD_IE(ic,
1417 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1418 wh, "WPA", "too short, len %u", len);
1419 return IEEE80211_REASON_IE_INVALID;
1421 frm += 6, len -= 4; /* NB: len is payload only */
1422 /* NB: iswapoui already validated the OUI and type */
1424 if (w != WPA_VERSION) {
1425 IEEE80211_DISCARD_IE(ic,
1426 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1427 wh, "WPA", "bad version %u", w);
1428 return IEEE80211_REASON_IE_INVALID;
1432 /* multicast/group cipher */
1433 w = wpa_cipher(frm, &rsn->rsn_mcastkeylen);
1434 if (w != rsn->rsn_mcastcipher) {
1435 IEEE80211_DISCARD_IE(ic,
1436 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1437 wh, "WPA", "mcast cipher mismatch; got %u, expected %u",
1438 w, rsn->rsn_mcastcipher);
1439 return IEEE80211_REASON_IE_INVALID;
1443 /* unicast ciphers */
1447 IEEE80211_DISCARD_IE(ic,
1448 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1449 wh, "WPA", "ucast cipher data too short; len %u, n %u",
1451 return IEEE80211_REASON_IE_INVALID;
1454 for (; n > 0; n--) {
1455 w |= 1<<wpa_cipher(frm, &rsn->rsn_ucastkeylen);
1458 w &= rsn->rsn_ucastcipherset;
1460 IEEE80211_DISCARD_IE(ic,
1461 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1462 wh, "WPA", "%s", "ucast cipher set empty");
1463 return IEEE80211_REASON_IE_INVALID;
1465 if (w & (1<<IEEE80211_CIPHER_TKIP))
1466 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
1468 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
1470 /* key management algorithms */
1474 IEEE80211_DISCARD_IE(ic,
1475 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1476 wh, "WPA", "key mgmt alg data too short; len %u, n %u",
1478 return IEEE80211_REASON_IE_INVALID;
1481 for (; n > 0; n--) {
1482 w |= wpa_keymgmt(frm);
1485 w &= rsn->rsn_keymgmtset;
1487 IEEE80211_DISCARD_IE(ic,
1488 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1489 wh, "WPA", "%s", "no acceptable key mgmt alg");
1490 return IEEE80211_REASON_IE_INVALID;
1492 if (w & WPA_ASE_8021X_UNSPEC)
1493 rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC;
1495 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK;
1497 if (len > 2) /* optional capabilities */
1498 rsn->rsn_caps = LE_READ_2(frm);
1504 * Convert an RSN cipher selector OUI to an internal
1505 * cipher algorithm. Where appropriate we also
1506 * record any key length.
1509 rsn_cipher(uint8_t *sel, uint8_t *keylen)
1511 #define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1512 uint32_t w = LE_READ_4(sel);
1515 case RSN_SEL(RSN_CSE_NULL):
1516 return IEEE80211_CIPHER_NONE;
1517 case RSN_SEL(RSN_CSE_WEP40):
1519 *keylen = 40 / NBBY;
1520 return IEEE80211_CIPHER_WEP;
1521 case RSN_SEL(RSN_CSE_WEP104):
1523 *keylen = 104 / NBBY;
1524 return IEEE80211_CIPHER_WEP;
1525 case RSN_SEL(RSN_CSE_TKIP):
1526 return IEEE80211_CIPHER_TKIP;
1527 case RSN_SEL(RSN_CSE_CCMP):
1528 return IEEE80211_CIPHER_AES_CCM;
1529 case RSN_SEL(RSN_CSE_WRAP):
1530 return IEEE80211_CIPHER_AES_OCB;
1532 return 32; /* NB: so 1<< is discarded */
1537 * Convert an RSN key management/authentication algorithm
1538 * to an internal code.
1541 rsn_keymgmt(uint8_t *sel)
1543 #define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1544 uint32_t w = LE_READ_4(sel);
1547 case RSN_SEL(RSN_ASE_8021X_UNSPEC):
1548 return RSN_ASE_8021X_UNSPEC;
1549 case RSN_SEL(RSN_ASE_8021X_PSK):
1550 return RSN_ASE_8021X_PSK;
1551 case RSN_SEL(RSN_ASE_NONE):
1552 return RSN_ASE_NONE;
1554 return 0; /* NB: so is discarded */
1559 * Parse a WPA/RSN information element to collect parameters
1560 * and validate the parameters against what has been
1561 * configured for the system.
1564 ieee80211_parse_rsn(struct ieee80211com *ic, uint8_t *frm,
1565 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh)
1567 uint8_t len = frm[1];
1572 * Check the length once for fixed parts:
1573 * version, mcast cipher, and 2 selector counts.
1574 * Other, variable-length data, must be checked separately.
1576 if ((ic->ic_flags & IEEE80211_F_WPA2) == 0) {
1577 IEEE80211_DISCARD_IE(ic,
1578 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1579 wh, "WPA", "not RSN, flags 0x%x", ic->ic_flags);
1580 return IEEE80211_REASON_IE_INVALID;
1583 IEEE80211_DISCARD_IE(ic,
1584 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1585 wh, "RSN", "too short, len %u", len);
1586 return IEEE80211_REASON_IE_INVALID;
1590 if (w != RSN_VERSION) {
1591 IEEE80211_DISCARD_IE(ic,
1592 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1593 wh, "RSN", "bad version %u", w);
1594 return IEEE80211_REASON_IE_INVALID;
1598 /* multicast/group cipher */
1599 w = rsn_cipher(frm, &rsn->rsn_mcastkeylen);
1600 if (w != rsn->rsn_mcastcipher) {
1601 IEEE80211_DISCARD_IE(ic,
1602 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1603 wh, "RSN", "mcast cipher mismatch; got %u, expected %u",
1604 w, rsn->rsn_mcastcipher);
1605 return IEEE80211_REASON_IE_INVALID;
1609 /* unicast ciphers */
1613 IEEE80211_DISCARD_IE(ic,
1614 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1615 wh, "RSN", "ucast cipher data too short; len %u, n %u",
1617 return IEEE80211_REASON_IE_INVALID;
1620 for (; n > 0; n--) {
1621 w |= 1<<rsn_cipher(frm, &rsn->rsn_ucastkeylen);
1624 w &= rsn->rsn_ucastcipherset;
1626 IEEE80211_DISCARD_IE(ic,
1627 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1628 wh, "RSN", "%s", "ucast cipher set empty");
1629 return IEEE80211_REASON_IE_INVALID;
1631 if (w & (1<<IEEE80211_CIPHER_TKIP))
1632 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
1634 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
1636 /* key management algorithms */
1640 IEEE80211_DISCARD_IE(ic,
1641 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1642 wh, "RSN", "key mgmt alg data too short; len %u, n %u",
1644 return IEEE80211_REASON_IE_INVALID;
1647 for (; n > 0; n--) {
1648 w |= rsn_keymgmt(frm);
1651 w &= rsn->rsn_keymgmtset;
1653 IEEE80211_DISCARD_IE(ic,
1654 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1655 wh, "RSN", "%s", "no acceptable key mgmt alg");
1656 return IEEE80211_REASON_IE_INVALID;
1658 if (w & RSN_ASE_8021X_UNSPEC)
1659 rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC;
1661 rsn->rsn_keymgmt = RSN_ASE_8021X_PSK;
1663 /* optional RSN capabilities */
1665 rsn->rsn_caps = LE_READ_2(frm);
1672 ieee80211_parse_wmeparams(struct ieee80211com *ic, uint8_t *frm,
1673 const struct ieee80211_frame *wh)
1675 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
1676 struct ieee80211_wme_state *wme = &ic->ic_wme;
1677 u_int len = frm[1], qosinfo;
1680 if (len < sizeof(struct ieee80211_wme_param)-2) {
1681 IEEE80211_DISCARD_IE(ic,
1682 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME,
1683 wh, "WME", "too short, len %u", len);
1686 qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)];
1687 qosinfo &= WME_QOSINFO_COUNT;
1688 /* XXX do proper check for wraparound */
1689 if (qosinfo == wme->wme_wmeChanParams.cap_info)
1691 frm += __offsetof(struct ieee80211_wme_param, params_acParams);
1692 for (i = 0; i < WME_NUM_AC; i++) {
1693 struct wmeParams *wmep =
1694 &wme->wme_wmeChanParams.cap_wmeParams[i];
1695 /* NB: ACI not used */
1696 wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM);
1697 wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN);
1698 wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN);
1699 wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX);
1700 wmep->wmep_txopLimit = LE_READ_2(frm+2);
1703 wme->wme_wmeChanParams.cap_info = qosinfo;
1709 ieee80211_saveie(uint8_t **iep, const uint8_t *ie)
1711 u_int ielen = ie[1]+2;
1713 * Record information element for later use.
1715 if (*iep == NULL || (*iep)[1] != ie[1]) {
1717 FREE(*iep, M_DEVBUF);
1718 MALLOC(*iep, void*, ielen, M_DEVBUF, M_NOWAIT);
1721 memcpy(*iep, ie, ielen);
1722 /* XXX note failure */
1725 /* XXX find a better place for definition */
1726 struct l2_update_frame {
1727 struct ether_header eh;
1735 * Deliver a TGf L2UF frame on behalf of a station.
1736 * This primes any bridge when the station is roaming
1737 * between ap's on the same wired network.
1740 ieee80211_deliver_l2uf(struct ieee80211_node *ni)
1742 struct ieee80211com *ic = ni->ni_ic;
1743 struct ifnet *ifp = ic->ic_ifp;
1745 struct l2_update_frame *l2uf;
1746 struct ether_header *eh;
1748 m = m_gethdr(M_NOWAIT, MT_DATA);
1750 IEEE80211_NOTE(ic, IEEE80211_MSG_ASSOC, ni,
1751 "%s", "no mbuf for l2uf frame");
1752 ic->ic_stats.is_rx_nobuf++; /* XXX not right */
1755 l2uf = mtod(m, struct l2_update_frame *);
1757 /* dst: Broadcast address */
1758 IEEE80211_ADDR_COPY(eh->ether_dhost, ifp->if_broadcastaddr);
1759 /* src: associated STA */
1760 IEEE80211_ADDR_COPY(eh->ether_shost, ni->ni_macaddr);
1761 eh->ether_type = htons(sizeof(*l2uf) - sizeof(*eh));
1765 l2uf->control = 0xf5;
1766 l2uf->xid[0] = 0x81;
1767 l2uf->xid[1] = 0x80;
1768 l2uf->xid[2] = 0x00;
1770 m->m_pkthdr.len = m->m_len = sizeof(*l2uf);
1771 m->m_pkthdr.rcvif = ifp;
1772 ieee80211_deliver_data(ic, ni, m);
1776 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
1777 struct ieee80211_node *ni,
1778 int subtype, int rssi, uint32_t rstamp)
1780 #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1781 #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
1782 struct ieee80211_frame *wh;
1783 uint8_t *frm, *efrm;
1784 uint8_t *ssid, *rates, *xrates, *wpa, *wme;
1785 int reassoc, resp, allocbs;
1788 wh = mtod(m0, struct ieee80211_frame *);
1789 frm = (uint8_t *)&wh[1];
1790 efrm = mtod(m0, uint8_t *) + m0->m_len;
1792 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1793 case IEEE80211_FC0_SUBTYPE_BEACON: {
1794 struct ieee80211_scanparams scan;
1797 * We process beacon/probe response frames:
1798 * o when scanning, or
1799 * o station mode when associated (to collect state
1800 * updates such as 802.11g slot time), or
1801 * o adhoc mode (to discover neighbors)
1802 * Frames otherwise received are discarded.
1804 if (!((ic->ic_flags & IEEE80211_F_SCAN) ||
1805 (ic->ic_opmode == IEEE80211_M_STA && ni->ni_associd) ||
1806 ic->ic_opmode == IEEE80211_M_IBSS)) {
1807 ic->ic_stats.is_rx_mgtdiscard++;
1811 * beacon/probe response frame format
1813 * [2] beacon interval
1814 * [2] capability information
1816 * [tlv] supported rates
1817 * [tlv] country information
1818 * [tlv] parameter set (FH/DS)
1819 * [tlv] erp information
1820 * [tlv] extended supported rates
1824 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
1825 memset(&scan, 0, sizeof(scan));
1826 scan.tstamp = frm; frm += 8;
1827 scan.bintval = le16toh(*(uint16_t *)frm); frm += 2;
1828 scan.capinfo = le16toh(*(uint16_t *)frm); frm += 2;
1829 scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
1830 scan.chan = scan.bchan;
1832 while (frm < efrm) {
1833 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]);
1835 case IEEE80211_ELEMID_SSID:
1838 case IEEE80211_ELEMID_RATES:
1841 case IEEE80211_ELEMID_COUNTRY:
1844 case IEEE80211_ELEMID_FHPARMS:
1845 if (ic->ic_phytype == IEEE80211_T_FH) {
1846 scan.fhdwell = LE_READ_2(&frm[2]);
1847 scan.chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
1848 scan.fhindex = frm[6];
1851 case IEEE80211_ELEMID_DSPARMS:
1853 * XXX hack this since depending on phytype
1854 * is problematic for multi-mode devices.
1856 if (ic->ic_phytype != IEEE80211_T_FH)
1859 case IEEE80211_ELEMID_TIM:
1862 scan.timoff = frm - mtod(m0, uint8_t *);
1864 case IEEE80211_ELEMID_IBSSPARMS:
1866 case IEEE80211_ELEMID_XRATES:
1869 case IEEE80211_ELEMID_ERP:
1871 IEEE80211_DISCARD_IE(ic,
1872 IEEE80211_MSG_ELEMID, wh, "ERP",
1873 "bad len %u", frm[1]);
1874 ic->ic_stats.is_rx_elem_toobig++;
1879 case IEEE80211_ELEMID_RSN:
1882 case IEEE80211_ELEMID_VENDOR:
1885 else if (iswmeparam(frm) || iswmeinfo(frm))
1887 /* XXX Atheros OUI support */
1890 IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID,
1892 "id %u, len %u", *frm, frm[1]);
1893 ic->ic_stats.is_rx_elem_unknown++;
1898 IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE);
1899 IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN);
1901 #if IEEE80211_CHAN_MAX < 255
1902 scan.chan > IEEE80211_CHAN_MAX ||
1904 isclr(ic->ic_chan_active, scan.chan)) {
1905 IEEE80211_DISCARD(ic,
1906 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
1907 wh, ieee80211_mgt_subtype_name[subtype >>
1908 IEEE80211_FC0_SUBTYPE_SHIFT],
1909 "invalid channel %u", scan.chan);
1910 ic->ic_stats.is_rx_badchan++;
1913 if (scan.chan != scan.bchan &&
1914 ic->ic_phytype != IEEE80211_T_FH) {
1916 * Frame was received on a channel different from the
1917 * one indicated in the DS params element id;
1918 * silently discard it.
1920 * NB: this can happen due to signal leakage.
1921 * But we should take it for FH phy because
1922 * the rssi value should be correct even for
1923 * different hop pattern in FH.
1925 IEEE80211_DISCARD(ic,
1926 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
1927 wh, ieee80211_mgt_subtype_name[subtype >>
1928 IEEE80211_FC0_SUBTYPE_SHIFT],
1929 "for off-channel %u", scan.chan);
1930 ic->ic_stats.is_rx_chanmismatch++;
1933 if (!(IEEE80211_BINTVAL_MIN <= scan.bintval &&
1934 scan.bintval <= IEEE80211_BINTVAL_MAX)) {
1935 IEEE80211_DISCARD(ic,
1936 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
1937 wh, ieee80211_mgt_subtype_name[subtype >>
1938 IEEE80211_FC0_SUBTYPE_SHIFT],
1939 "bogus beacon interval", scan.bintval);
1940 ic->ic_stats.is_rx_badbintval++;
1945 * Count frame now that we know it's to be processed.
1947 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
1948 ic->ic_stats.is_rx_beacon++; /* XXX remove */
1949 IEEE80211_NODE_STAT(ni, rx_beacons);
1951 IEEE80211_NODE_STAT(ni, rx_proberesp);
1954 * When operating in station mode, check for state updates.
1955 * Be careful to ignore beacons received while doing a
1956 * background scan. We consider only 11g/WMM stuff right now.
1958 if (ic->ic_opmode == IEEE80211_M_STA &&
1959 ni->ni_associd != 0 &&
1960 ((ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
1961 IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) {
1962 /* record tsf of last beacon */
1963 memcpy(ni->ni_tstamp.data, scan.tstamp,
1964 sizeof(ni->ni_tstamp));
1965 /* count beacon frame for s/w bmiss handling */
1966 ic->ic_swbmiss_count++;
1967 ic->ic_bmiss_count = 0;
1968 if (ni->ni_erp != scan.erp) {
1969 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1970 "[%6D] erp change: was 0x%x, now 0x%x\n",
1971 wh->i_addr2, ":", ni->ni_erp, scan.erp);
1972 if (ic->ic_curmode == IEEE80211_MODE_11G &&
1973 (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
1974 ic->ic_flags |= IEEE80211_F_USEPROT;
1976 ic->ic_flags &= ~IEEE80211_F_USEPROT;
1977 ni->ni_erp = scan.erp;
1980 if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
1981 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1982 "[%6D] capabilities change: before 0x%x,"
1985 ni->ni_capinfo, scan.capinfo);
1987 * NB: we assume short preamble doesn't
1988 * change dynamically
1990 ieee80211_set_shortslottime(ic,
1991 ic->ic_curmode == IEEE80211_MODE_11A ||
1992 (scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1993 ni->ni_capinfo = scan.capinfo;
1996 if (scan.wme != NULL &&
1997 (ni->ni_flags & IEEE80211_NODE_QOS) &&
1998 ieee80211_parse_wmeparams(ic, scan.wme, wh) > 0)
1999 ieee80211_wme_updateparams(ic);
2000 if (scan.tim != NULL) {
2001 struct ieee80211_tim_ie *ie =
2002 (struct ieee80211_tim_ie *) scan.tim;
2004 ni->ni_dtim_count = ie->tim_count;
2005 ni->ni_dtim_period = ie->tim_period;
2007 if (ic->ic_flags & IEEE80211_F_SCAN)
2008 ieee80211_add_scan(ic, &scan, wh,
2009 subtype, rssi, rstamp);
2013 * If scanning, just pass information to the scan module.
2015 if (ic->ic_flags & IEEE80211_F_SCAN) {
2016 if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) {
2018 * Actively scanning a channel marked passive;
2019 * send a probe request now that we know there
2020 * is 802.11 traffic present.
2022 * XXX check if the beacon we recv'd gives
2023 * us what we need and suppress the probe req
2025 ieee80211_probe_curchan(ic, 1);
2026 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
2028 ieee80211_add_scan(ic, &scan, wh,
2029 subtype, rssi, rstamp);
2032 if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
2033 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
2035 * Create a new entry in the neighbor table.
2037 ni = ieee80211_add_neighbor(ic, wh, &scan);
2038 } else if (ni->ni_capinfo == 0) {
2040 * Update faked node created on transmit.
2041 * Note this also updates the tsf.
2043 ieee80211_init_neighbor(ni, wh, &scan);
2046 * Record tsf for potential resync.
2048 memcpy(ni->ni_tstamp.data, scan.tstamp,
2049 sizeof(ni->ni_tstamp));
2053 ni->ni_rstamp = rstamp;
2059 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
2060 if (ic->ic_opmode == IEEE80211_M_STA ||
2061 ic->ic_state != IEEE80211_S_RUN) {
2062 ic->ic_stats.is_rx_mgtdiscard++;
2065 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
2066 /* frame must be directed */
2067 ic->ic_stats.is_rx_mgtdiscard++; /* XXX stat */
2072 * prreq frame format
2074 * [tlv] supported rates
2075 * [tlv] extended supported rates
2077 ssid = rates = xrates = NULL;
2078 while (frm < efrm) {
2079 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]);
2081 case IEEE80211_ELEMID_SSID:
2084 case IEEE80211_ELEMID_RATES:
2087 case IEEE80211_ELEMID_XRATES:
2093 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2094 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
2095 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid);
2096 if ((ic->ic_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) {
2097 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
2098 wh, ieee80211_mgt_subtype_name[subtype >>
2099 IEEE80211_FC0_SUBTYPE_SHIFT],
2100 "%s", "no ssid with ssid suppression enabled");
2101 ic->ic_stats.is_rx_ssidmismatch++; /*XXX*/
2106 if (ni == ic->ic_bss) {
2107 if (ic->ic_opmode != IEEE80211_M_IBSS) {
2108 ni = ieee80211_tmp_node(ic, wh->i_addr2);
2110 } else if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
2112 * XXX Cannot tell if the sender is operating
2113 * in ibss mode. But we need a new node to
2114 * send the response so blindly add them to the
2117 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
2123 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2124 "[%6D] recv probe req\n", wh->i_addr2, ":");
2126 ni->ni_rstamp = rstamp;
2127 rate = ieee80211_setup_rates(ni, rates, xrates,
2128 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
2129 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2130 if (rate & IEEE80211_RATE_BASIC) {
2131 IEEE80211_DISCARD(ic, IEEE80211_MSG_XRATE,
2132 wh, ieee80211_mgt_subtype_name[subtype >>
2133 IEEE80211_FC0_SUBTYPE_SHIFT],
2134 "%s", "recv'd rate set invalid");
2136 IEEE80211_SEND_MGMT(ic, ni,
2137 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
2141 * Temporary node created just to send a
2142 * response, reclaim immediately.
2144 ieee80211_free_node(ni);
2148 case IEEE80211_FC0_SUBTYPE_AUTH: {
2149 uint16_t algo, seq, status;
2157 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
2158 algo = le16toh(*(uint16_t *)frm);
2159 seq = le16toh(*(uint16_t *)(frm + 2));
2160 status = le16toh(*(uint16_t *)(frm + 4));
2161 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
2162 "[%6D] recv auth frame with algorithm %d seq %d\n",
2163 wh->i_addr2, ":", algo, seq);
2165 * Consult the ACL policy module if setup.
2167 if (ic->ic_acl != NULL &&
2168 !ic->ic_acl->iac_check(ic, wh->i_addr2)) {
2169 IEEE80211_DISCARD(ic, IEEE80211_MSG_ACL,
2170 wh, "auth", "%s", "disallowed by ACL");
2171 ic->ic_stats.is_rx_acl++;
2172 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2173 IEEE80211_SEND_MGMT(ic, ni,
2174 IEEE80211_FC0_SUBTYPE_AUTH,
2175 (seq+1) | (IEEE80211_STATUS_UNSPECIFIED<<16));
2179 if (ic->ic_flags & IEEE80211_F_COUNTERM) {
2180 IEEE80211_DISCARD(ic,
2181 IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO,
2182 wh, "auth", "%s", "TKIP countermeasures enabled");
2183 ic->ic_stats.is_rx_auth_countermeasures++;
2184 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2185 IEEE80211_SEND_MGMT(ic, ni,
2186 IEEE80211_FC0_SUBTYPE_AUTH,
2187 IEEE80211_REASON_MIC_FAILURE);
2191 if (algo == IEEE80211_AUTH_ALG_SHARED)
2192 ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi,
2193 rstamp, seq, status);
2194 else if (algo == IEEE80211_AUTH_ALG_OPEN)
2195 ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq,
2198 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2199 wh, "auth", "unsupported alg %d", algo);
2200 ic->ic_stats.is_rx_auth_unsupported++;
2201 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2203 IEEE80211_SEND_MGMT(ic, ni,
2204 IEEE80211_FC0_SUBTYPE_AUTH,
2205 (seq+1) | (IEEE80211_STATUS_ALG<<16));
2212 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
2213 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
2214 uint16_t capinfo, lintval;
2215 struct ieee80211_rsnparms rsn;
2218 if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
2219 ic->ic_state != IEEE80211_S_RUN) {
2220 ic->ic_stats.is_rx_mgtdiscard++;
2224 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
2226 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
2229 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
2232 * asreq frame format
2233 * [2] capability information
2234 * [2] listen interval
2235 * [6*] current AP address (reassoc only)
2237 * [tlv] supported rates
2238 * [tlv] extended supported rates
2241 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4));
2242 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
2243 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2244 wh, ieee80211_mgt_subtype_name[subtype >>
2245 IEEE80211_FC0_SUBTYPE_SHIFT],
2246 "%s", "wrong bssid");
2247 ic->ic_stats.is_rx_assoc_bss++;
2250 capinfo = le16toh(*(uint16_t *)frm); frm += 2;
2251 lintval = le16toh(*(uint16_t *)frm); frm += 2;
2253 frm += 6; /* ignore current AP info */
2254 ssid = rates = xrates = wpa = wme = NULL;
2255 while (frm < efrm) {
2256 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]);
2258 case IEEE80211_ELEMID_SSID:
2261 case IEEE80211_ELEMID_RATES:
2264 case IEEE80211_ELEMID_XRATES:
2267 /* XXX verify only one of RSN and WPA ie's? */
2268 case IEEE80211_ELEMID_RSN:
2271 case IEEE80211_ELEMID_VENDOR:
2274 else if (iswmeinfo(frm))
2276 /* XXX Atheros OUI support */
2281 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2282 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
2283 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid);
2285 if (ni == ic->ic_bss) {
2286 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
2287 "[%6D] deny %s request, sta not authenticated\n",
2288 wh->i_addr2, ":", reassoc ? "reassoc" : "assoc");
2289 ieee80211_send_error(ic, ni, wh->i_addr2,
2290 IEEE80211_FC0_SUBTYPE_DEAUTH,
2291 IEEE80211_REASON_ASSOC_NOT_AUTHED);
2292 ic->ic_stats.is_rx_assoc_notauth++;
2295 /* assert right associstion security credentials */
2296 if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) {
2297 IEEE80211_DPRINTF(ic,
2298 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
2299 "[%6D] no WPA/RSN IE in association request\n",
2301 IEEE80211_SEND_MGMT(ic, ni,
2302 IEEE80211_FC0_SUBTYPE_DEAUTH,
2303 IEEE80211_REASON_RSN_REQUIRED);
2304 ieee80211_node_leave(ic, ni);
2305 /* XXX distinguish WPA/RSN? */
2306 ic->ic_stats.is_rx_assoc_badwpaie++;
2311 * Parse WPA information element. Note that
2312 * we initialize the param block from the node
2313 * state so that information in the IE overrides
2314 * our defaults. The resulting parameters are
2315 * installed below after the association is assured.
2318 if (wpa[0] != IEEE80211_ELEMID_RSN)
2319 reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh);
2321 reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh);
2323 IEEE80211_SEND_MGMT(ic, ni,
2324 IEEE80211_FC0_SUBTYPE_DEAUTH, reason);
2325 ieee80211_node_leave(ic, ni);
2326 /* XXX distinguish WPA/RSN? */
2327 ic->ic_stats.is_rx_assoc_badwpaie++;
2330 IEEE80211_DPRINTF(ic,
2331 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
2332 "[%6D] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n",
2334 wpa[0] != IEEE80211_ELEMID_RSN ? "WPA" : "RSN",
2335 rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen,
2336 rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen,
2337 rsn.rsn_keymgmt, rsn.rsn_caps);
2339 /* discard challenge after association */
2340 if (ni->ni_challenge != NULL) {
2341 FREE(ni->ni_challenge, M_DEVBUF);
2342 ni->ni_challenge = NULL;
2344 /* NB: 802.11 spec says to ignore station's privacy bit */
2345 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0) {
2346 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
2347 "[%6D] deny %s request, capability mismatch 0x%x\n",
2349 reassoc ? "reassoc" : "assoc", capinfo);
2350 IEEE80211_SEND_MGMT(ic, ni, resp,
2351 IEEE80211_STATUS_CAPINFO);
2352 ieee80211_node_leave(ic, ni);
2353 ic->ic_stats.is_rx_assoc_capmismatch++;
2356 rate = ieee80211_setup_rates(ni, rates, xrates,
2357 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
2358 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2360 * If constrained to 11g-only stations reject an
2361 * 11b-only station. We cheat a bit here by looking
2362 * at the max negotiated xmit rate and assuming anyone
2363 * with a best rate <24Mb/s is an 11b station.
2365 if ((rate & IEEE80211_RATE_BASIC) ||
2366 ((ic->ic_flags & IEEE80211_F_PUREG) && rate < 48)) {
2367 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
2368 "[%6D] deny %s request, rate set mismatch\n",
2370 reassoc ? "reassoc" : "assoc");
2371 IEEE80211_SEND_MGMT(ic, ni, resp,
2372 IEEE80211_STATUS_BASIC_RATE);
2373 ieee80211_node_leave(ic, ni);
2374 ic->ic_stats.is_rx_assoc_norate++;
2378 ni->ni_rstamp = rstamp;
2379 ni->ni_intval = lintval;
2380 ni->ni_capinfo = capinfo;
2381 ni->ni_chan = ic->ic_bss->ni_chan;
2382 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
2383 ni->ni_fhindex = ic->ic_bss->ni_fhindex;
2386 * Record WPA/RSN parameters for station, mark
2387 * node as using WPA and record information element
2388 * for applications that require it.
2391 ieee80211_saveie(&ni->ni_wpa_ie, wpa);
2392 } else if (ni->ni_wpa_ie != NULL) {
2394 * Flush any state from a previous association.
2396 FREE(ni->ni_wpa_ie, M_DEVBUF);
2397 ni->ni_wpa_ie = NULL;
2401 * Record WME parameters for station, mark node
2402 * as capable of QoS and record information
2403 * element for applications that require it.
2405 ieee80211_saveie(&ni->ni_wme_ie, wme);
2406 ni->ni_flags |= IEEE80211_NODE_QOS;
2407 } else if (ni->ni_wme_ie != NULL) {
2409 * Flush any state from a previous association.
2411 FREE(ni->ni_wme_ie, M_DEVBUF);
2412 ni->ni_wme_ie = NULL;
2413 ni->ni_flags &= ~IEEE80211_NODE_QOS;
2415 ieee80211_deliver_l2uf(ni);
2416 ieee80211_node_join(ic, ni, resp);
2420 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
2421 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
2422 uint16_t capinfo, associd;
2425 if (ic->ic_opmode != IEEE80211_M_STA ||
2426 ic->ic_state != IEEE80211_S_ASSOC) {
2427 ic->ic_stats.is_rx_mgtdiscard++;
2432 * asresp frame format
2433 * [2] capability information
2435 * [2] association ID
2436 * [tlv] supported rates
2437 * [tlv] extended supported rates
2440 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
2442 capinfo = le16toh(*(uint16_t *)frm);
2444 status = le16toh(*(uint16_t *)frm);
2447 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2448 "[%6D] %sassoc failed (reason %d)\n",
2450 ISREASSOC(subtype) ? "re" : "", status);
2451 if (ni != ic->ic_bss) /* XXX never true? */
2453 ic->ic_stats.is_rx_auth_fail++; /* XXX */
2456 associd = le16toh(*(uint16_t *)frm);
2459 rates = xrates = wpa = wme = NULL;
2460 while (frm < efrm) {
2461 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]);
2463 case IEEE80211_ELEMID_RATES:
2466 case IEEE80211_ELEMID_XRATES:
2469 case IEEE80211_ELEMID_VENDOR:
2472 /* XXX Atheros OUI support */
2478 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2479 rate = ieee80211_setup_rates(ni, rates, xrates,
2480 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
2481 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2482 if (rate & IEEE80211_RATE_BASIC) {
2483 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2484 "[%6D] %sassoc failed (rate set mismatch)\n",
2486 ISREASSOC(subtype) ? "re" : "");
2487 if (ni != ic->ic_bss) /* XXX never true? */
2489 ic->ic_stats.is_rx_assoc_norate++;
2490 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
2494 ni->ni_capinfo = capinfo;
2495 ni->ni_associd = associd;
2497 ieee80211_parse_wmeparams(ic, wme, wh) >= 0) {
2498 ni->ni_flags |= IEEE80211_NODE_QOS;
2499 ieee80211_wme_updateparams(ic);
2501 ni->ni_flags &= ~IEEE80211_NODE_QOS;
2503 * Configure state now that we are associated.
2505 * XXX may need different/additional driver callbacks?
2507 if (ic->ic_curmode == IEEE80211_MODE_11A ||
2508 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
2509 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
2510 ic->ic_flags &= ~IEEE80211_F_USEBARKER;
2512 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
2513 ic->ic_flags |= IEEE80211_F_USEBARKER;
2515 ieee80211_set_shortslottime(ic,
2516 ic->ic_curmode == IEEE80211_MODE_11A ||
2517 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
2519 * Honor ERP protection.
2521 * NB: ni_erp should zero for non-11g operation.
2522 * XXX check ic_curmode anyway?
2524 if (ic->ic_curmode == IEEE80211_MODE_11G &&
2525 (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
2526 ic->ic_flags |= IEEE80211_F_USEPROT;
2528 ic->ic_flags &= ~IEEE80211_F_USEPROT;
2529 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2530 "[%6D] %sassoc success: %s preamble, %s slot time%s%s\n",
2532 ISREASSOC(subtype) ? "re" : "",
2533 ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
2534 ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
2535 ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
2536 ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : ""
2538 ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
2542 case IEEE80211_FC0_SUBTYPE_DEAUTH: {
2545 if (ic->ic_state == IEEE80211_S_SCAN) {
2546 ic->ic_stats.is_rx_mgtdiscard++;
2550 * deauth frame format
2553 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
2554 reason = le16toh(*(uint16_t *)frm);
2555 ic->ic_stats.is_rx_deauth++;
2556 IEEE80211_NODE_STAT(ni, rx_deauth);
2558 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
2559 "[%6D] recv deauthenticate (reason %d)\n",
2560 ni->ni_macaddr, ":", reason);
2561 switch (ic->ic_opmode) {
2562 case IEEE80211_M_STA:
2563 ieee80211_new_state(ic, IEEE80211_S_AUTH,
2564 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
2566 case IEEE80211_M_HOSTAP:
2567 if (ni != ic->ic_bss)
2568 ieee80211_node_leave(ic, ni);
2571 ic->ic_stats.is_rx_mgtdiscard++;
2577 case IEEE80211_FC0_SUBTYPE_DISASSOC: {
2580 if (ic->ic_state != IEEE80211_S_RUN &&
2581 ic->ic_state != IEEE80211_S_ASSOC &&
2582 ic->ic_state != IEEE80211_S_AUTH) {
2583 ic->ic_stats.is_rx_mgtdiscard++;
2587 * disassoc frame format
2590 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
2591 reason = le16toh(*(uint16_t *)frm);
2592 ic->ic_stats.is_rx_disassoc++;
2593 IEEE80211_NODE_STAT(ni, rx_disassoc);
2595 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2596 "[%6D] recv disassociate (reason %d)\n",
2597 ni->ni_macaddr, ":", reason);
2598 switch (ic->ic_opmode) {
2599 case IEEE80211_M_STA:
2600 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
2601 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
2603 case IEEE80211_M_HOSTAP:
2604 if (ni != ic->ic_bss)
2605 ieee80211_node_leave(ic, ni);
2608 ic->ic_stats.is_rx_mgtdiscard++;
2614 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2615 wh, "mgt", "subtype 0x%x not handled", subtype);
2616 ic->ic_stats.is_rx_badsubtype++;
2622 #undef IEEE80211_VERIFY_LENGTH
2623 #undef IEEE80211_VERIFY_ELEMENT
2626 * Handle station power-save state change.
2629 ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable)
2631 struct ieee80211com *ic = ni->ni_ic;
2634 ASSERT_SERIALIZED(ic->ic_ifp->if_serializer);
2637 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0)
2639 ni->ni_flags |= IEEE80211_NODE_PWR_MGT;
2640 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2641 "[%6D] power save mode on, %u sta's in ps mode\n",
2642 ni->ni_macaddr, ":", ic->ic_ps_sta);
2646 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT)
2648 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
2649 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2650 "[%6D] power save mode off, %u sta's in ps mode\n",
2651 ni->ni_macaddr, ":", ic->ic_ps_sta);
2652 /* XXX if no stations in ps mode, flush mc frames */
2655 * Flush queued unicast frames.
2657 if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) {
2658 if (ic->ic_set_tim != NULL)
2659 ic->ic_set_tim(ni, 0); /* just in case */
2662 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2663 "[%6D] flush ps queue, %u packets queued\n",
2664 ni->ni_macaddr, ":", IEEE80211_NODE_SAVEQ_QLEN(ni));
2668 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen);
2672 * If this is the last packet, turn off the TIM bit.
2673 * If there are more packets, set the more packets bit
2674 * in the mbuf so ieee80211_encap will mark the 802.11
2675 * head to indicate more data frames will follow.
2678 m->m_flags |= M_MORE_DATA;
2679 /* XXX need different driver interface */
2680 /* XXX bypasses q max */
2681 /* XXX bypasses ALTQ */
2682 ifq_enqueue(&ic->ic_ifp->if_snd, m, NULL);
2684 if (ic->ic_set_tim != NULL)
2685 ic->ic_set_tim(ni, 0);
2689 * Process a received ps-poll frame.
2692 ieee80211_recv_pspoll(struct ieee80211com *ic,
2693 struct ieee80211_node *ni, struct mbuf *m0)
2695 struct ieee80211_frame_min *wh;
2700 ASSERT_SERIALIZED(ic->ic_ifp->if_serializer);
2702 wh = mtod(m0, struct ieee80211_frame_min *);
2703 if (ni->ni_associd == 0) {
2704 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG,
2705 (struct ieee80211_frame *) wh, "ps-poll",
2706 "%s", "unassociated station");
2707 ic->ic_stats.is_ps_unassoc++;
2708 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
2709 IEEE80211_REASON_NOT_ASSOCED);
2713 aid = le16toh(*(uint16_t *)wh->i_dur);
2714 if (aid != ni->ni_associd) {
2715 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG,
2716 (struct ieee80211_frame *) wh, "ps-poll",
2717 "aid mismatch: sta aid 0x%x poll aid 0x%x",
2718 ni->ni_associd, aid);
2719 ic->ic_stats.is_ps_badaid++;
2720 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
2721 IEEE80211_REASON_NOT_ASSOCED);
2725 /* Okay, take the first queued packet and put it out... */
2726 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen);
2728 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2729 "[%6D] recv ps-poll, but queue empty\n",
2731 ieee80211_send_nulldata(ieee80211_ref_node(ni));
2732 ic->ic_stats.is_ps_qempty++; /* XXX node stat */
2733 if (ic->ic_set_tim != NULL)
2734 ic->ic_set_tim(ni, 0); /* just in case */
2738 * If there are more packets, set the more packets bit
2739 * in the packet dispatched to the station; otherwise
2740 * turn off the TIM bit.
2743 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2744 "[%6D] recv ps-poll, send packet, %u still queued\n",
2745 ni->ni_macaddr, ":", qlen);
2746 m->m_flags |= M_MORE_DATA;
2748 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2749 "[%6D] recv ps-poll, send packet, queue empty\n",
2750 ni->ni_macaddr, ":");
2751 if (ic->ic_set_tim != NULL)
2752 ic->ic_set_tim(ni, 0);
2754 m->m_flags |= M_PWR_SAV; /* bypass PS handling */
2755 ifq_enqueue(&ic->ic_ifp->if_snd, m, NULL); /* XXX bypasses ALTQ */
2758 #ifdef IEEE80211_DEBUG
2760 * Debugging support.
2764 * Return the bssid of a frame.
2766 static const uint8_t *
2767 ieee80211_getbssid(struct ieee80211com *ic, const struct ieee80211_frame *wh)
2769 if (ic->ic_opmode == IEEE80211_M_STA)
2771 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS)
2773 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
2779 ieee80211_note(struct ieee80211com *ic, const char *fmt, ...)
2781 char buf[128]; /* XXX */
2784 __va_start(ap, fmt);
2785 vsnprintf(buf, sizeof(buf), fmt, ap);
2788 if_printf(ic->ic_ifp, "%s", buf); /* NB: no \n */
2792 ieee80211_note_frame(struct ieee80211com *ic,
2793 const struct ieee80211_frame *wh,
2794 const char *fmt, ...)
2796 char buf[128]; /* XXX */
2799 __va_start(ap, fmt);
2800 vsnprintf(buf, sizeof(buf), fmt, ap);
2802 if_printf(ic->ic_ifp, "[%6D] %s\n",
2803 ieee80211_getbssid(ic, wh), ":", buf);
2807 ieee80211_note_mac(struct ieee80211com *ic,
2808 const uint8_t mac[IEEE80211_ADDR_LEN],
2809 const char *fmt, ...)
2811 char buf[128]; /* XXX */
2814 __va_start(ap, fmt);
2815 vsnprintf(buf, sizeof(buf), fmt, ap);
2817 if_printf(ic->ic_ifp, "[%6D] %s\n", mac, ":", buf);
2821 ieee80211_discard_frame(struct ieee80211com *ic,
2822 const struct ieee80211_frame *wh,
2823 const char *type, const char *fmt, ...)
2827 printf("[%s:%6D] discard ", ic->ic_ifp->if_xname,
2828 ieee80211_getbssid(ic, wh), ":");
2830 printf("%s frame, ", type);
2833 __va_start(ap, fmt);
2840 ieee80211_discard_ie(struct ieee80211com *ic,
2841 const struct ieee80211_frame *wh,
2842 const char *type, const char *fmt, ...)
2846 printf("[%s:%6D] discard ", ic->ic_ifp->if_xname,
2847 ieee80211_getbssid(ic, wh), ":");
2849 printf("%s information element, ", type);
2851 printf("information element, ");
2852 __va_start(ap, fmt);
2859 ieee80211_discard_mac(struct ieee80211com *ic,
2860 const uint8_t mac[IEEE80211_ADDR_LEN],
2861 const char *type, const char *fmt, ...)
2865 printf("[%s:%6D] discard ", ic->ic_ifp->if_xname, mac, ":");
2867 printf("%s frame, ", type);
2870 __va_start(ap, fmt);
2875 #endif /* IEEE80211_DEBUG */