Bug Summary

File:net80211/ieee80211_input.c
Warning:line 3065, column 2
Value stored to 'reason' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ieee80211_input.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/net80211/ieee80211_input.c
1/* $OpenBSD: ieee80211_input.c,v 1.242 2022/01/12 08:29:27 stsp Exp $ */
2
3/*-
4 * Copyright (c) 2001 Atsushi Onoe
5 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
6 * Copyright (c) 2007-2009 Damien Bergamini
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "bpfilter.h"
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/mbuf.h>
37#include <sys/malloc.h>
38#include <sys/kernel.h>
39#include <sys/socket.h>
40#include <sys/sockio.h>
41#include <sys/endian.h>
42#include <sys/errno.h>
43#include <sys/sysctl.h>
44#include <sys/task.h>
45
46#include <net/if.h>
47#include <net/if_dl.h>
48#include <net/if_media.h>
49#include <net/if_llc.h>
50
51#if NBPFILTER1 > 0
52#include <net/bpf.h>
53#endif
54
55#include <netinet/in.h>
56#include <netinet/if_ether.h>
57
58#include <net80211/ieee80211_var.h>
59#include <net80211/ieee80211_priv.h>
60
61struct mbuf *ieee80211_input_hwdecrypt(struct ieee80211com *,
62 struct ieee80211_node *, struct mbuf *,
63 struct ieee80211_rxinfo *rxi);
64struct mbuf *ieee80211_defrag(struct ieee80211com *, struct mbuf *, int);
65void ieee80211_defrag_timeout(void *);
66void ieee80211_input_ba(struct ieee80211com *, struct mbuf *,
67 struct ieee80211_node *, int, struct ieee80211_rxinfo *,
68 struct mbuf_list *);
69void ieee80211_input_ba_flush(struct ieee80211com *, struct ieee80211_node *,
70 struct ieee80211_rx_ba *, struct mbuf_list *);
71int ieee80211_input_ba_gap_skip(struct ieee80211_rx_ba *);
72void ieee80211_input_ba_gap_timeout(void *arg);
73void ieee80211_ba_move_window(struct ieee80211com *,
74 struct ieee80211_node *, u_int8_t, u_int16_t, struct mbuf_list *);
75void ieee80211_input_ba_seq(struct ieee80211com *,
76 struct ieee80211_node *, uint8_t, uint16_t, struct mbuf_list *);
77struct mbuf *ieee80211_align_mbuf(struct mbuf *);
78void ieee80211_decap(struct ieee80211com *, struct mbuf *,
79 struct ieee80211_node *, int, struct mbuf_list *);
80int ieee80211_amsdu_decap_validate(struct ieee80211com *, struct mbuf *,
81 struct ieee80211_node *);
82void ieee80211_amsdu_decap(struct ieee80211com *, struct mbuf *,
83 struct ieee80211_node *, int, struct mbuf_list *);
84void ieee80211_enqueue_data(struct ieee80211com *, struct mbuf *,
85 struct ieee80211_node *, int, struct mbuf_list *);
86int ieee80211_parse_edca_params_body(struct ieee80211com *,
87 const u_int8_t *);
88int ieee80211_parse_edca_params(struct ieee80211com *, const u_int8_t *);
89int ieee80211_parse_wmm_params(struct ieee80211com *, const u_int8_t *);
90enum ieee80211_cipher ieee80211_parse_rsn_cipher(const u_int8_t[]);
91enum ieee80211_akm ieee80211_parse_rsn_akm(const u_int8_t[]);
92int ieee80211_parse_rsn_body(struct ieee80211com *, const u_int8_t *,
93 u_int, struct ieee80211_rsnparams *);
94int ieee80211_save_ie(const u_int8_t *, u_int8_t **);
95void ieee80211_recv_probe_resp(struct ieee80211com *, struct mbuf *,
96 struct ieee80211_node *, struct ieee80211_rxinfo *, int);
97#ifndef IEEE80211_STA_ONLY
98void ieee80211_recv_probe_req(struct ieee80211com *, struct mbuf *,
99 struct ieee80211_node *, struct ieee80211_rxinfo *);
100#endif
101void ieee80211_recv_auth(struct ieee80211com *, struct mbuf *,
102 struct ieee80211_node *, struct ieee80211_rxinfo *);
103#ifndef IEEE80211_STA_ONLY
104void ieee80211_recv_assoc_req(struct ieee80211com *, struct mbuf *,
105 struct ieee80211_node *, struct ieee80211_rxinfo *, int);
106#endif
107void ieee80211_recv_assoc_resp(struct ieee80211com *, struct mbuf *,
108 struct ieee80211_node *, int);
109void ieee80211_recv_deauth(struct ieee80211com *, struct mbuf *,
110 struct ieee80211_node *);
111void ieee80211_recv_disassoc(struct ieee80211com *, struct mbuf *,
112 struct ieee80211_node *);
113void ieee80211_recv_addba_req(struct ieee80211com *, struct mbuf *,
114 struct ieee80211_node *);
115void ieee80211_recv_addba_resp(struct ieee80211com *, struct mbuf *,
116 struct ieee80211_node *);
117void ieee80211_recv_delba(struct ieee80211com *, struct mbuf *,
118 struct ieee80211_node *);
119void ieee80211_recv_sa_query_req(struct ieee80211com *, struct mbuf *,
120 struct ieee80211_node *);
121#ifndef IEEE80211_STA_ONLY
122void ieee80211_recv_sa_query_resp(struct ieee80211com *, struct mbuf *,
123 struct ieee80211_node *);
124#endif
125void ieee80211_recv_action(struct ieee80211com *, struct mbuf *,
126 struct ieee80211_node *);
127#ifndef IEEE80211_STA_ONLY
128void ieee80211_recv_pspoll(struct ieee80211com *, struct mbuf *,
129 struct ieee80211_node *);
130#endif
131void ieee80211_recv_bar(struct ieee80211com *, struct mbuf *,
132 struct ieee80211_node *);
133void ieee80211_bar_tid(struct ieee80211com *, struct ieee80211_node *,
134 u_int8_t, u_int16_t);
135
136/*
137 * Retrieve the length in bytes of an 802.11 header.
138 */
139u_int
140ieee80211_get_hdrlen(const struct ieee80211_frame *wh)
141{
142 u_int size = sizeof(*wh);
143
144 /* NB: does not work with control frames */
145 KASSERT(ieee80211_has_seq(wh))((ieee80211_has_seq(wh)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/net80211/ieee80211_input.c"
, 145, "ieee80211_has_seq(wh)"))
;
146
147 if (ieee80211_has_addr4(wh))
148 size += IEEE80211_ADDR_LEN6; /* i_addr4 */
149 if (ieee80211_has_qos(wh))
150 size += sizeof(u_int16_t); /* i_qos */
151 if (ieee80211_has_htc(wh))
152 size += sizeof(u_int32_t); /* i_ht */
153 return size;
154}
155
156/* Post-processing for drivers which perform decryption in hardware. */
157struct mbuf *
158ieee80211_input_hwdecrypt(struct ieee80211com *ic, struct ieee80211_node *ni,
159 struct mbuf *m, struct ieee80211_rxinfo *rxi)
160{
161 struct ieee80211_key *k;
162 struct ieee80211_frame *wh;
163 uint64_t pn, *prsc;
164 int hdrlen;
165
166 k = ieee80211_get_rxkey(ic, m, ni);
167 if (k == NULL((void *)0))
168 return NULL((void *)0);
169
170 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
171 hdrlen = ieee80211_get_hdrlen(wh);
172
173 /*
174 * Update the last-seen packet number (PN) for drivers using hardware
175 * crypto offloading. This cannot be done by drivers because A-MPDU
176 * reordering needs to occur before a valid lower bound can be
177 * determined for the PN. Drivers will read the PN we write here and
178 * are expected to discard replayed frames based on it.
179 * Drivers are expected to leave the IV of decrypted frames intact
180 * so we can update the last-seen PN and strip the IV here.
181 */
182 switch (k->k_cipher) {
183 case IEEE80211_CIPHER_CCMP:
184 if (!(wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40)) {
185 /*
186 * If the protected bit is clear then hardware has
187 * stripped the IV and we must trust that it handles
188 * replay detection correctly.
189 */
190 break;
191 }
192 if (ieee80211_ccmp_get_pn(&pn, &prsc, m, k) != 0)
193 return NULL((void *)0);
194 if (rxi->rxi_flags & IEEE80211_RXI_HWDEC_SAME_PN0x00000004) {
195 if (pn < *prsc) {
196 ic->ic_stats.is_ccmp_replays++;
197 return NULL((void *)0);
198 }
199 } else if (pn <= *prsc) {
200 ic->ic_stats.is_ccmp_replays++;
201 return NULL((void *)0);
202 }
203
204 /* Update last-seen packet number. */
205 *prsc = pn;
206
207 /* Clear Protected bit and strip IV. */
208 wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED0x40;
209 memmove(mtod(m, caddr_t) + IEEE80211_CCMP_HDRLEN, wh, hdrlen)__builtin_memmove((((caddr_t)((m)->m_hdr.mh_data)) + 8), (
wh), (hdrlen))
;
210 m_adj(m, IEEE80211_CCMP_HDRLEN8);
211 /* Drivers are expected to strip the MIC. */
212 break;
213 case IEEE80211_CIPHER_TKIP:
214 if (!(wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40)) {
215 /*
216 * If the protected bit is clear then hardware has
217 * stripped the IV and we must trust that it handles
218 * replay detection correctly.
219 */
220 break;
221 }
222 if (ieee80211_tkip_get_tsc(&pn, &prsc, m, k) != 0)
223 return NULL((void *)0);
224 if (rxi->rxi_flags & IEEE80211_RXI_HWDEC_SAME_PN0x00000004) {
225 if (pn < *prsc) {
226 ic->ic_stats.is_tkip_replays++;
227 return NULL((void *)0);
228 }
229 } else if (pn <= *prsc) {
230 ic->ic_stats.is_tkip_replays++;
231 return NULL((void *)0);
232 }
233
234 /* Update last-seen packet number. */
235 *prsc = pn;
236
237 /* Clear Protected bit and strip IV. */
238 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
239 wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED0x40;
240 memmove(mtod(m, caddr_t) + IEEE80211_TKIP_HDRLEN, wh, hdrlen)__builtin_memmove((((caddr_t)((m)->m_hdr.mh_data)) + 8), (
wh), (hdrlen))
;
241 m_adj(m, IEEE80211_TKIP_HDRLEN8);
242 /* Drivers are expected to strip the MIC. */
243 break;
244 default:
245 break;
246 }
247
248 return m;
249}
250
251/*
252 * Process a received frame. The node associated with the sender
253 * should be supplied. If nothing was found in the node table then
254 * the caller is assumed to supply a reference to ic_bss instead.
255 * The RSSI and a timestamp are also supplied. The RSSI data is used
256 * during AP scanning to select a AP to associate with; it can have
257 * any units so long as values have consistent units and higher values
258 * mean ``better signal''. The receive timestamp is currently not used
259 * by the 802.11 layer.
260 *
261 * This function acts on management frames immediately and queues data frames
262 * on the specified mbuf list. Delivery of queued data frames to upper layers
263 * must be triggered with if_input(). Drivers should call if_input() only once
264 * per Rx interrupt to avoid triggering the input ifq pressure drop mechanism
265 * unnecessarily.
266 */
267void
268ieee80211_inputm(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
269 struct ieee80211_rxinfo *rxi, struct mbuf_list *ml)
270{
271 struct ieee80211com *ic = (void *)ifp;
272 struct ieee80211_frame *wh;
273 u_int16_t *orxseq, nrxseq, qos;
274 u_int8_t dir, type, subtype, tid;
275 int hdrlen, hasqos;
276
277 KASSERT(ni != NULL)((ni != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/net80211/ieee80211_input.c"
, 277, "ni != NULL"))
;
278
279 /* in monitor mode, send everything directly to bpf */
280 if (ic->ic_opmode == IEEE80211_M_MONITOR)
281 goto out;
282
283 /*
284 * Do not process frames without an Address 2 field any further.
285 * Only CTS and ACK control frames do not have this field.
286 */
287 if (m->m_lenm_hdr.mh_len < sizeof(struct ieee80211_frame_min)) {
288 DPRINTF(("frame too short, len %u\n", m->m_len));
289 ic->ic_stats.is_rx_tooshort++;
290 goto out;
291 }
292
293 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
294 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK0x03) !=
295 IEEE80211_FC0_VERSION_00x00) {
296 DPRINTF(("frame with wrong version: %x\n", wh->i_fc[0]));
297 ic->ic_stats.is_rx_badversion++;
298 goto err;
299 }
300
301 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK0x03;
302 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c;
303 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK0xf0;
304
305 if (type != IEEE80211_FC0_TYPE_CTL0x04) {
306 hdrlen = ieee80211_get_hdrlen(wh);
307 if (m->m_lenm_hdr.mh_len < hdrlen) {
308 DPRINTF(("frame too short, len %u\n", m->m_len));
309 ic->ic_stats.is_rx_tooshort++;
310 goto err;
311 }
312 } else
313 hdrlen = 0;
314 if ((hasqos = ieee80211_has_qos(wh))) {
315 qos = ieee80211_get_qos(wh);
316 tid = qos & IEEE80211_QOS_TID0x000f;
317 } else {
318 qos = 0;
319 tid = 0;
320 }
321
322 if (ic->ic_state == IEEE80211_S_RUN &&
323 type == IEEE80211_FC0_TYPE_DATA0x08 && hasqos &&
324 (subtype & IEEE80211_FC0_SUBTYPE_NODATA0x40) == 0 &&
325 !(rxi->rxi_flags & IEEE80211_RXI_AMPDU_DONE0x00000002)
326#ifndef IEEE80211_STA_ONLY
327 && (ic->ic_opmode == IEEE80211_M_STA || ni != ic->ic_bss)
328#endif
329 ) {
330 int ba_state = ni->ni_rx_ba[tid].ba_state;
331
332#ifndef IEEE80211_STA_ONLY
333 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
334 if (!IEEE80211_ADDR_EQ(wh->i_addr1,(__builtin_memcmp((wh->i_addr1), (ic->ic_bss->ni_bssid
), (6)) == 0)
335 ic->ic_bss->ni_bssid)(__builtin_memcmp((wh->i_addr1), (ic->ic_bss->ni_bssid
), (6)) == 0)
) {
336 ic->ic_stats.is_rx_wrongbss++;
337 goto err;
338 }
339 if (ni->ni_state != IEEE80211_S_ASSOC) {
340 ic->ic_stats.is_rx_notassoc++;
341 goto err;
342 }
343 }
344#endif
345 /*
346 * If Block Ack was explicitly requested, check
347 * if we have a BA agreement for this RA/TID.
348 */
349 if ((qos & IEEE80211_QOS_ACK_POLICY_MASK0x0060) ==
350 IEEE80211_QOS_ACK_POLICY_BA0x0060 &&
351 ba_state != IEEE80211_BA_AGREED2) {
352 DPRINTF(("no BA agreement for %s, TID %d\n",
353 ether_sprintf(ni->ni_macaddr), tid));
354 /* send a DELBA with reason code UNKNOWN-BA */
355 IEEE80211_SEND_ACTION(ic, ni,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)
)
356 IEEE80211_CATEG_BA, IEEE80211_ACTION_DELBA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)
)
357 IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)
)
;
358 goto err;
359 }
360
361 /*
362 * Check if we have an explicit or implicit
363 * Block Ack Request for a valid BA agreement.
364 */
365 if (ba_state == IEEE80211_BA_AGREED2 &&
366 ((qos & IEEE80211_QOS_ACK_POLICY_MASK0x0060) ==
367 IEEE80211_QOS_ACK_POLICY_BA0x0060 ||
368 (qos & IEEE80211_QOS_ACK_POLICY_MASK0x0060) ==
369 IEEE80211_QOS_ACK_POLICY_NORMAL0x0000)) {
370 /* go through A-MPDU reordering */
371 ieee80211_input_ba(ic, m, ni, tid, rxi, ml);
372 return; /* don't free m! */
373 } else if (ba_state == IEEE80211_BA_REQUESTED1 &&
374 (qos & IEEE80211_QOS_ACK_POLICY_MASK0x0060) ==
375 IEEE80211_QOS_ACK_POLICY_NORMAL0x0000) {
376 /*
377 * Apparently, qos frames for a tid where a
378 * block ack agreement was requested but not
379 * yet confirmed by us should still contribute
380 * to the sequence number for this tid.
381 */
382 ieee80211_input_ba(ic, m, ni, tid, rxi, ml);
383 return; /* don't free m! */
384 }
385 }
386
387 /*
388 * We do not yet support fragments. Drop any fragmented packets.
389 * Counter-measure against attacks where an arbitrary packet is
390 * injected via a fragment with attacker-controlled content.
391 * See https://papers.mathyvanhoef.com/usenix2021.pdf
392 * Section 6.8 "Treating fragments as full frames"
393 */
394 if (ieee80211_has_seq(wh)) {
395 uint16_t rxseq = letoh16(*(const u_int16_t *)wh->i_seq)((__uint16_t)(*(const u_int16_t *)wh->i_seq));
396 if ((wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG0x04) ||
397 (rxseq & IEEE80211_SEQ_FRAG_MASK0x000f))
398 goto err;
399 }
400
401 /* duplicate detection (see 9.2.9) */
402 if (ieee80211_has_seq(wh) &&
403 ic->ic_state != IEEE80211_S_SCAN) {
404 nrxseq = letoh16(*(u_int16_t *)wh->i_seq)((__uint16_t)(*(u_int16_t *)wh->i_seq)) >>
405 IEEE80211_SEQ_SEQ_SHIFT4;
406 if (hasqos)
407 orxseq = &ni->ni_qos_rxseqs[tid];
408 else
409 orxseq = &ni->ni_rxseq;
410 if (rxi->rxi_flags & IEEE80211_RXI_SAME_SEQ0x00000008) {
411 if (nrxseq != *orxseq) {
412 /* duplicate, silently discarded */
413 ic->ic_stats.is_rx_dup++;
414 goto out;
415 }
416 } else if ((wh->i_fc[1] & IEEE80211_FC1_RETRY0x08) &&
417 nrxseq == *orxseq) {
418 /* duplicate, silently discarded */
419 ic->ic_stats.is_rx_dup++;
420 goto out;
421 }
422 *orxseq = nrxseq;
423 }
424 if (ic->ic_state > IEEE80211_S_SCAN) {
425 ni->ni_rssi = rxi->rxi_rssi;
426 ni->ni_rstamp = rxi->rxi_tstamp;
427 ni->ni_inact = 0;
428
429 if (ic->ic_state == IEEE80211_S_RUN && ic->ic_bgscan_start) {
430 /* Cancel or start background scan based on RSSI. */
431 if ((*ic->ic_node_checkrssi)(ic, ni))
432 timeout_del(&ic->ic_bgscan_timeout);
433 else if (!timeout_pending(&ic->ic_bgscan_timeout)((&ic->ic_bgscan_timeout)->to_flags & 0x02) &&
434 (ic->ic_flags & IEEE80211_F_BGSCAN0x08000000) == 0 &&
435 (ic->ic_flags & IEEE80211_F_DESBSSID0x00000800) == 0)
436 timeout_add_msec(&ic->ic_bgscan_timeout,
437 500 * (ic->ic_bgscan_fail + 1));
438 }
439 }
440
441#ifndef IEEE80211_STA_ONLY
442 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
443 (ic->ic_caps & IEEE80211_C_APPMGT0x00000020) &&
444 ni->ni_state == IEEE80211_STA_ASSOC) {
445 if (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT0x10) {
446 if (ni->ni_pwrsave == IEEE80211_PS_AWAKE) {
447 /* turn on PS mode */
448 ni->ni_pwrsave = IEEE80211_PS_DOZE;
449 DPRINTF(("PS mode on for %s\n",
450 ether_sprintf(wh->i_addr2)));
451 }
452 } else if (ni->ni_pwrsave == IEEE80211_PS_DOZE) {
453 struct mbuf *m;
454
455 /* turn off PS mode */
456 ni->ni_pwrsave = IEEE80211_PS_AWAKE;
457 DPRINTF(("PS mode off for %s\n",
458 ether_sprintf(wh->i_addr2)));
459
460 (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
461
462 /* dequeue buffered unicast frames */
463 while ((m = mq_dequeue(&ni->ni_savedq)) != NULL((void *)0)) {
464 mq_enqueue(&ic->ic_pwrsaveq, m);
465 if_start(ifp);
466 }
467 }
468 }
469#endif
470 switch (type) {
471 case IEEE80211_FC0_TYPE_DATA0x08:
472 switch (ic->ic_opmode) {
473 case IEEE80211_M_STA:
474 if (dir != IEEE80211_FC1_DIR_FROMDS0x02) {
475 ic->ic_stats.is_rx_wrongdir++;
476 goto out;
477 }
478 if (ic->ic_state != IEEE80211_S_SCAN &&
479 !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)(__builtin_memcmp((wh->i_addr2), (ni->ni_bssid), (6)) ==
0)
) {
480 /* Source address is not our BSS. */
481 DPRINTF(("discard frame from SA %s\n",
482 ether_sprintf(wh->i_addr2)));
483 ic->ic_stats.is_rx_wrongbss++;
484 goto out;
485 }
486 if ((ifp->if_flags & IFF_SIMPLEX0x800) &&
487 IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01) &&
488 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)(__builtin_memcmp((wh->i_addr3), (ic->ic_myaddr), (6)) ==
0)
) {
489 /*
490 * In IEEE802.11 network, multicast frame
491 * sent from me is broadcasted from AP.
492 * It should be silently discarded for
493 * SIMPLEX interface.
494 */
495 ic->ic_stats.is_rx_mcastecho++;
496 goto out;
497 }
498 break;
499#ifndef IEEE80211_STA_ONLY
500 case IEEE80211_M_IBSS:
501 case IEEE80211_M_AHDEMO:
502 if (dir != IEEE80211_FC1_DIR_NODS0x00) {
503 ic->ic_stats.is_rx_wrongdir++;
504 goto out;
505 }
506 if (ic->ic_state != IEEE80211_S_SCAN &&
507 !IEEE80211_ADDR_EQ(wh->i_addr3,(__builtin_memcmp((wh->i_addr3), (ic->ic_bss->ni_bssid
), (6)) == 0)
508 ic->ic_bss->ni_bssid)(__builtin_memcmp((wh->i_addr3), (ic->ic_bss->ni_bssid
), (6)) == 0)
&&
509 !IEEE80211_ADDR_EQ(wh->i_addr3,(__builtin_memcmp((wh->i_addr3), (etherbroadcastaddr), (6)
) == 0)
510 etherbroadcastaddr)(__builtin_memcmp((wh->i_addr3), (etherbroadcastaddr), (6)
) == 0)
) {
511 /* Destination is not our BSS or broadcast. */
512 DPRINTF(("discard data frame to DA %s\n",
513 ether_sprintf(wh->i_addr3)));
514 ic->ic_stats.is_rx_wrongbss++;
515 goto out;
516 }
517 break;
518 case IEEE80211_M_HOSTAP:
519 if (dir != IEEE80211_FC1_DIR_TODS0x01) {
520 ic->ic_stats.is_rx_wrongdir++;
521 goto out;
522 }
523 if (ic->ic_state != IEEE80211_S_SCAN &&
524 !IEEE80211_ADDR_EQ(wh->i_addr1,(__builtin_memcmp((wh->i_addr1), (ic->ic_bss->ni_bssid
), (6)) == 0)
525 ic->ic_bss->ni_bssid)(__builtin_memcmp((wh->i_addr1), (ic->ic_bss->ni_bssid
), (6)) == 0)
&&
526 !IEEE80211_ADDR_EQ(wh->i_addr1,(__builtin_memcmp((wh->i_addr1), (etherbroadcastaddr), (6)
) == 0)
527 etherbroadcastaddr)(__builtin_memcmp((wh->i_addr1), (etherbroadcastaddr), (6)
) == 0)
) {
528 /* BSS is not us or broadcast. */
529 DPRINTF(("discard data frame to BSS %s\n",
530 ether_sprintf(wh->i_addr1)));
531 ic->ic_stats.is_rx_wrongbss++;
532 goto out;
533 }
534 /* check if source STA is associated */
535 if (ni == ic->ic_bss) {
536 DPRINTF(("data from unknown src %s\n",
537 ether_sprintf(wh->i_addr2)));
538 /* NB: caller deals with reference */
539 ni = ieee80211_find_node(ic, wh->i_addr2);
540 if (ni == NULL((void *)0))
541 ni = ieee80211_dup_bss(ic, wh->i_addr2);
542 if (ni != NULL((void *)0)) {
543 IEEE80211_SEND_MGMT(ic, ni,((*(ic)->ic_send_mgmt)(ic, ni, 0xc0, IEEE80211_REASON_NOT_AUTHED
, 0))
544 IEEE80211_FC0_SUBTYPE_DEAUTH,((*(ic)->ic_send_mgmt)(ic, ni, 0xc0, IEEE80211_REASON_NOT_AUTHED
, 0))
545 IEEE80211_REASON_NOT_AUTHED)((*(ic)->ic_send_mgmt)(ic, ni, 0xc0, IEEE80211_REASON_NOT_AUTHED
, 0))
;
546 }
547 ic->ic_stats.is_rx_notassoc++;
548 goto err;
549 }
550 if (ni->ni_state != IEEE80211_STA_ASSOC) {
551 DPRINTF(("data from unassoc src %s\n",
552 ether_sprintf(wh->i_addr2)));
553 IEEE80211_SEND_MGMT(ic, ni,((*(ic)->ic_send_mgmt)(ic, ni, 0xa0, IEEE80211_REASON_NOT_ASSOCED
, 0))
554 IEEE80211_FC0_SUBTYPE_DISASSOC,((*(ic)->ic_send_mgmt)(ic, ni, 0xa0, IEEE80211_REASON_NOT_ASSOCED
, 0))
555 IEEE80211_REASON_NOT_ASSOCED)((*(ic)->ic_send_mgmt)(ic, ni, 0xa0, IEEE80211_REASON_NOT_ASSOCED
, 0))
;
556 ic->ic_stats.is_rx_notassoc++;
557 goto err;
558 }
559 break;
560#endif /* IEEE80211_STA_ONLY */
561 default:
562 /* can't get there */
563 goto out;
564 }
565
566 /* Do not process "no data" frames any further. */
567 if (subtype & IEEE80211_FC0_SUBTYPE_NODATA0x40) {
568#if NBPFILTER1 > 0
569 if (ic->ic_rawbpf)
570 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN(1 << 0));
571#endif
572 goto out;
573 }
574
575 if ((ic->ic_flags & IEEE80211_F_WEPON0x00000100) ||
576 ((ic->ic_flags & IEEE80211_F_RSNON0x00200000) &&
577 (ni->ni_flags & IEEE80211_NODE_RXPROT0x0008))) {
578 /* protection is on for Rx */
579 if (!(rxi->rxi_flags & IEEE80211_RXI_HWDEC0x00000001)) {
580 if (!(wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40)) {
581 /* drop unencrypted */
582 ic->ic_stats.is_rx_unencrypted++;
583 goto err;
584 }
585 /* do software decryption */
586 m = ieee80211_decrypt(ic, m, ni);
587 if (m == NULL((void *)0)) {
588 ic->ic_stats.is_rx_wepfail++;
589 goto err;
590 }
591 } else {
592 m = ieee80211_input_hwdecrypt(ic, ni, m, rxi);
593 if (m == NULL((void *)0))
594 goto err;
595 }
596 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
597 } else if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40) ||
598 (rxi->rxi_flags & IEEE80211_RXI_HWDEC0x00000001)) {
599 /* frame encrypted but protection off for Rx */
600 ic->ic_stats.is_rx_nowep++;
601 goto out;
602 }
603
604#if NBPFILTER1 > 0
605 /* copy to listener after decrypt */
606 if (ic->ic_rawbpf)
607 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN(1 << 0));
608#endif
609
610 if ((ni->ni_flags & IEEE80211_NODE_HT0x0400) &&
611 hasqos && (qos & IEEE80211_QOS_AMSDU0x0080))
612 ieee80211_amsdu_decap(ic, m, ni, hdrlen, ml);
613 else
614 ieee80211_decap(ic, m, ni, hdrlen, ml);
615 return;
616
617 case IEEE80211_FC0_TYPE_MGT0x00:
618 if (dir != IEEE80211_FC1_DIR_NODS0x00) {
619 ic->ic_stats.is_rx_wrongdir++;
620 goto err;
621 }
622#ifndef IEEE80211_STA_ONLY
623 if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
624 ic->ic_stats.is_rx_ahdemo_mgt++;
625 goto out;
626 }
627#endif
628 /* drop frames without interest */
629 if (ic->ic_state == IEEE80211_S_SCAN) {
630 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON0x80 &&
631 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP0x50) {
632 ic->ic_stats.is_rx_mgtdiscard++;
633 goto out;
634 }
635 }
636
637 if (ni->ni_flags & IEEE80211_NODE_RXMGMTPROT0x0020) {
638 /* MMPDU protection is on for Rx */
639 if (subtype == IEEE80211_FC0_SUBTYPE_DISASSOC0xa0 ||
640 subtype == IEEE80211_FC0_SUBTYPE_DEAUTH0xc0 ||
641 subtype == IEEE80211_FC0_SUBTYPE_ACTION0xd0) {
642 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01) &&
643 !(wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40)) {
644 /* unicast mgmt not encrypted */
645 goto out;
646 }
647 /* do software decryption */
648 m = ieee80211_decrypt(ic, m, ni);
649 if (m == NULL((void *)0)) {
650 /* XXX stats */
651 goto out;
652 }
653 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
654 }
655 } else if ((ic->ic_flags & IEEE80211_F_RSNON0x00200000) &&
656 (wh->i_fc[1] & IEEE80211_FC1_PROTECTED0x40)) {
657 /* encrypted but MMPDU Rx protection off for TA */
658 goto out;
659 }
660
661#if NBPFILTER1 > 0
662 if (bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN(1 << 0)) != 0) {
663 /*
664 * Drop mbuf if it was filtered by bpf. Normally,
665 * this is done in ether_input() but IEEE 802.11
666 * management frames are a special case.
667 */
668 m_freem(m);
669 return;
670 }
671#endif
672 (*ic->ic_recv_mgmt)(ic, m, ni, rxi, subtype);
673 m_freem(m);
674 return;
675
676 case IEEE80211_FC0_TYPE_CTL0x04:
677 switch (subtype) {
678#ifndef IEEE80211_STA_ONLY
679 case IEEE80211_FC0_SUBTYPE_PS_POLL0xa0:
680 ieee80211_recv_pspoll(ic, m, ni);
681 break;
682#endif
683 case IEEE80211_FC0_SUBTYPE_BAR0x80:
684 ieee80211_recv_bar(ic, m, ni);
685 break;
686 default:
687 ic->ic_stats.is_rx_ctl++;
688 break;
689 }
690 goto out;
691
692 default:
693 DPRINTF(("bad frame type %x\n", type));
694 /* should not come here */
695 break;
696 }
697 err:
698 ifp->if_ierrorsif_data.ifi_ierrors++;
699 out:
700 if (m != NULL((void *)0)) {
701#if NBPFILTER1 > 0
702 if (ic->ic_rawbpf)
703 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN(1 << 0));
704#endif
705 m_freem(m);
706 }
707}
708
709/* Input handler for drivers which only receive one frame per interrupt. */
710void
711ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
712 struct ieee80211_rxinfo *rxi)
713{
714 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
715
716 ieee80211_inputm(ifp, m, ni, rxi, &ml);
717 if_input(ifp, &ml);
718}
719
720#ifdef notyet
721/*
722 * Handle defragmentation (see 9.5 and Annex C). We support the concurrent
723 * reception of fragments of three fragmented MSDUs or MMPDUs.
724 */
725struct mbuf *
726ieee80211_defrag(struct ieee80211com *ic, struct mbuf *m, int hdrlen)
727{
728 const struct ieee80211_frame *owh, *wh;
729 struct ieee80211_defrag *df;
730 u_int16_t rxseq, seq;
731 u_int8_t frag;
732 int i;
733
734 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
735 rxseq = letoh16(*(const u_int16_t *)wh->i_seq)((__uint16_t)(*(const u_int16_t *)wh->i_seq));
736 seq = rxseq >> IEEE80211_SEQ_SEQ_SHIFT4;
737 frag = rxseq & IEEE80211_SEQ_FRAG_MASK0x000f;
738
739 if (frag == 0 && !(wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG0x04))
740 return m; /* not fragmented */
741
742 if (frag == 0) {
743 /* first fragment, setup entry in the fragment cache */
744 if (++ic->ic_defrag_cur == IEEE80211_DEFRAG_SIZE3)
745 ic->ic_defrag_cur = 0;
746 df = &ic->ic_defrag[ic->ic_defrag_cur];
747 m_freem(df->df_m); /* discard old entry */
748 df->df_seq = seq;
749 df->df_frag = 0;
750 df->df_m = m;
751 /* start receive MSDU timer of aMaxReceiveLifetime */
752 timeout_add_sec(&df->df_to, 1);
753 return NULL((void *)0); /* MSDU or MMPDU not yet complete */
754 }
755
756 /* find matching entry in the fragment cache */
757 for (i = 0; i < IEEE80211_DEFRAG_SIZE3; i++) {
758 df = &ic->ic_defrag[i];
759 if (df->df_m == NULL((void *)0))
760 continue;
761 if (df->df_seq != seq || df->df_frag + 1 != frag)
762 continue;
763 owh = mtod(df->df_m, struct ieee80211_frame *)((struct ieee80211_frame *)((df->df_m)->m_hdr.mh_data));
764 /* frame type, source and destination must match */
765 if (((wh->i_fc[0] ^ owh->i_fc[0]) & IEEE80211_FC0_TYPE_MASK0x0c) ||
766 !IEEE80211_ADDR_EQ(wh->i_addr1, owh->i_addr1)(__builtin_memcmp((wh->i_addr1), (owh->i_addr1), (6)) ==
0)
||
767 !IEEE80211_ADDR_EQ(wh->i_addr2, owh->i_addr2)(__builtin_memcmp((wh->i_addr2), (owh->i_addr2), (6)) ==
0)
)
768 continue;
769 /* matching entry found */
770 break;
771 }
772 if (i == IEEE80211_DEFRAG_SIZE3) {
773 /* no matching entry found, discard fragment */
774 ic->ic_ific_ac.ac_if.if_ierrorsif_data.ifi_ierrors++;
775 m_freem(m);
776 return NULL((void *)0);
777 }
778
779 df->df_frag = frag;
780 /* strip 802.11 header and concatenate fragment */
781 m_adj(m, hdrlen);
782 m_cat(df->df_m, m);
783 df->df_m->m_pkthdrM_dat.MH.MH_pkthdr.len += m->m_pkthdrM_dat.MH.MH_pkthdr.len;
784
785 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG0x04)
786 return NULL((void *)0); /* MSDU or MMPDU not yet complete */
787
788 /* MSDU or MMPDU complete */
789 timeout_del(&df->df_to);
790 m = df->df_m;
791 df->df_m = NULL((void *)0);
792 return m;
793}
794
795/*
796 * Receive MSDU defragmentation timer exceeds aMaxReceiveLifetime.
797 */
798void
799ieee80211_defrag_timeout(void *arg)
800{
801 struct ieee80211_defrag *df = arg;
802 int s = splnet()splraise(0x7);
803
804 /* discard all received fragments */
805 m_freem(df->df_m);
806 df->df_m = NULL((void *)0);
807
808 splx(s)spllower(s);
809}
810#endif
811
812/*
813 * Process a received data MPDU related to a specific HT-immediate Block Ack
814 * agreement (see 9.10.7.6).
815 */
816void
817ieee80211_input_ba(struct ieee80211com *ic, struct mbuf *m,
818 struct ieee80211_node *ni, int tid, struct ieee80211_rxinfo *rxi,
819 struct mbuf_list *ml)
820{
821 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
822 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
823 struct ieee80211_frame *wh;
824 int idx, count;
825 u_int16_t sn;
826
827 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
828 sn = letoh16(*(u_int16_t *)wh->i_seq)((__uint16_t)(*(u_int16_t *)wh->i_seq)) >> IEEE80211_SEQ_SEQ_SHIFT4;
829
830 /* reset Block Ack inactivity timer */
831 if (ba->ba_timeout_val != 0)
832 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
833
834 if (SEQ_LT(sn, ba->ba_winstart)((((u_int16_t)(sn) - (u_int16_t)(ba->ba_winstart)) & 0xfff
) > 2048)
) { /* SN < WinStartB */
835 ic->ic_stats.is_ht_rx_frame_below_ba_winstart++;
836 m_freem(m); /* discard the MPDU */
837 return;
838 }
839 if (SEQ_LT(ba->ba_winend, sn)((((u_int16_t)(ba->ba_winend) - (u_int16_t)(sn)) & 0xfff
) > 2048)
) { /* WinEndB < SN */
840 ic->ic_stats.is_ht_rx_frame_above_ba_winend++;
841 count = (sn - ba->ba_winend) & 0xfff;
842 if (count > ba->ba_winsize) {
843 /*
844 * Check whether we're consistently behind the window,
845 * and let the window move forward if necessary.
846 */
847 if (ba->ba_winmiss < IEEE80211_BA_MAX_WINMISS8) {
848 if (ba->ba_missedsn == ((sn - 1) & 0xfff))
849 ba->ba_winmiss++;
850 else
851 ba->ba_winmiss = 0;
852 ba->ba_missedsn = sn;
853 ifp->if_ierrorsif_data.ifi_ierrors++;
854 m_freem(m); /* discard the MPDU */
855 return;
856 }
857
858 /* It appears the window has moved for real. */
859 ic->ic_stats.is_ht_rx_ba_window_jump++;
860 ba->ba_winmiss = 0;
861 ba->ba_missedsn = 0;
862 ieee80211_ba_move_window(ic, ni, tid, sn, ml);
863 } else {
864 ic->ic_stats.is_ht_rx_ba_window_slide++;
865 ieee80211_input_ba_seq(ic, ni, tid,
866 (ba->ba_winstart + count) & 0xfff, ml);
867 ieee80211_input_ba_flush(ic, ni, ba, ml);
868 }
869 }
870 /* WinStartB <= SN <= WinEndB */
871
872 ba->ba_winmiss = 0;
873 ba->ba_missedsn = 0;
874 idx = (sn - ba->ba_winstart) & 0xfff;
875 idx = (ba->ba_head + idx) % IEEE80211_BA_MAX_WINSZ64;
876 /* store the received MPDU in the buffer */
877 if (ba->ba_buf[idx].m != NULL((void *)0)) {
878 ifp->if_ierrorsif_data.ifi_ierrors++;
879 ic->ic_stats.is_ht_rx_ba_no_buf++;
880 m_freem(m);
881 return;
882 }
883 ba->ba_buf[idx].m = m;
884 /* store Rx meta-data too */
885 rxi->rxi_flags |= IEEE80211_RXI_AMPDU_DONE0x00000002;
886 ba->ba_buf[idx].rxi = *rxi;
887 ba->ba_gapwait++;
888
889 if (ba->ba_buf[ba->ba_head].m == NULL((void *)0) && ba->ba_gapwait == 1)
890 timeout_add_msec(&ba->ba_gap_to, IEEE80211_BA_GAP_TIMEOUT300);
891
892 ieee80211_input_ba_flush(ic, ni, ba, ml);
893}
894
895/*
896 * Forward buffered frames with sequence number lower than max_seq.
897 * See 802.11-2012 9.21.7.6.2 b.
898 */
899void
900ieee80211_input_ba_seq(struct ieee80211com *ic, struct ieee80211_node *ni,
901 uint8_t tid, uint16_t max_seq, struct mbuf_list *ml)
902{
903 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
904 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
905 struct ieee80211_frame *wh;
906 uint16_t seq;
907 int i = 0;
908
909 while (i++ < ba->ba_winsize) {
910 /* gaps may exist */
911 if (ba->ba_buf[ba->ba_head].m != NULL((void *)0)) {
912 wh = mtod(ba->ba_buf[ba->ba_head].m,((struct ieee80211_frame *)((ba->ba_buf[ba->ba_head].m)
->m_hdr.mh_data))
913 struct ieee80211_frame *)((struct ieee80211_frame *)((ba->ba_buf[ba->ba_head].m)
->m_hdr.mh_data))
;
914 KASSERT(ieee80211_has_seq(wh))((ieee80211_has_seq(wh)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/net80211/ieee80211_input.c"
, 914, "ieee80211_has_seq(wh)"))
;
915 seq = letoh16(*(u_int16_t *)wh->i_seq)((__uint16_t)(*(u_int16_t *)wh->i_seq)) >>
916 IEEE80211_SEQ_SEQ_SHIFT4;
917 if (!SEQ_LT(seq, max_seq)((((u_int16_t)(seq) - (u_int16_t)(max_seq)) & 0xfff) >
2048)
)
918 break;
919 ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m,
920 ni, &ba->ba_buf[ba->ba_head].rxi, ml);
921 ba->ba_buf[ba->ba_head].m = NULL((void *)0);
922 ba->ba_gapwait--;
923 } else
924 ic->ic_stats.is_ht_rx_ba_frame_lost++;
925 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ64;
926 /* move window forward */
927 ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
928 }
929 ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
930}
931
932/* Flush a consecutive sequence of frames from the reorder buffer. */
933void
934ieee80211_input_ba_flush(struct ieee80211com *ic, struct ieee80211_node *ni,
935 struct ieee80211_rx_ba *ba, struct mbuf_list *ml)
936
937{
938 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
939
940 /* Do not re-arm the gap timeout if we made no progress. */
941 if (ba->ba_buf[ba->ba_head].m == NULL((void *)0))
942 return;
943
944 /* pass reordered MPDUs up to the next MAC process */
945 while (ba->ba_buf[ba->ba_head].m != NULL((void *)0)) {
946 ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m, ni,
947 &ba->ba_buf[ba->ba_head].rxi, ml);
948 ba->ba_buf[ba->ba_head].m = NULL((void *)0);
949 ba->ba_gapwait--;
950
951 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ64;
952 /* move window forward */
953 ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
954 }
955 ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
956
957 if (timeout_pending(&ba->ba_gap_to)((&ba->ba_gap_to)->to_flags & 0x02))
958 timeout_del(&ba->ba_gap_to);
959 if (ba->ba_gapwait)
960 timeout_add_msec(&ba->ba_gap_to, IEEE80211_BA_GAP_TIMEOUT300);
961}
962
963/*
964 * Forcibly move the BA window forward to remove a leading gap which has
965 * been causing frames to linger in the reordering buffer for too long.
966 * A leading gap will occur if a particular A-MPDU subframe never arrives
967 * or if a bug in the sender causes sequence numbers to jump forward by > 1.
968 */
969int
970ieee80211_input_ba_gap_skip(struct ieee80211_rx_ba *ba)
971{
972 int skipped = 0;
973
974 while (skipped < ba->ba_winsize && ba->ba_buf[ba->ba_head].m == NULL((void *)0)) {
975 /* move window forward */
976 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ64;
977 ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
978 skipped++;
979 }
980 if (skipped > 0)
981 ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
982
983 return skipped;
984}
985
986void
987ieee80211_input_ba_gap_timeout(void *arg)
988{
989 struct ieee80211_rx_ba *ba = arg;
990 struct ieee80211_node *ni = ba->ba_ni;
991 struct ieee80211com *ic = ni->ni_ic;
992 int s, skipped;
993
994 ic->ic_stats.is_ht_rx_ba_window_gap_timeout++;
995
996 s = splnet()splraise(0x7);
997
998 skipped = ieee80211_input_ba_gap_skip(ba);
999 ic->ic_stats.is_ht_rx_ba_frame_lost += skipped;
1000 if (skipped) {
1001 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
1002 ieee80211_input_ba_flush(ic, ni, ba, &ml);
1003 if_input(&ic->ic_ific_ac.ac_if, &ml);
1004 }
1005
1006 splx(s)spllower(s);
1007}
1008
1009
1010/*
1011 * Change the value of WinStartB (move window forward) upon reception of a
1012 * BlockAckReq frame or an ADDBA Request (PBAC).
1013 */
1014void
1015ieee80211_ba_move_window(struct ieee80211com *ic, struct ieee80211_node *ni,
1016 u_int8_t tid, u_int16_t ssn, struct mbuf_list *ml)
1017{
1018 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1019 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
1020 int count;
1021
1022 /* assert(WinStartB <= SSN) */
1023
1024 count = (ssn - ba->ba_winstart) & 0xfff;
1025 if (count > ba->ba_winsize) /* no overlap */
1026 count = ba->ba_winsize;
1027 while (count-- > 0) {
1028 /* gaps may exist */
1029 if (ba->ba_buf[ba->ba_head].m != NULL((void *)0)) {
1030 ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m, ni,
1031 &ba->ba_buf[ba->ba_head].rxi, ml);
1032 ba->ba_buf[ba->ba_head].m = NULL((void *)0);
1033 ba->ba_gapwait--;
1034 } else
1035 ic->ic_stats.is_ht_rx_ba_frame_lost++;
1036 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ64;
1037 }
1038 /* move window forward */
1039 ba->ba_winstart = ssn;
1040 ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
1041
1042 ieee80211_input_ba_flush(ic, ni, ba, ml);
1043}
1044
1045void
1046ieee80211_enqueue_data(struct ieee80211com *ic, struct mbuf *m,
1047 struct ieee80211_node *ni, int mcast, struct mbuf_list *ml)
1048{
1049 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
1050 struct ether_header *eh;
1051 struct mbuf *m1;
1052
1053 eh = mtod(m, struct ether_header *)((struct ether_header *)((m)->m_hdr.mh_data));
1054
1055 if ((ic->ic_flags & IEEE80211_F_RSNON0x00200000) && !ni->ni_port_valid &&
1056 eh->ether_type != htons(ETHERTYPE_EAPOL)(__uint16_t)(__builtin_constant_p(0x888E) ? (__uint16_t)(((__uint16_t
)(0x888E) & 0xffU) << 8 | ((__uint16_t)(0x888E) &
0xff00U) >> 8) : __swap16md(0x888E))
) {
1057 DPRINTF(("port not valid: %s\n",
1058 ether_sprintf(eh->ether_dhost)));
1059 ic->ic_stats.is_rx_unauth++;
1060 m_freem(m);
1061 return;
1062 }
1063
1064 /*
1065 * Perform as a bridge within the AP. Notice that we do not
1066 * bridge EAPOL frames as suggested in C.1.1 of IEEE Std 802.1X.
1067 * And we do not forward unicast frames received on a multicast address.
1068 */
1069 m1 = NULL((void *)0);
1070#ifndef IEEE80211_STA_ONLY
1071 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
1072 !(ic->ic_userflags & IEEE80211_F_NOBRIDGE0x00000002) &&
1073 eh->ether_type != htons(ETHERTYPE_EAPOL)(__uint16_t)(__builtin_constant_p(0x888E) ? (__uint16_t)(((__uint16_t
)(0x888E) & 0xffU) << 8 | ((__uint16_t)(0x888E) &
0xff00U) >> 8) : __swap16md(0x888E))
) {
1074 struct ieee80211_node *ni1;
1075
1076 if (ETHER_IS_MULTICAST(eh->ether_dhost)(*(eh->ether_dhost) & 0x01)) {
1077 m1 = m_dup_pkt(m, ETHER_ALIGN2, M_DONTWAIT0x0002);
1078 if (m1 == NULL((void *)0))
1079 ifp->if_oerrorsif_data.ifi_oerrors++;
1080 else
1081 m1->m_flagsm_hdr.mh_flags |= M_MCAST0x0200;
1082 } else if (!mcast) {
1083 ni1 = ieee80211_find_node(ic, eh->ether_dhost);
1084 if (ni1 != NULL((void *)0) &&
1085 ni1->ni_state == IEEE80211_STA_ASSOC) {
1086 m1 = m;
1087 m = NULL((void *)0);
1088 }
1089 }
1090 if (m1 != NULL((void *)0)) {
1091 if (if_enqueue(ifp, m1))
1092 ifp->if_oerrorsif_data.ifi_oerrors++;
1093 }
1094 }
1095#endif
1096 if (m != NULL((void *)0)) {
1097 if ((ic->ic_flags & IEEE80211_F_RSNON0x00200000) &&
1098 eh->ether_type == htons(ETHERTYPE_EAPOL)(__uint16_t)(__builtin_constant_p(0x888E) ? (__uint16_t)(((__uint16_t
)(0x888E) & 0xffU) << 8 | ((__uint16_t)(0x888E) &
0xff00U) >> 8) : __swap16md(0x888E))
) {
1099 ifp->if_ipacketsif_data.ifi_ipackets++;
1100#if NBPFILTER1 > 0
1101 /*
1102 * If we forward frame into transmitter of the AP,
1103 * we don't need to duplicate for DLT_EN10MB.
1104 */
1105 if (ifp->if_bpf && m1 == NULL((void *)0))
1106 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN(1 << 0));
1107#endif
1108 ieee80211_eapol_key_input(ic, m, ni);
1109 } else {
1110 ml_enqueue(ml, m);
1111 }
1112 }
1113}
1114
1115void
1116ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
1117 struct ieee80211_node *ni, int hdrlen, struct mbuf_list *ml)
1118{
1119 struct ether_header eh;
1120 struct ieee80211_frame *wh;
1121 struct llc *llc;
1122 int mcast;
1123
1124 if (m->m_lenm_hdr.mh_len < hdrlen + LLC_SNAPFRAMELEN8 &&
1125 (m = m_pullup(m, hdrlen + LLC_SNAPFRAMELEN8)) == NULL((void *)0)) {
1126 ic->ic_stats.is_rx_decap++;
1127 return;
1128 }
1129 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1130 mcast = IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01);
1131 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK0x03) {
1132 case IEEE80211_FC1_DIR_NODS0x00:
1133 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1)__builtin_memcpy((eh.ether_dhost), (wh->i_addr1), (6));
1134 IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2)__builtin_memcpy((eh.ether_shost), (wh->i_addr2), (6));
1135 break;
1136 case IEEE80211_FC1_DIR_TODS0x01:
1137 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3)__builtin_memcpy((eh.ether_dhost), (wh->i_addr3), (6));
1138 IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2)__builtin_memcpy((eh.ether_shost), (wh->i_addr2), (6));
1139 break;
1140 case IEEE80211_FC1_DIR_FROMDS0x02:
1141 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1)__builtin_memcpy((eh.ether_dhost), (wh->i_addr1), (6));
1142 IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr3)__builtin_memcpy((eh.ether_shost), (wh->i_addr3), (6));
1143 break;
1144 case IEEE80211_FC1_DIR_DSTODS0x03:
1145 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3)__builtin_memcpy((eh.ether_dhost), (wh->i_addr3), (6));
1146 IEEE80211_ADDR_COPY(eh.ether_shost,__builtin_memcpy((eh.ether_shost), (((struct ieee80211_frame_addr4
*)wh)->i_addr4), (6))
1147 ((struct ieee80211_frame_addr4 *)wh)->i_addr4)__builtin_memcpy((eh.ether_shost), (((struct ieee80211_frame_addr4
*)wh)->i_addr4), (6))
;
1148 break;
1149 }
1150 llc = (struct llc *)((caddr_t)wh + hdrlen);
1151 if (llc->llc_dsap == LLC_SNAP_LSAP0xaa &&
1152 llc->llc_ssap == LLC_SNAP_LSAP0xaa &&
1153 llc->llc_controlllc_un.type_u.control == LLC_UI0x3 &&
1154 llc->llc_snapllc_un.type_snap.org_code[0] == 0 &&
1155 llc->llc_snapllc_un.type_snap.org_code[1] == 0 &&
1156 llc->llc_snapllc_un.type_snap.org_code[2] == 0) {
1157 eh.ether_type = llc->llc_snapllc_un.type_snap.ether_type;
1158 m_adj(m, hdrlen + LLC_SNAPFRAMELEN8 - ETHER_HDR_LEN((6 * 2) + 2));
1159 } else {
1160 eh.ether_type = htons(m->m_pkthdr.len - hdrlen)(__uint16_t)(__builtin_constant_p(m->M_dat.MH.MH_pkthdr.len
- hdrlen) ? (__uint16_t)(((__uint16_t)(m->M_dat.MH.MH_pkthdr
.len - hdrlen) & 0xffU) << 8 | ((__uint16_t)(m->
M_dat.MH.MH_pkthdr.len - hdrlen) & 0xff00U) >> 8) :
__swap16md(m->M_dat.MH.MH_pkthdr.len - hdrlen))
;
1161 m_adj(m, hdrlen - ETHER_HDR_LEN((6 * 2) + 2));
1162 }
1163 memcpy(mtod(m, caddr_t), &eh, ETHER_HDR_LEN)__builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data))), (&
eh), (((6 * 2) + 2)))
;
1164 if (!ALIGNED_POINTER(mtod(m, caddr_t) + ETHER_HDR_LEN, u_int32_t)1) {
1165 struct mbuf *m0 = m;
1166 m = m_dup_pkt(m0, ETHER_ALIGN2, M_NOWAIT0x0002);
1167 m_freem(m0);
1168 if (m == NULL((void *)0)) {
1169 ic->ic_stats.is_rx_decap++;
1170 return;
1171 }
1172 }
1173 ieee80211_enqueue_data(ic, m, ni, mcast, ml);
1174}
1175
1176int
1177ieee80211_amsdu_decap_validate(struct ieee80211com *ic, struct mbuf *m,
1178 struct ieee80211_node *ni)
1179{
1180 struct ether_header *eh = mtod(m, struct ether_header *)((struct ether_header *)((m)->m_hdr.mh_data));
1181 const uint8_t llc_hdr_mac[ETHER_ADDR_LEN6] = {
1182 /* MAC address matching the 802.2 LLC header. */
1183 LLC_SNAP_LSAP0xaa, LLC_SNAP_LSAP0xaa, LLC_UI0x3, 0, 0, 0
1184 };
1185
1186 /*
1187 * We are sorry, but this particular MAC address cannot be used.
1188 * This mitigates an attack where a single 802.11 frame is interpreted
1189 * as an A-MSDU because of a forged AMSDU-present bit in the 802.11
1190 * QoS frame header: https://papers.mathyvanhoef.com/usenix2021.pdf
1191 * See Section 7.2, 'Countermeasures for the design flaws'
1192 */
1193 if (ETHER_IS_EQ(eh->ether_dhost, llc_hdr_mac)(__builtin_memcmp(((eh->ether_dhost)), ((llc_hdr_mac)), (6
)) == 0)
)
1194 return 1;
1195
1196 switch (ic->ic_opmode) {
1197#ifndef IEEE80211_STA_ONLY
1198 case IEEE80211_M_HOSTAP:
1199 /*
1200 * Subframes must use the source address of the node which
1201 * transmitted the A-MSDU. Prevents MAC spoofing.
1202 */
1203 if (!ETHER_IS_EQ(ni->ni_macaddr, eh->ether_shost)(__builtin_memcmp(((ni->ni_macaddr)), ((eh->ether_shost
)), (6)) == 0)
)
1204 return 1;
1205 break;
1206#endif
1207 case IEEE80211_M_STA:
1208 /* Subframes must be addressed to me. */
1209 if (!ETHER_IS_EQ(ic->ic_myaddr, eh->ether_dhost)(__builtin_memcmp(((ic->ic_myaddr)), ((eh->ether_dhost)
), (6)) == 0)
)
1210 return 1;
1211 break;
1212 default:
1213 /* Ignore MONITOR/IBSS modes for now. */
1214 break;
1215 }
1216
1217 return 0;
1218}
1219
1220/*
1221 * Decapsulate an Aggregate MSDU (see 7.2.2.2).
1222 */
1223void
1224ieee80211_amsdu_decap(struct ieee80211com *ic, struct mbuf *m,
1225 struct ieee80211_node *ni, int hdrlen, struct mbuf_list *ml)
1226{
1227 struct mbuf *n;
1228 struct ether_header *eh;
1229 struct llc *llc;
1230 int len, pad, mcast;
1231 struct ieee80211_frame *wh;
1232 struct mbuf_list subframes = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
1233
1234 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1235 mcast = IEEE80211_IS_MULTICAST(wh->i_addr1)(*(wh->i_addr1) & 0x01);
1236
1237 /* strip 802.11 header */
1238 m_adj(m, hdrlen);
1239
1240 while (m->m_pkthdrM_dat.MH.MH_pkthdr.len >= ETHER_HDR_LEN((6 * 2) + 2) + LLC_SNAPFRAMELEN8) {
1241 /* process an A-MSDU subframe */
1242 m = m_pullup(m, ETHER_HDR_LEN((6 * 2) + 2) + LLC_SNAPFRAMELEN8);
1243 if (m == NULL((void *)0))
1244 break;
1245 eh = mtod(m, struct ether_header *)((struct ether_header *)((m)->m_hdr.mh_data));
1246 /* examine 802.3 header */
1247 len = ntohs(eh->ether_type)(__uint16_t)(__builtin_constant_p(eh->ether_type) ? (__uint16_t
)(((__uint16_t)(eh->ether_type) & 0xffU) << 8 | (
(__uint16_t)(eh->ether_type) & 0xff00U) >> 8) : __swap16md
(eh->ether_type))
;
1248 if (len < LLC_SNAPFRAMELEN8) {
1249 DPRINTF(("A-MSDU subframe too short (%d)\n", len));
1250 /* stop processing A-MSDU subframes */
1251 ic->ic_stats.is_rx_decap++;
1252 ml_purge(&subframes);
1253 m_freem(m);
1254 return;
1255 }
1256 llc = (struct llc *)&eh[1];
1257 /* Examine the 802.2 LLC header after the A-MSDU header. */
1258 if (llc->llc_dsap == LLC_SNAP_LSAP0xaa &&
1259 llc->llc_ssap == LLC_SNAP_LSAP0xaa &&
1260 llc->llc_controlllc_un.type_u.control == LLC_UI0x3 &&
1261 llc->llc_snapllc_un.type_snap.org_code[0] == 0 &&
1262 llc->llc_snapllc_un.type_snap.org_code[1] == 0 &&
1263 llc->llc_snapllc_un.type_snap.org_code[2] == 0) {
1264 /* convert to Ethernet II header */
1265 eh->ether_type = llc->llc_snapllc_un.type_snap.ether_type;
1266 /* strip LLC+SNAP headers */
1267 memmove((u_int8_t *)eh + LLC_SNAPFRAMELEN, eh,__builtin_memmove(((u_int8_t *)eh + 8), (eh), (((6 * 2) + 2))
)
1268 ETHER_HDR_LEN)__builtin_memmove(((u_int8_t *)eh + 8), (eh), (((6 * 2) + 2))
)
;
1269 m_adj(m, LLC_SNAPFRAMELEN8);
1270 len -= LLC_SNAPFRAMELEN8;
1271 }
1272 len += ETHER_HDR_LEN((6 * 2) + 2);
1273 if (len > m->m_pkthdrM_dat.MH.MH_pkthdr.len) {
1274 /* stop processing A-MSDU subframes */
1275 DPRINTF(("A-MSDU subframe too long (%d)\n", len));
1276 ic->ic_stats.is_rx_decap++;
1277 ml_purge(&subframes);
1278 m_freem(m);
1279 return;
1280 }
1281
1282 /* "detach" our A-MSDU subframe from the others */
1283 n = m_split(m, len, M_NOWAIT0x0002);
1284 if (n == NULL((void *)0)) {
1285 /* stop processing A-MSDU subframes */
1286 ic->ic_stats.is_rx_decap++;
1287 ml_purge(&subframes);
1288 m_freem(m);
1289 return;
1290 }
1291
1292 if (ieee80211_amsdu_decap_validate(ic, m, ni)) {
1293 /* stop processing A-MSDU subframes */
1294 ic->ic_stats.is_rx_decap++;
1295 ml_purge(&subframes);
1296 m_freem(m);
1297 return;
1298 }
1299
1300 ml_enqueue(&subframes, m);
1301
1302 m = n;
1303 /* remove padding */
1304 pad = ((len + 3) & ~3) - len;
1305 m_adj(m, pad);
1306 }
1307
1308 while ((n = ml_dequeue(&subframes)) != NULL((void *)0))
1309 ieee80211_enqueue_data(ic, n, ni, mcast, ml);
1310
1311 m_freem(m);
1312}
1313
1314/*
1315 * Parse an EDCA Parameter Set element (see 7.3.2.27).
1316 */
1317int
1318ieee80211_parse_edca_params_body(struct ieee80211com *ic, const u_int8_t *frm)
1319{
1320 u_int updtcount;
1321 int aci;
1322
1323 /*
1324 * Check if EDCA parameters have changed XXX if we miss more than
1325 * 15 consecutive beacons, we might not detect changes to EDCA
1326 * parameters due to wraparound of the 4-bit Update Count field.
1327 */
1328 updtcount = frm[0] & 0xf;
1329 if (updtcount == ic->ic_edca_updtcount)
1330 return 0; /* no changes to EDCA parameters, ignore */
1331 ic->ic_edca_updtcount = updtcount;
1332
1333 frm += 2; /* skip QoS Info & Reserved fields */
1334
1335 /* parse AC Parameter Records */
1336 for (aci = 0; aci < EDCA_NUM_AC4; aci++) {
1337 struct ieee80211_edca_ac_params *ac = &ic->ic_edca_ac[aci];
1338
1339 ac->ac_acm = (frm[0] >> 4) & 0x1;
1340 ac->ac_aifsn = frm[0] & 0xf;
1341 ac->ac_ecwmin = frm[1] & 0xf;
1342 ac->ac_ecwmax = frm[1] >> 4;
1343 ac->ac_txoplimit = LE_READ_2(frm + 2)((u_int16_t) ((((const u_int8_t *)(frm + 2))[0]) | (((const u_int8_t
*)(frm + 2))[1] << 8)))
;
1344 frm += 4;
1345 }
1346 /* give drivers a chance to update their settings */
1347 if ((ic->ic_flags & IEEE80211_F_QOS0x00080000) && ic->ic_updateedca != NULL((void *)0))
1348 (*ic->ic_updateedca)(ic);
1349
1350 return 0;
1351}
1352
1353int
1354ieee80211_parse_edca_params(struct ieee80211com *ic, const u_int8_t *frm)
1355{
1356 if (frm[1] < 18) {
1357 ic->ic_stats.is_rx_elem_toosmall++;
1358 return IEEE80211_REASON_IE_INVALID;
1359 }
1360 return ieee80211_parse_edca_params_body(ic, frm + 2);
1361}
1362
1363int
1364ieee80211_parse_wmm_params(struct ieee80211com *ic, const u_int8_t *frm)
1365{
1366 if (frm[1] < 24) {
1367 ic->ic_stats.is_rx_elem_toosmall++;
1368 return IEEE80211_REASON_IE_INVALID;
1369 }
1370 return ieee80211_parse_edca_params_body(ic, frm + 8);
1371}
1372
1373enum ieee80211_cipher
1374ieee80211_parse_rsn_cipher(const u_int8_t selector[4])
1375{
1376 if (memcmp(selector, MICROSOFT_OUI, 3)__builtin_memcmp((selector), (((const u_int8_t[]){ 0x00, 0x50
, 0xf2 })), (3))
== 0) { /* WPA */
1377 switch (selector[3]) {
1378 case 0: /* use group data cipher suite */
1379 return IEEE80211_CIPHER_USEGROUP;
1380 case 1: /* WEP-40 */
1381 return IEEE80211_CIPHER_WEP40;
1382 case 2: /* TKIP */
1383 return IEEE80211_CIPHER_TKIP;
1384 case 4: /* CCMP (RSNA default) */
1385 return IEEE80211_CIPHER_CCMP;
1386 case 5: /* WEP-104 */
1387 return IEEE80211_CIPHER_WEP104;
1388 }
1389 } else if (memcmp(selector, IEEE80211_OUI, 3)__builtin_memcmp((selector), (((const u_int8_t[]){ 0x00, 0x0f
, 0xac })), (3))
== 0) { /* RSN */
1390 /* see 802.11-2012 Table 8-99 */
1391 switch (selector[3]) {
1392 case 0: /* use group data cipher suite */
1393 return IEEE80211_CIPHER_USEGROUP;
1394 case 1: /* WEP-40 */
1395 return IEEE80211_CIPHER_WEP40;
1396 case 2: /* TKIP */
1397 return IEEE80211_CIPHER_TKIP;
1398 case 4: /* CCMP (RSNA default) */
1399 return IEEE80211_CIPHER_CCMP;
1400 case 5: /* WEP-104 */
1401 return IEEE80211_CIPHER_WEP104;
1402 case 6: /* BIP */
1403 return IEEE80211_CIPHER_BIP;
1404 }
1405 }
1406 return IEEE80211_CIPHER_NONE; /* ignore unknown ciphers */
1407}
1408
1409enum ieee80211_akm
1410ieee80211_parse_rsn_akm(const u_int8_t selector[4])
1411{
1412 if (memcmp(selector, MICROSOFT_OUI, 3)__builtin_memcmp((selector), (((const u_int8_t[]){ 0x00, 0x50
, 0xf2 })), (3))
== 0) { /* WPA */
1413 switch (selector[3]) {
1414 case 1: /* IEEE 802.1X (RSNA default) */
1415 return IEEE80211_AKM_8021X;
1416 case 2: /* PSK */
1417 return IEEE80211_AKM_PSK;
1418 }
1419 } else if (memcmp(selector, IEEE80211_OUI, 3)__builtin_memcmp((selector), (((const u_int8_t[]){ 0x00, 0x0f
, 0xac })), (3))
== 0) { /* RSN */
1420 /* from IEEE Std 802.11i-2004 - Table 20dc */
1421 switch (selector[3]) {
1422 case 1: /* IEEE 802.1X (RSNA default) */
1423 return IEEE80211_AKM_8021X;
1424 case 2: /* PSK */
1425 return IEEE80211_AKM_PSK;
1426 case 5: /* IEEE 802.1X with SHA256 KDF */
1427 return IEEE80211_AKM_SHA256_8021X;
1428 case 6: /* PSK with SHA256 KDF */
1429 return IEEE80211_AKM_SHA256_PSK;
1430 }
1431 }
1432 return IEEE80211_AKM_NONE; /* ignore unknown AKMs */
1433}
1434
1435/*
1436 * Parse an RSN element (see 802.11-2012 8.4.2.27)
1437 */
1438int
1439ieee80211_parse_rsn_body(struct ieee80211com *ic, const u_int8_t *frm,
1440 u_int len, struct ieee80211_rsnparams *rsn)
1441{
1442 const u_int8_t *efrm;
1443 u_int16_t m, n, s;
1444
1445 efrm = frm + len;
1446
1447 /* check Version field */
1448 if (LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
!= 1)
1449 return IEEE80211_STATUS_RSN_IE_VER_UNSUP;
1450 frm += 2;
1451
1452 /* all fields after the Version field are optional */
1453
1454 /* if Cipher Suite missing, default to CCMP */
1455 rsn->rsn_groupcipher = IEEE80211_CIPHER_CCMP;
1456 rsn->rsn_nciphers = 1;
1457 rsn->rsn_ciphers = IEEE80211_CIPHER_CCMP;
1458 /* if Group Management Cipher Suite missing, default to BIP */
1459 rsn->rsn_groupmgmtcipher = IEEE80211_CIPHER_BIP;
1460 /* if AKM Suite missing, default to 802.1X */
1461 rsn->rsn_nakms = 1;
1462 rsn->rsn_akms = IEEE80211_AKM_8021X;
1463 /* if RSN capabilities missing, default to 0 */
1464 rsn->rsn_caps = 0;
1465 rsn->rsn_npmkids = 0;
1466
1467 /* read Group Data Cipher Suite field */
1468 if (frm + 4 > efrm)
1469 return 0;
1470 rsn->rsn_groupcipher = ieee80211_parse_rsn_cipher(frm);
1471 if (rsn->rsn_groupcipher == IEEE80211_CIPHER_NONE ||
1472 rsn->rsn_groupcipher == IEEE80211_CIPHER_USEGROUP ||
1473 rsn->rsn_groupcipher == IEEE80211_CIPHER_BIP)
1474 return IEEE80211_STATUS_BAD_GROUP_CIPHER;
1475 frm += 4;
1476
1477 /* read Pairwise Cipher Suite Count field */
1478 if (frm + 2 > efrm)
1479 return 0;
1480 m = rsn->rsn_nciphers = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
;
1481 frm += 2;
1482
1483 /* read Pairwise Cipher Suite List */
1484 if (frm + m * 4 > efrm)
1485 return IEEE80211_STATUS_IE_INVALID;
1486 rsn->rsn_ciphers = IEEE80211_CIPHER_NONE;
1487 while (m-- > 0) {
1488 rsn->rsn_ciphers |= ieee80211_parse_rsn_cipher(frm);
1489 frm += 4;
1490 }
1491 if (rsn->rsn_ciphers & IEEE80211_CIPHER_USEGROUP) {
1492 if (rsn->rsn_ciphers != IEEE80211_CIPHER_USEGROUP)
1493 return IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
1494 if (rsn->rsn_groupcipher == IEEE80211_CIPHER_CCMP)
1495 return IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
1496 }
1497
1498 /* read AKM Suite List Count field */
1499 if (frm + 2 > efrm)
1500 return 0;
1501 n = rsn->rsn_nakms = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
;
1502 frm += 2;
1503
1504 /* read AKM Suite List */
1505 if (frm + n * 4 > efrm)
1506 return IEEE80211_STATUS_IE_INVALID;
1507 rsn->rsn_akms = IEEE80211_AKM_NONE;
1508 while (n-- > 0) {
1509 rsn->rsn_akms |= ieee80211_parse_rsn_akm(frm);
1510 frm += 4;
1511 }
1512
1513 /* read RSN Capabilities field */
1514 if (frm + 2 > efrm)
1515 return 0;
1516 rsn->rsn_caps = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
;
1517 frm += 2;
1518
1519 /* read PMKID Count field */
1520 if (frm + 2 > efrm)
1521 return 0;
1522 s = rsn->rsn_npmkids = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
;
1523 frm += 2;
1524
1525 /* read PMKID List */
1526 if (frm + s * IEEE80211_PMKID_LEN16 > efrm)
1527 return IEEE80211_STATUS_IE_INVALID;
1528 if (s != 0) {
1529 rsn->rsn_pmkids = frm;
1530 frm += s * IEEE80211_PMKID_LEN16;
1531 }
1532
1533 /* read Group Management Cipher Suite field */
1534 if (frm + 4 > efrm)
1535 return 0;
1536 rsn->rsn_groupmgmtcipher = ieee80211_parse_rsn_cipher(frm);
1537 if (rsn->rsn_groupmgmtcipher != IEEE80211_CIPHER_BIP)
1538 return IEEE80211_STATUS_BAD_GROUP_CIPHER;
1539
1540 return IEEE80211_STATUS_SUCCESS;
1541}
1542
1543int
1544ieee80211_parse_rsn(struct ieee80211com *ic, const u_int8_t *frm,
1545 struct ieee80211_rsnparams *rsn)
1546{
1547 if (frm[1] < 2) {
1548 ic->ic_stats.is_rx_elem_toosmall++;
1549 return IEEE80211_STATUS_IE_INVALID;
1550 }
1551 return ieee80211_parse_rsn_body(ic, frm + 2, frm[1], rsn);
1552}
1553
1554int
1555ieee80211_parse_wpa(struct ieee80211com *ic, const u_int8_t *frm,
1556 struct ieee80211_rsnparams *rsn)
1557{
1558 if (frm[1] < 6) {
1559 ic->ic_stats.is_rx_elem_toosmall++;
1560 return IEEE80211_STATUS_IE_INVALID;
1561 }
1562 return ieee80211_parse_rsn_body(ic, frm + 6, frm[1] - 4, rsn);
1563}
1564
1565/*
1566 * Create (or update) a copy of an information element.
1567 */
1568int
1569ieee80211_save_ie(const u_int8_t *frm, u_int8_t **ie)
1570{
1571 int olen = *ie ? 2 + (*ie)[1] : 0;
1572 int len = 2 + frm[1];
1573
1574 if (*ie == NULL((void *)0) || olen != len) {
1575 if (*ie != NULL((void *)0))
1576 free(*ie, M_DEVBUF2, olen);
1577 *ie = malloc(len, M_DEVBUF2, M_NOWAIT0x0002);
1578 if (*ie == NULL((void *)0))
1579 return ENOMEM12;
1580 }
1581 memcpy(*ie, frm, len)__builtin_memcpy((*ie), (frm), (len));
1582 return 0;
1583}
1584
1585/*-
1586 * Beacon/Probe response frame format:
1587 * [8] Timestamp
1588 * [2] Beacon interval
1589 * [2] Capability
1590 * [tlv] Service Set Identifier (SSID)
1591 * [tlv] Supported rates
1592 * [tlv] DS Parameter Set (802.11g)
1593 * [tlv] ERP Information (802.11g)
1594 * [tlv] Extended Supported Rates (802.11g)
1595 * [tlv] RSN (802.11i)
1596 * [tlv] EDCA Parameter Set (802.11e)
1597 * [tlv] QoS Capability (Beacon only, 802.11e)
1598 * [tlv] HT Capabilities (802.11n)
1599 * [tlv] HT Operation (802.11n)
1600 */
1601void
1602ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
1603 struct ieee80211_node *rni, struct ieee80211_rxinfo *rxi, int isprobe)
1604{
1605 struct ieee80211_node *ni;
1606 const struct ieee80211_frame *wh;
1607 const u_int8_t *frm, *efrm;
1608 const u_int8_t *tstamp, *ssid, *rates, *xrates, *edcaie, *wmmie;
1609 const u_int8_t *rsnie, *wpaie, *htcaps, *htop;
1610 u_int16_t capinfo, bintval;
1611 u_int8_t chan, bchan, erp, dtim_count, dtim_period;
1612 int is_new;
1613
1614 /*
1615 * We process beacon/probe response frames for:
1616 * o station mode: to collect state
1617 * updates such as 802.11g slot time and for passive
1618 * scanning of APs
1619 * o adhoc mode: to discover neighbors
1620 * o hostap mode: for passive scanning of neighbor APs
1621 * o when scanning
1622 * In other words, in all modes other than monitor (which
1623 * does not process incoming frames) and adhoc-demo (which
1624 * does not use management frames at all).
1625 */
1626#ifdef DIAGNOSTIC1
1627 if (ic->ic_opmode != IEEE80211_M_STA &&
1628#ifndef IEEE80211_STA_ONLY
1629 ic->ic_opmode != IEEE80211_M_IBSS &&
1630 ic->ic_opmode != IEEE80211_M_HOSTAP &&
1631#endif
1632 ic->ic_state != IEEE80211_S_SCAN) {
1633 panic("%s: impossible operating mode", __func__);
1634 }
1635#endif
1636 /* make sure all mandatory fixed fields are present */
1637 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 12) {
1638 DPRINTF(("frame too short\n"));
1639 return;
1640 }
1641 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
1642 frm = (const u_int8_t *)&wh[1];
1643 efrm = mtod(m, u_int8_t *)((u_int8_t *)((m)->m_hdr.mh_data)) + m->m_lenm_hdr.mh_len;
1644
1645 tstamp = frm; frm += 8;
1646 bintval = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
1647 capinfo = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
1648
1649 ssid = rates = xrates = edcaie = wmmie = rsnie = wpaie = NULL((void *)0);
1650 htcaps = htop = NULL((void *)0);
1651 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1652 chan = bchan;
1653 erp = 0;
1654 dtim_count = dtim_period = 0;
1655 while (frm + 2 <= efrm) {
1656 if (frm + 2 + frm[1] > efrm) {
1657 ic->ic_stats.is_rx_elem_toosmall++;
1658 break;
1659 }
1660 switch (frm[0]) {
1661 case IEEE80211_ELEMID_SSID:
1662 ssid = frm;
1663 break;
1664 case IEEE80211_ELEMID_RATES:
1665 rates = frm;
1666 break;
1667 case IEEE80211_ELEMID_DSPARMS:
1668 if (frm[1] < 1) {
1669 ic->ic_stats.is_rx_elem_toosmall++;
1670 break;
1671 }
1672 chan = frm[2];
1673 break;
1674 case IEEE80211_ELEMID_XRATES:
1675 xrates = frm;
1676 break;
1677 case IEEE80211_ELEMID_ERP:
1678 if (frm[1] < 1) {
1679 ic->ic_stats.is_rx_elem_toosmall++;
1680 break;
1681 }
1682 erp = frm[2];
1683 break;
1684 case IEEE80211_ELEMID_RSN:
1685 rsnie = frm;
1686 break;
1687 case IEEE80211_ELEMID_EDCAPARMS:
1688 edcaie = frm;
1689 break;
1690 case IEEE80211_ELEMID_HTCAPS:
1691 htcaps = frm;
1692 break;
1693 case IEEE80211_ELEMID_HTOP:
1694 htop = frm;
1695 break;
1696 case IEEE80211_ELEMID_TIM:
1697 if (frm[1] > 3) {
1698 dtim_count = frm[2];
1699 dtim_period = frm[3];
1700 }
1701 break;
1702 case IEEE80211_ELEMID_VENDOR:
1703 if (frm[1] < 4) {
1704 ic->ic_stats.is_rx_elem_toosmall++;
1705 break;
1706 }
1707 if (memcmp(frm + 2, MICROSOFT_OUI, 3)__builtin_memcmp((frm + 2), (((const u_int8_t[]){ 0x00, 0x50,
0xf2 })), (3))
== 0) {
1708 if (frm[5] == 1)
1709 wpaie = frm;
1710 else if (frm[1] >= 5 &&
1711 frm[5] == 2 && frm[6] == 1)
1712 wmmie = frm;
1713 }
1714 break;
1715 }
1716 frm += 2 + frm[1];
1717 }
1718 /* supported rates element is mandatory */
1719 if (rates == NULL((void *)0) || rates[1] > IEEE80211_RATE_MAXSIZE15) {
1720 DPRINTF(("invalid supported rates element\n"));
1721 return;
1722 }
1723 /* SSID element is mandatory */
1724 if (ssid == NULL((void *)0) || ssid[1] > IEEE80211_NWID_LEN32) {
1725 DPRINTF(("invalid SSID element\n"));
1726 return;
1727 }
1728
1729 if (
1730#if IEEE80211_CHAN_MAX255 < 255
1731 chan > IEEE80211_CHAN_MAX255 ||
1732#endif
1733 isclr(ic->ic_chan_active, chan)(((ic->ic_chan_active)[(chan)>>3] & (1<<((
chan)&(8 -1)))) == 0)
) {
1734 DPRINTF(("ignore %s with invalid channel %u\n",
1735 isprobe ? "probe response" : "beacon", chan));
1736 ic->ic_stats.is_rx_badchan++;
1737 return;
1738 }
1739 if ((ic->ic_state != IEEE80211_S_SCAN ||
1740 !(ic->ic_caps & IEEE80211_C_SCANALL0x00000400)) &&
1741 chan != bchan) {
1742 /*
1743 * Frame was received on a channel different from the
1744 * one indicated in the DS params element id;
1745 * silently discard it.
1746 *
1747 * NB: this can happen due to signal leakage.
1748 */
1749 DPRINTF(("ignore %s on channel %u marked for channel %u\n",
1750 isprobe ? "probe response" : "beacon", bchan, chan));
1751 ic->ic_stats.is_rx_chanmismatch++;
1752 return;
1753 }
1754
1755#ifdef IEEE80211_DEBUG
1756 if (ieee80211_debug > 1 &&
1757 (ni == NULL((void *)0) || ic->ic_state == IEEE80211_S_SCAN ||
1758 (ic->ic_flags & IEEE80211_F_BGSCAN0x08000000))) {
1759 printf("%s: %s%s on chan %u (bss chan %u) ",
1760 __func__, (ni == NULL((void *)0) ? "new " : ""),
1761 isprobe ? "probe response" : "beacon",
1762 chan, bchan);
1763 ieee80211_print_essid(ssid + 2, ssid[1]);
1764 printf(" from %s\n", ether_sprintf((u_int8_t *)wh->i_addr2));
1765 printf("%s: caps 0x%x bintval %u erp 0x%x\n",
1766 __func__, capinfo, bintval, erp);
1767 }
1768#endif
1769
1770 if ((ni = ieee80211_find_node(ic, wh->i_addr2)) == NULL((void *)0)) {
1771 ni = ieee80211_alloc_node(ic, wh->i_addr2);
1772 if (ni == NULL((void *)0))
1773 return;
1774 is_new = 1;
1775 } else
1776 is_new = 0;
1777
1778 if (htcaps)
1779 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
1780 if (htop && !ieee80211_setup_htop(ni, htop + 2, htop[1], 1))
1781 htop = NULL((void *)0); /* invalid HTOP */
1782
1783 ni->ni_dtimcount = dtim_count;
1784 ni->ni_dtimperiod = dtim_period;
1785
1786 /*
1787 * When operating in station mode, check for state updates
1788 * while we're associated.
1789 */
1790 if (ic->ic_opmode == IEEE80211_M_STA &&
1791 ic->ic_state == IEEE80211_S_RUN &&
1792 ni->ni_state == IEEE80211_STA_BSS) {
1793 int updateprot = 0;
1794 /*
1795 * Check if protection mode has changed since last beacon.
1796 */
1797 if (ni->ni_erp != erp) {
1798 DPRINTF(("[%s] erp change: was 0x%x, now 0x%x\n",
1799 ether_sprintf((u_int8_t *)wh->i_addr2),
1800 ni->ni_erp, erp));
1801 if ((ic->ic_curmode == IEEE80211_MODE_11G ||
1802 (ic->ic_curmode == IEEE80211_MODE_11N &&
1803 IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)(((ni->ni_chan)->ic_flags & 0x0080) != 0))) &&
1804 (erp & IEEE80211_ERP_USE_PROTECTION0x02))
1805 ic->ic_flags |= IEEE80211_F_USEPROT0x00100000;
1806 else
1807 ic->ic_flags &= ~IEEE80211_F_USEPROT0x00100000;
1808 ic->ic_bss->ni_erp = erp;
1809 updateprot = 1;
1810 }
1811 if (htop && (ic->ic_bss->ni_flags & IEEE80211_NODE_HT0x0400)) {
1812 enum ieee80211_htprot htprot_last, htprot;
1813 htprot_last =
1814 ((ic->ic_bss->ni_htop1 & IEEE80211_HTOP1_PROT_MASK0x0003)
1815 >> IEEE80211_HTOP1_PROT_SHIFT0);
1816 htprot = ((ni->ni_htop1 & IEEE80211_HTOP1_PROT_MASK0x0003) >>
1817 IEEE80211_HTOP1_PROT_SHIFT0);
1818 if (htprot_last != htprot) {
1819 DPRINTF(("[%s] htprot change: was %d, now %d\n",
1820 ether_sprintf((u_int8_t *)wh->i_addr2),
1821 htprot_last, htprot));
1822 ic->ic_stats.is_ht_prot_change++;
1823 ic->ic_bss->ni_htop1 = ni->ni_htop1;
1824 updateprot = 1;
1825 }
1826 }
1827 if (updateprot && ic->ic_updateprot != NULL((void *)0))
1828 ic->ic_updateprot(ic);
1829
1830 /*
1831 * Check if 40MHz channel mode has changed since last beacon.
1832 */
1833 if (htop && (ic->ic_bss->ni_flags & IEEE80211_NODE_HT0x0400) &&
1834 (ic->ic_htcaps & IEEE80211_HTCAP_CBW20_400x00000002)) {
1835 uint8_t chw_last, chw, sco_last, sco;
1836 chw_last = (ic->ic_bss->ni_htop0 & IEEE80211_HTOP0_CHW0x04);
1837 chw = (ni->ni_htop0 & IEEE80211_HTOP0_CHW0x04);
1838 sco_last =
1839 ((ic->ic_bss->ni_htop0 & IEEE80211_HTOP0_SCO_MASK0x03)
1840 >> IEEE80211_HTOP0_SCO_SHIFT0);
1841 sco = ((ni->ni_htop0 & IEEE80211_HTOP0_SCO_MASK0x03) >>
1842 IEEE80211_HTOP0_SCO_SHIFT0);
1843 ic->ic_bss->ni_htop0 = ni->ni_htop0;
1844 if (chw_last != chw || sco_last != sco) {
1845 if (ic->ic_updatechan != NULL((void *)0))
1846 ic->ic_updatechan(ic);
1847 }
1848 } else if (htop)
1849 ic->ic_bss->ni_htop0 = ni->ni_htop0;
1850
1851 /*
1852 * Check if AP short slot time setting has changed
1853 * since last beacon and give the driver a chance to
1854 * update the hardware.
1855 */
1856 if ((ni->ni_capinfo ^ capinfo) &
1857 IEEE80211_CAPINFO_SHORT_SLOTTIME0x0400) {
1858 ieee80211_set_shortslottime(ic,
1859 ic->ic_curmode == IEEE80211_MODE_11A ||
1860 (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME0x0400));
1861 }
1862
1863 /*
1864 * Reset management timer. If it is non-zero in RUN state, the
1865 * driver sent a probe request after a missed beacon event.
1866 * This probe response indicates the AP is still serving us
1867 * so don't allow ieee80211_watchdog() to move us into SCAN.
1868 */
1869 if ((ic->ic_flags & IEEE80211_F_BGSCAN0x08000000) == 0)
1870 ic->ic_mgt_timer = 0;
1871 }
1872 /*
1873 * We do not try to update EDCA parameters if QoS was not negotiated
1874 * with the AP at association time.
1875 */
1876 if (ni->ni_flags & IEEE80211_NODE_QOS0x0002) {
1877 /* always prefer EDCA IE over Wi-Fi Alliance WMM IE */
1878 if ((edcaie != NULL((void *)0) &&
1879 ieee80211_parse_edca_params(ic, edcaie) == 0) ||
1880 (wmmie != NULL((void *)0) &&
1881 ieee80211_parse_wmm_params(ic, wmmie) == 0))
1882 ni->ni_flags |= IEEE80211_NODE_QOS0x0002;
1883 else
1884 ni->ni_flags &= ~IEEE80211_NODE_QOS0x0002;
1885 }
1886
1887 if (ic->ic_state == IEEE80211_S_SCAN ||
1888 (ic->ic_flags & IEEE80211_F_BGSCAN0x08000000)) {
1889 struct ieee80211_rsnparams rsn, wpa;
1890
1891 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
1892 ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE0;
1893 ni->ni_rsnakms = 0;
1894 ni->ni_supported_rsnakms = 0;
1895 ni->ni_rsnciphers = 0;
1896 ni->ni_rsngroupcipher = 0;
1897 ni->ni_rsngroupmgmtcipher = 0;
1898 ni->ni_rsncaps = 0;
1899
1900 if (rsnie != NULL((void *)0) &&
1901 ieee80211_parse_rsn(ic, rsnie, &rsn) == 0) {
1902 ni->ni_supported_rsnprotos |= IEEE80211_PROTO_RSN(1 << 0);
1903 ni->ni_supported_rsnakms |= rsn.rsn_akms;
1904 }
1905 if (wpaie != NULL((void *)0) &&
1906 ieee80211_parse_wpa(ic, wpaie, &wpa) == 0) {
1907 ni->ni_supported_rsnprotos |= IEEE80211_PROTO_WPA(1 << 1);
1908 ni->ni_supported_rsnakms |= wpa.rsn_akms;
1909 }
1910
1911 /*
1912 * If the AP advertises both WPA and RSN IEs (WPA1+WPA2),
1913 * we only use the highest protocol version we support.
1914 */
1915 if (rsnie != NULL((void *)0) &&
1916 (ni->ni_supported_rsnprotos & IEEE80211_PROTO_RSN(1 << 0)) &&
1917 (ic->ic_caps & IEEE80211_C_RSN0x00001000)) {
1918 if (ieee80211_save_ie(rsnie, &ni->ni_rsnie) == 0
1919#ifndef IEEE80211_STA_ONLY
1920 && ic->ic_opmode != IEEE80211_M_HOSTAP
1921#endif
1922 ) {
1923 ni->ni_rsnprotos = IEEE80211_PROTO_RSN(1 << 0);
1924 ni->ni_rsnakms = rsn.rsn_akms;
1925 ni->ni_rsnciphers = rsn.rsn_ciphers;
1926 ni->ni_rsngroupcipher = rsn.rsn_groupcipher;
1927 ni->ni_rsngroupmgmtcipher =
1928 rsn.rsn_groupmgmtcipher;
1929 ni->ni_rsncaps = rsn.rsn_caps;
1930 }
1931 } else if (wpaie != NULL((void *)0) &&
1932 (ni->ni_supported_rsnprotos & IEEE80211_PROTO_WPA(1 << 1)) &&
1933 (ic->ic_caps & IEEE80211_C_RSN0x00001000)) {
1934 if (ieee80211_save_ie(wpaie, &ni->ni_rsnie) == 0
1935#ifndef IEEE80211_STA_ONLY
1936 && ic->ic_opmode != IEEE80211_M_HOSTAP
1937#endif
1938 ) {
1939 ni->ni_rsnprotos = IEEE80211_PROTO_WPA(1 << 1);
1940 ni->ni_rsnakms = wpa.rsn_akms;
1941 ni->ni_rsnciphers = wpa.rsn_ciphers;
1942 ni->ni_rsngroupcipher = wpa.rsn_groupcipher;
1943 ni->ni_rsngroupmgmtcipher =
1944 wpa.rsn_groupmgmtcipher;
1945 ni->ni_rsncaps = wpa.rsn_caps;
1946 }
1947 }
1948 }
1949
1950 /*
1951 * Set our SSID if we do not know it yet.
1952 * If we are doing a directed scan for an AP with a hidden SSID
1953 * we must collect the SSID from a probe response to override
1954 * a non-zero-length SSID filled with zeroes that we may have
1955 * received earlier in a beacon.
1956 */
1957 if (ssid[1] != 0 && ni->ni_essid[0] == '\0') {
1958 ni->ni_esslen = ssid[1];
1959 memset(ni->ni_essid, 0, sizeof(ni->ni_essid))__builtin_memset((ni->ni_essid), (0), (sizeof(ni->ni_essid
)))
;
1960 /* we know that ssid[1] <= IEEE80211_NWID_LEN */
1961 memcpy(ni->ni_essid, &ssid[2], ssid[1])__builtin_memcpy((ni->ni_essid), (&ssid[2]), (ssid[1])
)
;
1962 }
1963 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3)__builtin_memcpy((ni->ni_bssid), (wh->i_addr3), (6));
1964 /* XXX validate channel # */
1965 ni->ni_chan = &ic->ic_channels[chan];
1966 if (ic->ic_state == IEEE80211_S_SCAN &&
1967 IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)(((ni->ni_chan)->ic_flags & 0x0100) != 0)) {
1968 /*
1969 * During a scan on 5Ghz, prefer RSSI measured for probe
1970 * response frames. i.e. don't allow beacons to lower the
1971 * measured RSSI. Some 5GHz APs send beacons with much
1972 * less Tx power than they use for probe responses.
1973 */
1974 if (isprobe || ni->ni_rssi == 0)
1975 ni->ni_rssi = rxi->rxi_rssi;
1976 else if (ni->ni_rssi < rxi->rxi_rssi)
1977 ni->ni_rssi = rxi->rxi_rssi;
1978 } else
1979 ni->ni_rssi = rxi->rxi_rssi;
1980 ni->ni_rstamp = rxi->rxi_tstamp;
1981 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp))__builtin_memcpy((ni->ni_tstamp), (tstamp), (sizeof(ni->
ni_tstamp)))
;
1982 ni->ni_intval = bintval;
1983 ni->ni_capinfo = capinfo;
1984 ni->ni_erp = erp;
1985 /* NB: must be after ni_chan is setup */
1986 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT0x00000001);
1987#ifndef IEEE80211_STA_ONLY
1988 if (ic->ic_opmode == IEEE80211_M_IBSS && is_new && isprobe) {
1989 /*
1990 * Fake an association so the driver can setup it's
1991 * private state. The rate set has been setup above;
1992 * there is no handshake as in ap/station operation.
1993 */
1994 if (ic->ic_newassoc)
1995 (*ic->ic_newassoc)(ic, ni, 1);
1996 }
1997#endif
1998}
1999
2000#ifndef IEEE80211_STA_ONLY
2001/*-
2002 * Probe request frame format:
2003 * [tlv] SSID
2004 * [tlv] Supported rates
2005 * [tlv] Extended Supported Rates (802.11g)
2006 * [tlv] HT Capabilities (802.11n)
2007 */
2008void
2009ieee80211_recv_probe_req(struct ieee80211com *ic, struct mbuf *m,
2010 struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi)
2011{
2012 const struct ieee80211_frame *wh;
2013 const u_int8_t *frm, *efrm;
2014 const u_int8_t *ssid, *rates, *xrates, *htcaps;
2015 u_int8_t rate;
2016
2017 if (ic->ic_opmode == IEEE80211_M_STA ||
2018 ic->ic_state != IEEE80211_S_RUN)
2019 return;
2020
2021 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2022 frm = (const u_int8_t *)&wh[1];
2023 efrm = mtod(m, u_int8_t *)((u_int8_t *)((m)->m_hdr.mh_data)) + m->m_lenm_hdr.mh_len;
2024
2025 ssid = rates = xrates = htcaps = NULL((void *)0);
2026 while (frm + 2 <= efrm) {
2027 if (frm + 2 + frm[1] > efrm) {
2028 ic->ic_stats.is_rx_elem_toosmall++;
2029 break;
2030 }
2031 switch (frm[0]) {
2032 case IEEE80211_ELEMID_SSID:
2033 ssid = frm;
2034 break;
2035 case IEEE80211_ELEMID_RATES:
2036 rates = frm;
2037 break;
2038 case IEEE80211_ELEMID_XRATES:
2039 xrates = frm;
2040 break;
2041 case IEEE80211_ELEMID_HTCAPS:
2042 htcaps = frm;
2043 break;
2044 }
2045 frm += 2 + frm[1];
2046 }
2047 /* supported rates element is mandatory */
2048 if (rates == NULL((void *)0) || rates[1] > IEEE80211_RATE_MAXSIZE15) {
2049 DPRINTF(("invalid supported rates element\n"));
2050 return;
2051 }
2052 /* SSID element is mandatory */
2053 if (ssid == NULL((void *)0) || ssid[1] > IEEE80211_NWID_LEN32) {
2054 DPRINTF(("invalid SSID element\n"));
2055 return;
2056 }
2057 /* check that the specified SSID (if not wildcard) matches ours */
2058 if (ssid[1] != 0 && (ssid[1] != ic->ic_bss->ni_esslen ||
2059 memcmp(&ssid[2], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen)__builtin_memcmp((&ssid[2]), (ic->ic_bss->ni_essid)
, (ic->ic_bss->ni_esslen))
)) {
2060 DPRINTF(("SSID mismatch\n"));
2061 ic->ic_stats.is_rx_ssidmismatch++;
2062 return;
2063 }
2064 /* refuse wildcard SSID if we're hiding our SSID in beacons */
2065 if (ssid[1] == 0 && (ic->ic_userflags & IEEE80211_F_HIDENWID0x00000001)) {
2066 DPRINTF(("wildcard SSID rejected"));
2067 ic->ic_stats.is_rx_ssidmismatch++;
2068 return;
2069 }
2070
2071 if (ni == ic->ic_bss) {
2072 ni = ieee80211_find_node(ic, wh->i_addr2);
2073 if (ni == NULL((void *)0))
2074 ni = ieee80211_dup_bss(ic, wh->i_addr2);
2075 if (ni == NULL((void *)0))
2076 return;
2077 DPRINTF(("new probe req from %s\n",
2078 ether_sprintf((u_int8_t *)wh->i_addr2)));
2079 }
2080 ni->ni_rssi = rxi->rxi_rssi;
2081 ni->ni_rstamp = rxi->rxi_tstamp;
2082 rate = ieee80211_setup_rates(ic, ni, rates, xrates,
2083 IEEE80211_F_DOSORT0x00000001 | IEEE80211_F_DOFRATE0x00000002 | IEEE80211_F_DONEGO0x00000004 |
2084 IEEE80211_F_DODEL0x00000008);
2085 if (rate & IEEE80211_RATE_BASIC0x80) {
2086 DPRINTF(("rate mismatch for %s\n",
2087 ether_sprintf((u_int8_t *)wh->i_addr2)));
2088 return;
2089 }
2090 if (htcaps)
2091 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
2092 else
2093 ieee80211_clear_htcaps(ni);
2094 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0)((*(ic)->ic_send_mgmt)(ic, ni, 0x50, 0, 0));
2095}
2096#endif /* IEEE80211_STA_ONLY */
2097
2098/*-
2099 * Authentication frame format:
2100 * [2] Authentication algorithm number
2101 * [2] Authentication transaction sequence number
2102 * [2] Status code
2103 */
2104void
2105ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m,
2106 struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi)
2107{
2108 const struct ieee80211_frame *wh;
2109 const u_int8_t *frm;
2110 u_int16_t algo, seq, status;
2111
2112 /* make sure all mandatory fixed fields are present */
2113 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 6) {
2114 DPRINTF(("frame too short\n"));
2115 return;
2116 }
2117 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2118 frm = (const u_int8_t *)&wh[1];
2119
2120 algo = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2121 seq = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2122 status = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2123 DPRINTF(("auth %d seq %d from %s\n", algo, seq,
2124 ether_sprintf((u_int8_t *)wh->i_addr2)));
2125
2126 /* only "open" auth mode is supported */
2127 if (algo != IEEE80211_AUTH_ALG_OPEN0x0000) {
2128 DPRINTF(("unsupported auth algorithm %d from %s\n",
2129 algo, ether_sprintf((u_int8_t *)wh->i_addr2)));
2130 ic->ic_stats.is_rx_auth_unsupported++;
2131#ifndef IEEE80211_STA_ONLY
2132 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2133 /* XXX hack to workaround calling convention */
2134 IEEE80211_SEND_MGMT(ic, ni,((*(ic)->ic_send_mgmt)(ic, ni, 0xb0, IEEE80211_STATUS_ALG <<
16 | ((seq + 1) & 0xfff), 0))
2135 IEEE80211_FC0_SUBTYPE_AUTH,((*(ic)->ic_send_mgmt)(ic, ni, 0xb0, IEEE80211_STATUS_ALG <<
16 | ((seq + 1) & 0xfff), 0))
2136 IEEE80211_STATUS_ALG << 16 | ((seq + 1) & 0xfff))((*(ic)->ic_send_mgmt)(ic, ni, 0xb0, IEEE80211_STATUS_ALG <<
16 | ((seq + 1) & 0xfff), 0))
;
2137 }
2138#endif
2139 return;
2140 }
2141 ieee80211_auth_open(ic, wh, ni, rxi, seq, status);
2142}
2143
2144#ifndef IEEE80211_STA_ONLY
2145/*-
2146 * (Re)Association request frame format:
2147 * [2] Capability information
2148 * [2] Listen interval
2149 * [6*] Current AP address (Reassociation only)
2150 * [tlv] SSID
2151 * [tlv] Supported rates
2152 * [tlv] Extended Supported Rates (802.11g)
2153 * [tlv] RSN (802.11i)
2154 * [tlv] QoS Capability (802.11e)
2155 * [tlv] HT Capabilities (802.11n)
2156 */
2157void
2158ieee80211_recv_assoc_req(struct ieee80211com *ic, struct mbuf *m,
2159 struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int reassoc)
2160{
2161 const struct ieee80211_frame *wh;
2162 const u_int8_t *frm, *efrm;
2163 const u_int8_t *ssid, *rates, *xrates, *rsnie, *wpaie, *wmeie, *htcaps;
2164 u_int16_t capinfo, bintval;
2165 int resp, status = 0;
2166 struct ieee80211_rsnparams rsn;
2167 u_int8_t rate;
2168 const u_int8_t *saveie = NULL((void *)0);
2169
2170 if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
2171 ic->ic_state != IEEE80211_S_RUN)
2172 return;
2173
2174 /* make sure all mandatory fixed fields are present */
2175 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + (reassoc ? 10 : 4)) {
2176 DPRINTF(("frame too short\n"));
2177 return;
2178 }
2179 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2180 frm = (const u_int8_t *)&wh[1];
2181 efrm = mtod(m, u_int8_t *)((u_int8_t *)((m)->m_hdr.mh_data)) + m->m_lenm_hdr.mh_len;
2182
2183 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)(__builtin_memcmp((wh->i_addr3), (ic->ic_bss->ni_bssid
), (6)) == 0)
) {
2184 DPRINTF(("ignore other bss from %s\n",
2185 ether_sprintf((u_int8_t *)wh->i_addr2)));
2186 ic->ic_stats.is_rx_assoc_bss++;
2187 return;
2188 }
2189 capinfo = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2190 bintval = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2191 if (reassoc) {
2192 frm += IEEE80211_ADDR_LEN6; /* skip current AP address */
2193 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP0x30;
2194 } else
2195 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP0x10;
2196
2197 ssid = rates = xrates = rsnie = wpaie = wmeie = htcaps = NULL((void *)0);
2198 while (frm + 2 <= efrm) {
2199 if (frm + 2 + frm[1] > efrm) {
2200 ic->ic_stats.is_rx_elem_toosmall++;
2201 break;
2202 }
2203 switch (frm[0]) {
2204 case IEEE80211_ELEMID_SSID:
2205 ssid = frm;
2206 break;
2207 case IEEE80211_ELEMID_RATES:
2208 rates = frm;
2209 break;
2210 case IEEE80211_ELEMID_XRATES:
2211 xrates = frm;
2212 break;
2213 case IEEE80211_ELEMID_RSN:
2214 rsnie = frm;
2215 break;
2216 case IEEE80211_ELEMID_QOS_CAP:
2217 break;
2218 case IEEE80211_ELEMID_HTCAPS:
2219 htcaps = frm;
2220 break;
2221 case IEEE80211_ELEMID_VENDOR:
2222 if (frm[1] < 4) {
2223 ic->ic_stats.is_rx_elem_toosmall++;
2224 break;
2225 }
2226 if (memcmp(frm + 2, MICROSOFT_OUI, 3)__builtin_memcmp((frm + 2), (((const u_int8_t[]){ 0x00, 0x50,
0xf2 })), (3))
== 0) {
2227 if (frm[5] == 1)
2228 wpaie = frm;
2229 /* WME info IE: len=7 type=2 subtype=0 */
2230 if (frm[1] == 7 && frm[5] == 2 && frm[6] == 0)
2231 wmeie = frm;
2232 }
2233 break;
2234 }
2235 frm += 2 + frm[1];
2236 }
2237 /* supported rates element is mandatory */
2238 if (rates == NULL((void *)0) || rates[1] > IEEE80211_RATE_MAXSIZE15) {
2239 DPRINTF(("invalid supported rates element\n"));
2240 return;
2241 }
2242 /* SSID element is mandatory */
2243 if (ssid == NULL((void *)0) || ssid[1] > IEEE80211_NWID_LEN32) {
2244 DPRINTF(("invalid SSID element\n"));
2245 return;
2246 }
2247 /* check that the specified SSID matches ours */
2248 if (ssid[1] != ic->ic_bss->ni_esslen ||
2249 memcmp(&ssid[2], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen)__builtin_memcmp((&ssid[2]), (ic->ic_bss->ni_essid)
, (ic->ic_bss->ni_esslen))
) {
2250 DPRINTF(("SSID mismatch\n"));
2251 ic->ic_stats.is_rx_ssidmismatch++;
2252 return;
2253 }
2254
2255 if (ni->ni_state != IEEE80211_STA_AUTH &&
2256 ni->ni_state != IEEE80211_STA_ASSOC) {
2257 DPRINTF(("deny %sassoc from %s, not authenticated\n",
2258 reassoc ? "re" : "",
2259 ether_sprintf((u_int8_t *)wh->i_addr2)));
2260 ni = ieee80211_find_node(ic, wh->i_addr2);
2261 if (ni == NULL((void *)0))
2262 ni = ieee80211_dup_bss(ic, wh->i_addr2);
2263 if (ni != NULL((void *)0)) {
2264 IEEE80211_SEND_MGMT(ic, ni,((*(ic)->ic_send_mgmt)(ic, ni, 0xc0, IEEE80211_REASON_ASSOC_NOT_AUTHED
, 0))
2265 IEEE80211_FC0_SUBTYPE_DEAUTH,((*(ic)->ic_send_mgmt)(ic, ni, 0xc0, IEEE80211_REASON_ASSOC_NOT_AUTHED
, 0))
2266 IEEE80211_REASON_ASSOC_NOT_AUTHED)((*(ic)->ic_send_mgmt)(ic, ni, 0xc0, IEEE80211_REASON_ASSOC_NOT_AUTHED
, 0))
;
2267 }
2268 ic->ic_stats.is_rx_assoc_notauth++;
2269 return;
2270 }
2271
2272 if (ni->ni_state == IEEE80211_STA_ASSOC &&
2273 (ni->ni_flags & IEEE80211_NODE_MFP0x0080)) {
2274 if (ni->ni_flags & IEEE80211_NODE_SA_QUERY_FAILED0x1000) {
2275 /* send a protected Disassociate frame */
2276 IEEE80211_SEND_MGMT(ic, ni,((*(ic)->ic_send_mgmt)(ic, ni, 0xa0, IEEE80211_REASON_AUTH_EXPIRE
, 0))
2277 IEEE80211_FC0_SUBTYPE_DISASSOC,((*(ic)->ic_send_mgmt)(ic, ni, 0xa0, IEEE80211_REASON_AUTH_EXPIRE
, 0))
2278 IEEE80211_REASON_AUTH_EXPIRE)((*(ic)->ic_send_mgmt)(ic, ni, 0xa0, IEEE80211_REASON_AUTH_EXPIRE
, 0))
;
2279 /* terminate the old SA */
2280 ieee80211_node_leave(ic, ni);
2281 } else {
2282 /* reject the (Re)Association Request temporarily */
2283 IEEE80211_SEND_MGMT(ic, ni, resp,((*(ic)->ic_send_mgmt)(ic, ni, resp, IEEE80211_STATUS_TRY_AGAIN_LATER
, 0))
2284 IEEE80211_STATUS_TRY_AGAIN_LATER)((*(ic)->ic_send_mgmt)(ic, ni, resp, IEEE80211_STATUS_TRY_AGAIN_LATER
, 0))
;
2285 /* start SA Query procedure if not already engaged */
2286 if (!(ni->ni_flags & IEEE80211_NODE_SA_QUERY0x0800))
2287 ieee80211_sa_query_request(ic, ni);
2288 /* do not modify association state */
2289 }
2290 return;
2291 }
2292
2293 if (!(capinfo & IEEE80211_CAPINFO_ESS0x0001)) {
2294 ic->ic_stats.is_rx_assoc_capmismatch++;
2295 status = IEEE80211_STATUS_CAPINFO;
2296 goto end;
2297 }
2298 rate = ieee80211_setup_rates(ic, ni, rates, xrates,
2299 IEEE80211_F_DOSORT0x00000001 | IEEE80211_F_DOFRATE0x00000002 | IEEE80211_F_DONEGO0x00000004 |
2300 IEEE80211_F_DODEL0x00000008);
2301 if (rate & IEEE80211_RATE_BASIC0x80) {
2302 ic->ic_stats.is_rx_assoc_norate++;
2303 status = IEEE80211_STATUS_BASIC_RATE;
2304 goto end;
2305 }
2306
2307 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2308 ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE0;
2309 ni->ni_rsnakms = 0;
2310 ni->ni_supported_rsnakms = 0;
2311 ni->ni_rsnciphers = 0;
2312 ni->ni_rsngroupcipher = 0;
2313 ni->ni_rsngroupmgmtcipher = 0;
2314 ni->ni_rsncaps = 0;
2315
2316 /*
2317 * A station should never include both a WPA and an RSN IE
2318 * in its (Re)Association Requests, but if it does, we only
2319 * consider the IE of the highest version of the protocol
2320 * that is allowed (ie RSN over WPA).
2321 */
2322 if (rsnie != NULL((void *)0)) {
2323 status = ieee80211_parse_rsn(ic, rsnie, &rsn);
2324 if (status != 0)
2325 goto end;
2326 ni->ni_supported_rsnprotos = IEEE80211_PROTO_RSN(1 << 0);
2327 ni->ni_supported_rsnakms = rsn.rsn_akms;
2328 if ((ic->ic_flags & IEEE80211_F_RSNON0x00200000) &&
2329 (ic->ic_rsnprotos & IEEE80211_PROTO_RSN(1 << 0))) {
2330 ni->ni_rsnprotos = IEEE80211_PROTO_RSN(1 << 0);
2331 saveie = rsnie;
2332 }
2333 } else if (wpaie != NULL((void *)0)) {
2334 status = ieee80211_parse_wpa(ic, wpaie, &rsn);
2335 if (status != 0)
2336 goto end;
2337 ni->ni_supported_rsnprotos = IEEE80211_PROTO_WPA(1 << 1);
2338 ni->ni_supported_rsnakms = rsn.rsn_akms;
2339 if ((ic->ic_flags & IEEE80211_F_RSNON0x00200000) &&
2340 (ic->ic_rsnprotos & IEEE80211_PROTO_WPA(1 << 1))) {
2341 ni->ni_rsnprotos = IEEE80211_PROTO_WPA(1 << 1);
2342 saveie = wpaie;
2343 }
2344 }
2345
2346 if (ic->ic_flags & IEEE80211_F_QOS0x00080000) {
2347 if (wmeie != NULL((void *)0))
2348 ni->ni_flags |= IEEE80211_NODE_QOS0x0002;
2349 else /* for Reassociation */
2350 ni->ni_flags &= ~IEEE80211_NODE_QOS0x0002;
2351 }
2352
2353 if (ic->ic_flags & IEEE80211_F_RSNON0x00200000) {
2354 if (ni->ni_rsnprotos == IEEE80211_PROTO_NONE0) {
2355 /*
2356 * In an RSN, an AP shall not associate with STAs
2357 * that fail to include the RSN IE in the
2358 * (Re)Association Request.
2359 */
2360 status = IEEE80211_STATUS_IE_INVALID;
2361 goto end;
2362 }
2363 /*
2364 * The initiating STA's RSN IE shall include one authentication
2365 * and pairwise cipher suite among those advertised by the
2366 * targeted AP. It shall also specify the group cipher suite
2367 * specified by the targeted AP.
2368 */
2369 if (rsn.rsn_nakms != 1 ||
2370 !(rsn.rsn_akms & ic->ic_bss->ni_rsnakms)) {
2371 status = IEEE80211_STATUS_BAD_AKMP;
2372 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2373 goto end;
2374 }
2375 if (rsn.rsn_nciphers != 1 ||
2376 !(rsn.rsn_ciphers & ic->ic_bss->ni_rsnciphers)) {
2377 status = IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
2378 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2379 goto end;
2380 }
2381 if (rsn.rsn_groupcipher != ic->ic_bss->ni_rsngroupcipher) {
2382 status = IEEE80211_STATUS_BAD_GROUP_CIPHER;
2383 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2384 goto end;
2385 }
2386
2387 if ((ic->ic_bss->ni_rsncaps & IEEE80211_RSNCAP_MFPR0x0040) &&
2388 !(rsn.rsn_caps & IEEE80211_RSNCAP_MFPC0x0080)) {
2389 status = IEEE80211_STATUS_MFP_POLICY;
2390 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2391 goto end;
2392 }
2393 if ((ic->ic_bss->ni_rsncaps & IEEE80211_RSNCAP_MFPC0x0080) &&
2394 (rsn.rsn_caps & (IEEE80211_RSNCAP_MFPC0x0080 |
2395 IEEE80211_RSNCAP_MFPR0x0040)) == IEEE80211_RSNCAP_MFPR0x0040) {
2396 /* STA advertises an invalid setting */
2397 status = IEEE80211_STATUS_MFP_POLICY;
2398 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2399 goto end;
2400 }
2401 /*
2402 * A STA that has associated with Management Frame Protection
2403 * enabled shall not use cipher suite pairwise selector WEP40,
2404 * WEP104, TKIP, or "Use Group cipher suite".
2405 */
2406 if ((rsn.rsn_caps & IEEE80211_RSNCAP_MFPC0x0080) &&
2407 (rsn.rsn_ciphers != IEEE80211_CIPHER_CCMP ||
2408 rsn.rsn_groupmgmtcipher !=
2409 ic->ic_bss->ni_rsngroupmgmtcipher)) {
2410 status = IEEE80211_STATUS_MFP_POLICY;
2411 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2412 goto end;
2413 }
2414
2415 /*
2416 * Disallow new associations using TKIP if countermeasures
2417 * are active.
2418 */
2419 if ((ic->ic_flags & IEEE80211_F_COUNTERM0x00800000) &&
2420 (rsn.rsn_ciphers == IEEE80211_CIPHER_TKIP ||
2421 rsn.rsn_groupcipher == IEEE80211_CIPHER_TKIP)) {
2422 status = IEEE80211_STATUS_CIPHER_REJ_POLICY;
2423 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2424 goto end;
2425 }
2426
2427 /* everything looks fine, save IE and parameters */
2428 if (saveie == NULL((void *)0) ||
2429 ieee80211_save_ie(saveie, &ni->ni_rsnie) != 0) {
2430 status = IEEE80211_STATUS_TOOMANY;
2431 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2432 goto end;
2433 }
2434 ni->ni_rsnakms = rsn.rsn_akms;
2435 ni->ni_rsnciphers = rsn.rsn_ciphers;
2436 ni->ni_rsngroupcipher = ic->ic_bss->ni_rsngroupcipher;
2437 ni->ni_rsngroupmgmtcipher = ic->ic_bss->ni_rsngroupmgmtcipher;
2438 ni->ni_rsncaps = rsn.rsn_caps;
2439
2440 if (ieee80211_is_8021x_akm(ni->ni_rsnakms)) {
2441 struct ieee80211_pmk *pmk = NULL((void *)0);
2442 const u_int8_t *pmkid = rsn.rsn_pmkids;
2443 /*
2444 * Check if we have a cached PMK entry matching one
2445 * of the PMKIDs specified in the RSN IE.
2446 */
2447 while (rsn.rsn_npmkids-- > 0) {
2448 pmk = ieee80211_pmksa_find(ic, ni, pmkid);
2449 if (pmk != NULL((void *)0))
2450 break;
2451 pmkid += IEEE80211_PMKID_LEN16;
2452 }
2453 if (pmk != NULL((void *)0)) {
2454 memcpy(ni->ni_pmk, pmk->pmk_key,__builtin_memcpy((ni->ni_pmk), (pmk->pmk_key), (32))
2455 IEEE80211_PMK_LEN)__builtin_memcpy((ni->ni_pmk), (pmk->pmk_key), (32));
2456 memcpy(ni->ni_pmkid, pmk->pmk_pmkid,__builtin_memcpy((ni->ni_pmkid), (pmk->pmk_pmkid), (16)
)
2457 IEEE80211_PMKID_LEN)__builtin_memcpy((ni->ni_pmkid), (pmk->pmk_pmkid), (16)
)
;
2458 ni->ni_flags |= IEEE80211_NODE_PMK0x0100;
2459 }
2460 }
2461 }
2462
2463 ni->ni_rssi = rxi->rxi_rssi;
2464 ni->ni_rstamp = rxi->rxi_tstamp;
2465 ni->ni_intval = bintval;
2466 ni->ni_capinfo = capinfo;
2467 ni->ni_chan = ic->ic_bss->ni_chan;
2468 if (htcaps)
2469 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
2470 else
2471 ieee80211_clear_htcaps(ni);
2472 end:
2473 if (status != 0) {
2474 IEEE80211_SEND_MGMT(ic, ni, resp, status)((*(ic)->ic_send_mgmt)(ic, ni, resp, status, 0));
2475 ieee80211_node_leave(ic, ni);
2476 } else
2477 ieee80211_node_join(ic, ni, resp);
2478}
2479#endif /* IEEE80211_STA_ONLY */
2480
2481/*-
2482 * (Re)Association response frame format:
2483 * [2] Capability information
2484 * [2] Status code
2485 * [2] Association ID (AID)
2486 * [tlv] Supported rates
2487 * [tlv] Extended Supported Rates (802.11g)
2488 * [tlv] EDCA Parameter Set (802.11e)
2489 * [tlv] HT Capabilities (802.11n)
2490 * [tlv] HT Operation (802.11n)
2491 */
2492void
2493ieee80211_recv_assoc_resp(struct ieee80211com *ic, struct mbuf *m,
2494 struct ieee80211_node *ni, int reassoc)
2495{
2496 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
2497 const struct ieee80211_frame *wh;
2498 const u_int8_t *frm, *efrm;
2499 const u_int8_t *rates, *xrates, *edcaie, *wmmie, *htcaps, *htop;
2500 u_int16_t capinfo, status, associd;
2501 u_int8_t rate;
2502
2503 if (ic->ic_opmode != IEEE80211_M_STA ||
2504 ic->ic_state != IEEE80211_S_ASSOC) {
2505 ic->ic_stats.is_rx_mgtdiscard++;
2506 return;
2507 }
2508
2509 /* make sure all mandatory fixed fields are present */
2510 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 6) {
2511 DPRINTF(("frame too short\n"));
2512 return;
2513 }
2514 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2515 frm = (const u_int8_t *)&wh[1];
2516 efrm = mtod(m, u_int8_t *)((u_int8_t *)((m)->m_hdr.mh_data)) + m->m_lenm_hdr.mh_len;
2517
2518 capinfo = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2519 status = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2520 if (status != IEEE80211_STATUS_SUCCESS) {
2521 if (ifp->if_flags & IFF_DEBUG0x4)
2522 printf("%s: %sassociation failed (status %d)"
2523 " for %s\n", ifp->if_xname,
2524 reassoc ? "re" : "",
2525 status, ether_sprintf((u_int8_t *)wh->i_addr3));
2526 if (ni != ic->ic_bss)
2527 ni->ni_fails++;
2528 ic->ic_stats.is_rx_auth_fail++;
2529 return;
2530 }
2531 associd = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
; frm += 2;
2532
2533 rates = xrates = edcaie = wmmie = htcaps = htop = NULL((void *)0);
2534 while (frm + 2 <= efrm) {
2535 if (frm + 2 + frm[1] > efrm) {
2536 ic->ic_stats.is_rx_elem_toosmall++;
2537 break;
2538 }
2539 switch (frm[0]) {
2540 case IEEE80211_ELEMID_RATES:
2541 rates = frm;
2542 break;
2543 case IEEE80211_ELEMID_XRATES:
2544 xrates = frm;
2545 break;
2546 case IEEE80211_ELEMID_EDCAPARMS:
2547 edcaie = frm;
2548 break;
2549 case IEEE80211_ELEMID_HTCAPS:
2550 htcaps = frm;
2551 break;
2552 case IEEE80211_ELEMID_HTOP:
2553 htop = frm;
2554 break;
2555 case IEEE80211_ELEMID_VENDOR:
2556 if (frm[1] < 4) {
2557 ic->ic_stats.is_rx_elem_toosmall++;
2558 break;
2559 }
2560 if (memcmp(frm + 2, MICROSOFT_OUI, 3)__builtin_memcmp((frm + 2), (((const u_int8_t[]){ 0x00, 0x50,
0xf2 })), (3))
== 0) {
2561 if (frm[1] >= 5 && frm[5] == 2 && frm[6] == 1)
2562 wmmie = frm;
2563 }
2564 break;
2565 }
2566 frm += 2 + frm[1];
2567 }
2568 /* supported rates element is mandatory */
2569 if (rates == NULL((void *)0) || rates[1] > IEEE80211_RATE_MAXSIZE15) {
2570 DPRINTF(("invalid supported rates element\n"));
2571 return;
2572 }
2573 rate = ieee80211_setup_rates(ic, ni, rates, xrates,
2574 IEEE80211_F_DOSORT0x00000001 | IEEE80211_F_DOFRATE0x00000002 | IEEE80211_F_DONEGO0x00000004 |
2575 IEEE80211_F_DODEL0x00000008);
2576 if (rate & IEEE80211_RATE_BASIC0x80) {
2577 DPRINTF(("rate mismatch for %s\n",
2578 ether_sprintf((u_int8_t *)wh->i_addr2)));
2579 ic->ic_stats.is_rx_assoc_norate++;
2580 return;
2581 }
2582 ni->ni_capinfo = capinfo;
2583 ni->ni_associd = associd;
2584 if (edcaie != NULL((void *)0) || wmmie != NULL((void *)0)) {
2585 /* force update of EDCA parameters */
2586 ic->ic_edca_updtcount = -1;
2587
2588 if ((edcaie != NULL((void *)0) &&
2589 ieee80211_parse_edca_params(ic, edcaie) == 0) ||
2590 (wmmie != NULL((void *)0) &&
2591 ieee80211_parse_wmm_params(ic, wmmie) == 0))
2592 ni->ni_flags |= IEEE80211_NODE_QOS0x0002;
2593 else /* for Reassociation */
2594 ni->ni_flags &= ~IEEE80211_NODE_QOS0x0002;
2595 }
2596 if (htcaps)
2597 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
2598 if (htop)
2599 ieee80211_setup_htop(ni, htop + 2, htop[1], 0);
2600 ieee80211_ht_negotiate(ic, ni);
2601
2602 /* Hop into 11n mode after associating to an HT AP in a non-11n mode. */
2603 if (ni->ni_flags & IEEE80211_NODE_HT0x0400)
2604 ieee80211_setmode(ic, IEEE80211_MODE_11N);
2605 else
2606 ieee80211_setmode(ic, ieee80211_chan2mode(ic, ni->ni_chan));
2607 /*
2608 * Reset the erp state (mostly the slot time) now that
2609 * our operating mode has been nailed down.
2610 */
2611 ieee80211_reset_erp(ic);
2612
2613 /*
2614 * Configure state now that we are associated.
2615 */
2616 if (ic->ic_curmode == IEEE80211_MODE_11A ||
2617 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE0x0020))
2618 ic->ic_flags |= IEEE80211_F_SHPREAMBLE0x00040000;
2619 else
2620 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE0x00040000;
2621
2622 ieee80211_set_shortslottime(ic,
2623 ic->ic_curmode == IEEE80211_MODE_11A ||
2624 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME0x0400));
2625 /*
2626 * Honor ERP protection.
2627 */
2628 if ((ic->ic_curmode == IEEE80211_MODE_11G ||
2629 (ic->ic_curmode == IEEE80211_MODE_11N &&
2630 IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)(((ni->ni_chan)->ic_flags & 0x0080) != 0))) &&
2631 (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION0x02))
2632 ic->ic_flags |= IEEE80211_F_USEPROT0x00100000;
2633 else
2634 ic->ic_flags &= ~IEEE80211_F_USEPROT0x00100000;
2635 /*
2636 * If not an RSNA, mark the port as valid, otherwise wait for
2637 * 802.1X authentication and 4-way handshake to complete..
2638 */
2639 if (ic->ic_flags & IEEE80211_F_RSNON0x00200000) {
2640 /* XXX ic->ic_mgt_timer = 5; */
2641 ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART;
2642 } else if (ic->ic_flags & IEEE80211_F_WEPON0x00000100)
2643 ni->ni_flags |= IEEE80211_NODE_TXRXPROT(0x0010 | 0x0008);
2644
2645 ieee80211_new_state(ic, IEEE80211_S_RUN,(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (0x10)))
2646 IEEE80211_FC0_SUBTYPE_ASSOC_RESP)(((ic)->ic_newstate)((ic), (IEEE80211_S_RUN), (0x10)));
2647}
2648
2649/*-
2650 * Deauthentication frame format:
2651 * [2] Reason code
2652 */
2653void
2654ieee80211_recv_deauth(struct ieee80211com *ic, struct mbuf *m,
2655 struct ieee80211_node *ni)
2656{
2657 const struct ieee80211_frame *wh;
2658 const u_int8_t *frm;
2659 u_int16_t reason;
2660
2661 /* make sure all mandatory fixed fields are present */
2662 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 2) {
2663 DPRINTF(("frame too short\n"));
2664 return;
2665 }
2666 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2667 frm = (const u_int8_t *)&wh[1];
2668
2669 reason = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
;
2670
2671 ic->ic_stats.is_rx_deauth++;
2672 switch (ic->ic_opmode) {
2673 case IEEE80211_M_STA: {
2674 int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN0x08000000) &&
2675 ic->ic_state == IEEE80211_S_RUN);
2676 int stay_auth = ((ic->ic_userflags & IEEE80211_F_STAYAUTH0x00000004) &&
2677 ic->ic_state >= IEEE80211_S_AUTH);
2678 if (!(bgscan || stay_auth))
2679 ieee80211_new_state(ic, IEEE80211_S_AUTH,(((ic)->ic_newstate)((ic), (IEEE80211_S_AUTH), (0xc0)))
2680 IEEE80211_FC0_SUBTYPE_DEAUTH)(((ic)->ic_newstate)((ic), (IEEE80211_S_AUTH), (0xc0)));
2681 }
2682 break;
2683#ifndef IEEE80211_STA_ONLY
2684 case IEEE80211_M_HOSTAP:
2685 if (ni != ic->ic_bss) {
2686 int stay_auth =
2687 ((ic->ic_userflags & IEEE80211_F_STAYAUTH0x00000004) &&
2688 (ni->ni_state == IEEE80211_STA_AUTH ||
2689 ni->ni_state == IEEE80211_STA_ASSOC));
2690 if (ic->ic_ific_ac.ac_if.if_flags & IFF_DEBUG0x4)
2691 printf("%s: station %s deauthenticated "
2692 "by peer (reason %d)\n",
2693 ic->ic_ific_ac.ac_if.if_xname,
2694 ether_sprintf(ni->ni_macaddr),
2695 reason);
2696 if (!stay_auth)
2697 ieee80211_node_leave(ic, ni);
2698 }
2699 break;
2700#endif
2701 default:
2702 break;
2703 }
2704}
2705
2706/*-
2707 * Disassociation frame format:
2708 * [2] Reason code
2709 */
2710void
2711ieee80211_recv_disassoc(struct ieee80211com *ic, struct mbuf *m,
2712 struct ieee80211_node *ni)
2713{
2714 const struct ieee80211_frame *wh;
2715 const u_int8_t *frm;
2716 u_int16_t reason;
2717
2718 /* make sure all mandatory fixed fields are present */
2719 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 2) {
2720 DPRINTF(("frame too short\n"));
2721 return;
2722 }
2723 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2724 frm = (const u_int8_t *)&wh[1];
2725
2726 reason = LE_READ_2(frm)((u_int16_t) ((((const u_int8_t *)(frm))[0]) | (((const u_int8_t
*)(frm))[1] << 8)))
;
2727
2728 ic->ic_stats.is_rx_disassoc++;
2729 switch (ic->ic_opmode) {
2730 case IEEE80211_M_STA: {
2731 int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN0x08000000) &&
2732 ic->ic_state == IEEE80211_S_RUN);
2733 if (!bgscan) /* ignore disassoc during bgscan */
2734 ieee80211_new_state(ic, IEEE80211_S_ASSOC,(((ic)->ic_newstate)((ic), (IEEE80211_S_ASSOC), (0xa0)))
2735 IEEE80211_FC0_SUBTYPE_DISASSOC)(((ic)->ic_newstate)((ic), (IEEE80211_S_ASSOC), (0xa0)));
2736 }
2737 break;
2738#ifndef IEEE80211_STA_ONLY
2739 case IEEE80211_M_HOSTAP:
2740 if (ni != ic->ic_bss) {
2741 if (ic->ic_ific_ac.ac_if.if_flags & IFF_DEBUG0x4)
2742 printf("%s: station %s disassociated "
2743 "by peer (reason %d)\n",
2744 ic->ic_ific_ac.ac_if.if_xname,
2745 ether_sprintf(ni->ni_macaddr),
2746 reason);
2747 ieee80211_node_leave(ic, ni);
2748 }
2749 break;
2750#endif
2751 default:
2752 break;
2753 }
2754}
2755
2756/*-
2757 * ADDBA Request frame format:
2758 * [1] Category
2759 * [1] Action
2760 * [1] Dialog Token
2761 * [2] Block Ack Parameter Set
2762 * [2] Block Ack Timeout Value
2763 * [2] Block Ack Starting Sequence Control
2764 */
2765void
2766ieee80211_recv_addba_req(struct ieee80211com *ic, struct mbuf *m,
2767 struct ieee80211_node *ni)
2768{
2769 const struct ieee80211_frame *wh;
2770 const u_int8_t *frm;
2771 struct ieee80211_rx_ba *ba;
2772 u_int16_t params, ssn, bufsz, timeout;
2773 u_int8_t token, tid;
2774 int err = 0;
2775
2776 if (!(ni->ni_flags & IEEE80211_NODE_HT0x0400)) {
2777 DPRINTF(("received ADDBA req from non-HT STA %s\n",
2778 ether_sprintf(ni->ni_macaddr)));
2779 return;
2780 }
2781 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 9) {
2782 DPRINTF(("frame too short\n"));
2783 return;
2784 }
2785 /* MLME-ADDBA.indication */
2786 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2787 frm = (const u_int8_t *)&wh[1];
2788
2789 token = frm[2];
2790 params = LE_READ_2(&frm[3])((u_int16_t) ((((const u_int8_t *)(&frm[3]))[0]) | (((const
u_int8_t *)(&frm[3]))[1] << 8)))
;
2791 tid = ((params & IEEE80211_ADDBA_TID_MASK0x003c) >>
2792 IEEE80211_ADDBA_TID_SHIFT2);
2793 bufsz = (params & IEEE80211_ADDBA_BUFSZ_MASK0xffc0) >>
2794 IEEE80211_ADDBA_BUFSZ_SHIFT6;
2795 timeout = LE_READ_2(&frm[5])((u_int16_t) ((((const u_int8_t *)(&frm[5]))[0]) | (((const
u_int8_t *)(&frm[5]))[1] << 8)))
;
2796 ssn = LE_READ_2(&frm[7])((u_int16_t) ((((const u_int8_t *)(&frm[7]))[0]) | (((const
u_int8_t *)(&frm[7]))[1] << 8)))
>> 4;
2797
2798 ba = &ni->ni_rx_ba[tid];
2799 /* The driver is still processing an ADDBA request for this tid. */
2800 if (ba->ba_state == IEEE80211_BA_REQUESTED1)
2801 return;
2802 /* If we are in the process of roaming between APs, ignore. */
2803 if ((ic->ic_flags & IEEE80211_F_BGSCAN0x08000000) &&
2804 (ic->ic_xflags & IEEE80211_F_TX_MGMT_ONLY0x00000001))
2805 return;
2806 /* check if we already have a Block Ack agreement for this RA/TID */
2807 if (ba->ba_state == IEEE80211_BA_AGREED2) {
2808 /* XXX should we update the timeout value? */
2809 /* reset Block Ack inactivity timer */
2810 if (ba->ba_timeout_val != 0)
2811 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
2812
2813 /* check if it's a Protected Block Ack agreement */
2814 if (!(ni->ni_flags & IEEE80211_NODE_MFP0x0080) ||
2815 !(ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC0x1000))
2816 return; /* not a PBAC, ignore */
2817
2818 /* PBAC: treat the ADDBA Request like a BlockAckReq */
2819 if (SEQ_LT(ba->ba_winstart, ssn)((((u_int16_t)(ba->ba_winstart) - (u_int16_t)(ssn)) & 0xfff
) > 2048)
) {
2820 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
2821 ieee80211_ba_move_window(ic, ni, tid, ssn, &ml);
2822 if_input(&ic->ic_ific_ac.ac_if, &ml);
2823 }
2824 return;
2825 }
2826
2827 /* if PBAC required but RA does not support it, refuse request */
2828 if ((ic->ic_flags & IEEE80211_F_PBAR0x04000000) &&
2829 (!(ni->ni_flags & IEEE80211_NODE_MFP0x0080) ||
2830 !(ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC0x1000)))
2831 goto refuse;
2832 /*
2833 * If the TID for which the Block Ack agreement is requested is
2834 * configured with a no-ACK policy, refuse the agreement.
2835 */
2836 if (ic->ic_tid_noack & (1 << tid))
2837 goto refuse;
2838
2839 /* check that we support the requested Block Ack Policy */
2840 if (!(ic->ic_htcaps & IEEE80211_HTCAP_DELAYEDBA0x00000400) &&
2841 !(params & IEEE80211_ADDBA_BA_POLICY0x0002))
2842 goto refuse;
2843
2844 /* setup Block Ack agreement */
2845 ba->ba_state = IEEE80211_BA_REQUESTED1;
2846 ba->ba_timeout_val = timeout * IEEE80211_DUR_TU1024;
2847 ba->ba_ni = ni;
2848 ba->ba_token = token;
2849 timeout_set(&ba->ba_to, ieee80211_rx_ba_timeout, ba);
2850 timeout_set(&ba->ba_gap_to, ieee80211_input_ba_gap_timeout, ba);
2851 ba->ba_gapwait = 0;
2852 ba->ba_winsize = bufsz;
2853 if (ba->ba_winsize == 0 || ba->ba_winsize > IEEE80211_BA_MAX_WINSZ64)
2854 ba->ba_winsize = IEEE80211_BA_MAX_WINSZ64;
2855 ba->ba_params = (params & IEEE80211_ADDBA_BA_POLICY0x0002);
2856 ba->ba_params |= ((ba->ba_winsize << IEEE80211_ADDBA_BUFSZ_SHIFT6) |
2857 (tid << IEEE80211_ADDBA_TID_SHIFT2));
2858 ba->ba_params |= IEEE80211_ADDBA_AMSDU0x0001;
2859 ba->ba_winstart = ssn;
2860 ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
2861 /* allocate and setup our reordering buffer */
2862 ba->ba_buf = malloc(IEEE80211_BA_MAX_WINSZ64 * sizeof(*ba->ba_buf),
2863 M_DEVBUF2, M_NOWAIT0x0002 | M_ZERO0x0008);
2864 if (ba->ba_buf == NULL((void *)0))
2865 goto refuse;
2866
2867 ba->ba_head = 0;
2868
2869 /* notify drivers of this new Block Ack agreement */
2870 if (ic->ic_ampdu_rx_start != NULL((void *)0))
2871 err = ic->ic_ampdu_rx_start(ic, ni, tid);
2872 if (err == EBUSY16) {
2873 /* driver will accept or refuse agreement when done */
2874 return;
2875 } else if (err) {
2876 /* driver failed to setup, rollback */
2877 ieee80211_addba_req_refuse(ic, ni, tid);
2878 } else
2879 ieee80211_addba_req_accept(ic, ni, tid);
2880 return;
2881
2882 refuse:
2883 /* MLME-ADDBA.response */
2884 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_REFUSED << 16 | token <<
8 | tid))
2885 IEEE80211_ACTION_ADDBA_RESP,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_REFUSED << 16 | token <<
8 | tid))
2886 IEEE80211_STATUS_REFUSED << 16 | token << 8 | tid)((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_REFUSED << 16 | token <<
8 | tid))
;
2887}
2888
2889void
2890ieee80211_addba_req_accept(struct ieee80211com *ic, struct ieee80211_node *ni,
2891 uint8_t tid)
2892{
2893 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
2894
2895 ba->ba_state = IEEE80211_BA_AGREED2;
2896 ic->ic_stats.is_ht_rx_ba_agreements++;
2897 /* start Block Ack inactivity timer */
2898 if (ba->ba_timeout_val != 0)
2899 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
2900
2901 /* MLME-ADDBA.response */
2902 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_SUCCESS << 16 | ba->ba_token
<< 8 | tid))
2903 IEEE80211_ACTION_ADDBA_RESP,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_SUCCESS << 16 | ba->ba_token
<< 8 | tid))
2904 IEEE80211_STATUS_SUCCESS << 16 | ba->ba_token << 8 | tid)((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_SUCCESS << 16 | ba->ba_token
<< 8 | tid))
;
2905}
2906
2907void
2908ieee80211_addba_req_refuse(struct ieee80211com *ic, struct ieee80211_node *ni,
2909 uint8_t tid)
2910{
2911 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
2912
2913 free(ba->ba_buf, M_DEVBUF2,
2914 IEEE80211_BA_MAX_WINSZ64 * sizeof(*ba->ba_buf));
2915 ba->ba_buf = NULL((void *)0);
2916 ba->ba_state = IEEE80211_BA_INIT0;
2917
2918 /* MLME-ADDBA.response */
2919 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_REFUSED << 16 | ba->ba_token
<< 8 | tid))
2920 IEEE80211_ACTION_ADDBA_RESP,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_REFUSED << 16 | ba->ba_token
<< 8 | tid))
2921 IEEE80211_STATUS_REFUSED << 16 | ba->ba_token << 8 | tid)((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (1), IEEE80211_STATUS_REFUSED << 16 | ba->ba_token
<< 8 | tid))
;
2922}
2923
2924/*-
2925 * ADDBA Response frame format:
2926 * [1] Category
2927 * [1] Action
2928 * [1] Dialog Token
2929 * [2] Status Code
2930 * [2] Block Ack Parameter Set
2931 * [2] Block Ack Timeout Value
2932 */
2933void
2934ieee80211_recv_addba_resp(struct ieee80211com *ic, struct mbuf *m,
2935 struct ieee80211_node *ni)
2936{
2937 const struct ieee80211_frame *wh;
2938 const u_int8_t *frm;
2939 struct ieee80211_tx_ba *ba;
2940 u_int16_t status, params, bufsz, timeout;
2941 u_int8_t token, tid;
2942 int err = 0;
2943
2944 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 9) {
2945 DPRINTF(("frame too short\n"));
2946 return;
2947 }
2948 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
2949 frm = (const u_int8_t *)&wh[1];
2950
2951 token = frm[2];
2952 status = LE_READ_2(&frm[3])((u_int16_t) ((((const u_int8_t *)(&frm[3]))[0]) | (((const
u_int8_t *)(&frm[3]))[1] << 8)))
;
2953 params = LE_READ_2(&frm[5])((u_int16_t) ((((const u_int8_t *)(&frm[5]))[0]) | (((const
u_int8_t *)(&frm[5]))[1] << 8)))
;
2954 tid = (params >> 2) & 0xf;
2955 bufsz = (params >> 6) & 0x3ff;
2956 timeout = LE_READ_2(&frm[7])((u_int16_t) ((((const u_int8_t *)(&frm[7]))[0]) | (((const
u_int8_t *)(&frm[7]))[1] << 8)))
;
2957
2958 DPRINTF(("received ADDBA resp from %s, TID %d, status %d\n",
2959 ether_sprintf(ni->ni_macaddr), tid, status));
2960
2961 /*
2962 * Ignore if no ADDBA request has been sent for this RA/TID or
2963 * if we already have a Block Ack agreement.
2964 */
2965 ba = &ni->ni_tx_ba[tid];
2966 if (ba->ba_state != IEEE80211_BA_REQUESTED1) {
2967 DPRINTF(("no matching ADDBA req found\n"));
2968 return;
2969 }
2970 if (token != ba->ba_token) {
2971 DPRINTF(("ignoring ADDBA resp from %s: token %x!=%x\n",
2972 ether_sprintf(ni->ni_macaddr), token, ba->ba_token));
2973 return;
2974 }
2975 /* we got an ADDBA Response matching our request, stop timeout */
2976 timeout_del(&ba->ba_to);
2977
2978 if (status != IEEE80211_STATUS_SUCCESS) {
2979 if (ni->ni_addba_req_intval[tid] <
2980 IEEE80211_ADDBA_REQ_INTVAL_MAX30)
2981 ni->ni_addba_req_intval[tid]++;
2982
2983 ieee80211_addba_resp_refuse(ic, ni, tid, status);
2984
2985 /*
2986 * In case the peer believes there is an existing
2987 * block ack agreement with us, try to delete it.
2988 */
2989 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | 1 <<
8 | tid))
2990 IEEE80211_ACTION_DELBA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | 1 <<
8 | tid))
2991 IEEE80211_REASON_SETUP_REQUIRED << 16 | 1 << 8 | tid)((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | 1 <<
8 | tid))
;
2992 return;
2993 }
2994
2995 /* notify drivers of this new Block Ack agreement */
2996 if (ic->ic_ampdu_tx_start != NULL((void *)0))
2997 err = ic->ic_ampdu_tx_start(ic, ni, tid);
2998
2999 if (err == EBUSY16) {
3000 /* driver will accept or refuse agreement when done */
3001 return;
3002 } else if (err) {
3003 /* driver failed to setup, rollback */
3004 ieee80211_addba_resp_refuse(ic, ni, tid,
3005 IEEE80211_STATUS_UNSPECIFIED);
3006 } else
3007 ieee80211_addba_resp_accept(ic, ni, tid);
3008}
3009
3010void
3011ieee80211_addba_resp_accept(struct ieee80211com *ic,
3012 struct ieee80211_node *ni, uint8_t tid)
3013{
3014 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
3015
3016 /* MLME-ADDBA.confirm(Success) */
3017 ba->ba_state = IEEE80211_BA_AGREED2;
3018 ic->ic_stats.is_ht_tx_ba_agreements++;
3019
3020 /* Reset ADDBA request interval. */
3021 ni->ni_addba_req_intval[tid] = 1;
3022
3023 ni->ni_qos_txseqs[tid] = ba->ba_winstart;
3024
3025 /* start Block Ack inactivity timeout */
3026 if (ba->ba_timeout_val != 0)
3027 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
3028}
3029
3030void
3031ieee80211_addba_resp_refuse(struct ieee80211com *ic,
3032 struct ieee80211_node *ni, uint8_t tid, uint16_t status)
3033{
3034 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
3035
3036 /* MLME-ADDBA.confirm(Failure) */
3037 ba->ba_state = IEEE80211_BA_INIT0;
3038}
3039
3040/*-
3041 * DELBA frame format:
3042 * [1] Category
3043 * [1] Action
3044 * [2] DELBA Parameter Set
3045 * [2] Reason Code
3046 */
3047void
3048ieee80211_recv_delba(struct ieee80211com *ic, struct mbuf *m,
3049 struct ieee80211_node *ni)
3050{
3051 const struct ieee80211_frame *wh;
3052 const u_int8_t *frm;
3053 u_int16_t params, reason;
3054 u_int8_t tid;
3055 int i;
3056
3057 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 6) {
3058 DPRINTF(("frame too short\n"));
3059 return;
3060 }
3061 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
3062 frm = (const u_int8_t *)&wh[1];
3063
3064 params = LE_READ_2(&frm[2])((u_int16_t) ((((const u_int8_t *)(&frm[2]))[0]) | (((const
u_int8_t *)(&frm[2]))[1] << 8)))
;
3065 reason = LE_READ_2(&frm[4])((u_int16_t) ((((const u_int8_t *)(&frm[4]))[0]) | (((const
u_int8_t *)(&frm[4]))[1] << 8)))
;
Value stored to 'reason' is never read
3066 tid = params >> 12;
3067
3068 DPRINTF(("received DELBA from %s, TID %d, reason %d\n",
3069 ether_sprintf(ni->ni_macaddr), tid, reason));
3070
3071 if (params & IEEE80211_DELBA_INITIATOR0x0800) {
3072 /* MLME-DELBA.indication(Originator) */
3073 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
3074
3075 if (ba->ba_state != IEEE80211_BA_AGREED2) {
3076 DPRINTF(("no matching Block Ack agreement\n"));
3077 return;
3078 }
3079 /* notify drivers of the end of the Block Ack agreement */
3080 if (ic->ic_ampdu_rx_stop != NULL((void *)0))
3081 ic->ic_ampdu_rx_stop(ic, ni, tid);
3082
3083 ba->ba_state = IEEE80211_BA_INIT0;
3084 /* stop Block Ack inactivity timer */
3085 timeout_del(&ba->ba_to);
3086 timeout_del(&ba->ba_gap_to);
3087 ba->ba_gapwait = 0;
3088
3089 if (ba->ba_buf != NULL((void *)0)) {
3090 /* free all MSDUs stored in reordering buffer */
3091 for (i = 0; i < IEEE80211_BA_MAX_WINSZ64; i++)
3092 m_freem(ba->ba_buf[i].m);
3093 /* free reordering buffer */
3094 free(ba->ba_buf, M_DEVBUF2,
3095 IEEE80211_BA_MAX_WINSZ64 * sizeof(*ba->ba_buf));
3096 ba->ba_buf = NULL((void *)0);
3097 }
3098 } else {
3099 /* MLME-DELBA.indication(Recipient) */
3100 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
3101
3102 if (ba->ba_state != IEEE80211_BA_AGREED2) {
3103 DPRINTF(("no matching Block Ack agreement\n"));
3104 return;
3105 }
3106 /* notify drivers of the end of the Block Ack agreement */
3107 if (ic->ic_ampdu_tx_stop != NULL((void *)0))
3108 ic->ic_ampdu_tx_stop(ic, ni, tid);
3109
3110 ba->ba_state = IEEE80211_BA_INIT0;
3111 /* stop Block Ack inactivity timer */
3112 timeout_del(&ba->ba_to);
3113 }
3114}
3115
3116/*-
3117 * SA Query Request frame format:
3118 * [1] Category
3119 * [1] Action
3120 * [2] Transaction Identifier
3121 */
3122void
3123ieee80211_recv_sa_query_req(struct ieee80211com *ic, struct mbuf *m,
3124 struct ieee80211_node *ni)
3125{
3126 const struct ieee80211_frame *wh;
3127 const u_int8_t *frm;
3128
3129 if (ic->ic_opmode != IEEE80211_M_STA ||
3130 !(ni->ni_flags & IEEE80211_NODE_MFP0x0080)) {
3131 DPRINTF(("unexpected SA Query req from %s\n",
3132 ether_sprintf(ni->ni_macaddr)));
3133 return;
3134 }
3135 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 4) {
3136 DPRINTF(("frame too short\n"));
3137 return;
3138 }
3139 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
3140 frm = (const u_int8_t *)&wh[1];
3141
3142 /* MLME-SAQuery.indication */
3143
3144 /* save Transaction Identifier for SA Query Response */
3145 ni->ni_sa_query_trid = LE_READ_2(&frm[2])((u_int16_t) ((((const u_int8_t *)(&frm[2]))[0]) | (((const
u_int8_t *)(&frm[2]))[1] << 8)))
;
3146
3147 /* MLME-SAQuery.response */
3148 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_SA_QUERY,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_SA_QUERY
) << 16 | (1), 0))
3149 IEEE80211_ACTION_SA_QUERY_RESP, 0)((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_SA_QUERY
) << 16 | (1), 0))
;
3150}
3151
3152#ifndef IEEE80211_STA_ONLY
3153/*-
3154 * SA Query Response frame format:
3155 * [1] Category
3156 * [1] Action
3157 * [2] Transaction Identifier
3158 */
3159void
3160ieee80211_recv_sa_query_resp(struct ieee80211com *ic, struct mbuf *m,
3161 struct ieee80211_node *ni)
3162{
3163 const struct ieee80211_frame *wh;
3164 const u_int8_t *frm;
3165
3166 /* ignore if we're not engaged in an SA Query with that STA */
3167 if (!(ni->ni_flags & IEEE80211_NODE_SA_QUERY0x0800)) {
3168 DPRINTF(("unexpected SA Query resp from %s\n",
3169 ether_sprintf(ni->ni_macaddr)));
3170 return;
3171 }
3172 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 4) {
3173 DPRINTF(("frame too short\n"));
3174 return;
3175 }
3176 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
3177 frm = (const u_int8_t *)&wh[1];
3178
3179 /* check that Transaction Identifier matches */
3180 if (ni->ni_sa_query_trid != LE_READ_2(&frm[2])((u_int16_t) ((((const u_int8_t *)(&frm[2]))[0]) | (((const
u_int8_t *)(&frm[2]))[1] << 8)))
) {
3181 DPRINTF(("transaction identifier does not match\n"));
3182 return;
3183 }
3184 /* MLME-SAQuery.confirm */
3185 timeout_del(&ni->ni_sa_query_to);
3186 ni->ni_flags &= ~IEEE80211_NODE_SA_QUERY0x0800;
3187}
3188#endif
3189
3190/*-
3191 * Action frame format:
3192 * [1] Category
3193 * [1] Action
3194 */
3195void
3196ieee80211_recv_action(struct ieee80211com *ic, struct mbuf *m,
3197 struct ieee80211_node *ni)
3198{
3199 const struct ieee80211_frame *wh;
3200 const u_int8_t *frm;
3201
3202 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 2) {
3203 DPRINTF(("frame too short\n"));
3204 return;
3205 }
3206 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
3207 frm = (const u_int8_t *)&wh[1];
3208
3209 switch (frm[0]) {
3210 case IEEE80211_CATEG_BA:
3211 switch (frm[1]) {
3212 case IEEE80211_ACTION_ADDBA_REQ0:
3213 ieee80211_recv_addba_req(ic, m, ni);
3214 break;
3215 case IEEE80211_ACTION_ADDBA_RESP1:
3216 ieee80211_recv_addba_resp(ic, m, ni);
3217 break;
3218 case IEEE80211_ACTION_DELBA2:
3219 ieee80211_recv_delba(ic, m, ni);
3220 break;
3221 }
3222 break;
3223 case IEEE80211_CATEG_SA_QUERY:
3224 switch (frm[1]) {
3225 case IEEE80211_ACTION_SA_QUERY_REQ0:
3226 ieee80211_recv_sa_query_req(ic, m, ni);
3227 break;
3228#ifndef IEEE80211_STA_ONLY
3229 case IEEE80211_ACTION_SA_QUERY_RESP1:
3230 ieee80211_recv_sa_query_resp(ic, m, ni);
3231 break;
3232#endif
3233 }
3234 break;
3235 default:
3236 DPRINTF(("action frame category %d not handled\n", frm[0]));
3237 break;
3238 }
3239}
3240
3241void
3242ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
3243 struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int subtype)
3244{
3245 switch (subtype) {
3246 case IEEE80211_FC0_SUBTYPE_BEACON0x80:
3247 ieee80211_recv_probe_resp(ic, m, ni, rxi, 0);
3248 break;
3249 case IEEE80211_FC0_SUBTYPE_PROBE_RESP0x50:
3250 ieee80211_recv_probe_resp(ic, m, ni, rxi, 1);
3251 break;
3252#ifndef IEEE80211_STA_ONLY
3253 case IEEE80211_FC0_SUBTYPE_PROBE_REQ0x40:
3254 ieee80211_recv_probe_req(ic, m, ni, rxi);
3255 break;
3256#endif
3257 case IEEE80211_FC0_SUBTYPE_AUTH0xb0:
3258 ieee80211_recv_auth(ic, m, ni, rxi);
3259 break;
3260#ifndef IEEE80211_STA_ONLY
3261 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ0x00:
3262 ieee80211_recv_assoc_req(ic, m, ni, rxi, 0);
3263 break;
3264 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20:
3265 ieee80211_recv_assoc_req(ic, m, ni, rxi, 1);
3266 break;
3267#endif
3268 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP0x10:
3269 ieee80211_recv_assoc_resp(ic, m, ni, 0);
3270 break;
3271 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP0x30:
3272 ieee80211_recv_assoc_resp(ic, m, ni, 1);
3273 break;
3274 case IEEE80211_FC0_SUBTYPE_DEAUTH0xc0:
3275 ieee80211_recv_deauth(ic, m, ni);
3276 break;
3277 case IEEE80211_FC0_SUBTYPE_DISASSOC0xa0:
3278 ieee80211_recv_disassoc(ic, m, ni);
3279 break;
3280 case IEEE80211_FC0_SUBTYPE_ACTION0xd0:
3281 ieee80211_recv_action(ic, m, ni);
3282 break;
3283 default:
3284 DPRINTF(("mgmt frame with subtype 0x%x not handled\n",
3285 subtype));
3286 ic->ic_stats.is_rx_badsubtype++;
3287 break;
3288 }
3289}
3290
3291#ifndef IEEE80211_STA_ONLY
3292/*
3293 * Process an incoming PS-Poll control frame (see 11.2).
3294 */
3295void
3296ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m,
3297 struct ieee80211_node *ni)
3298{
3299 struct ifnet *ifp = &ic->ic_ific_ac.ac_if;
3300 struct ieee80211_frame_pspoll *psp;
3301 struct ieee80211_frame *wh;
3302 u_int16_t aid;
3303
3304 if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
3305 !(ic->ic_caps & IEEE80211_C_APPMGT0x00000020) ||
3306 ni->ni_state != IEEE80211_STA_ASSOC)
3307 return;
3308
3309 if (m->m_lenm_hdr.mh_len < sizeof(*psp)) {
3310 DPRINTF(("frame too short, len %u\n", m->m_len));
3311 ic->ic_stats.is_rx_tooshort++;
3312 return;
3313 }
3314 psp = mtod(m, struct ieee80211_frame_pspoll *)((struct ieee80211_frame_pspoll *)((m)->m_hdr.mh_data));
3315 if (!IEEE80211_ADDR_EQ(psp->i_bssid, ic->ic_bss->ni_bssid)(__builtin_memcmp((psp->i_bssid), (ic->ic_bss->ni_bssid
), (6)) == 0)
) {
3316 DPRINTF(("discard pspoll frame to BSS %s\n",
3317 ether_sprintf(psp->i_bssid)));
3318 ic->ic_stats.is_rx_wrongbss++;
3319 return;
3320 }
3321 aid = letoh16(*(u_int16_t *)psp->i_aid)((__uint16_t)(*(u_int16_t *)psp->i_aid));
3322 if (aid != ni->ni_associd) {
3323 DPRINTF(("invalid pspoll aid %x from %s\n", aid,
3324 ether_sprintf(psp->i_ta)));
3325 return;
3326 }
3327
3328 /* take the first queued frame and put it out.. */
3329 m = mq_dequeue(&ni->ni_savedq);
3330 if (m == NULL((void *)0))
3331 return;
3332 if (mq_empty(&ni->ni_savedq)((&(&ni->ni_savedq)->mq_list)->ml_len == 0)) {
3333 /* last queued frame, turn off the TIM bit */
3334 (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
3335 } else {
3336 /* more queued frames, set the more data bit */
3337 wh = mtod(m, struct ieee80211_frame *)((struct ieee80211_frame *)((m)->m_hdr.mh_data));
3338 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA0x20;
3339 }
3340 mq_enqueue(&ic->ic_pwrsaveq, m);
3341 if_start(ifp);
3342}
3343#endif /* IEEE80211_STA_ONLY */
3344
3345/*
3346 * Process an incoming BlockAckReq control frame (see 7.2.1.7).
3347 */
3348void
3349ieee80211_recv_bar(struct ieee80211com *ic, struct mbuf *m,
3350 struct ieee80211_node *ni)
3351{
3352 const struct ieee80211_frame_min *wh;
3353 const u_int8_t *frm;
3354 u_int16_t ctl, ssn;
3355 u_int8_t tid, ntids;
3356
3357 if (!(ni->ni_flags & IEEE80211_NODE_HT0x0400)) {
3358 DPRINTF(("received BlockAckReq from non-HT STA %s\n",
3359 ether_sprintf(ni->ni_macaddr)));
3360 return;
3361 }
3362 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 4) {
3363 DPRINTF(("frame too short\n"));
3364 return;
3365 }
3366 wh = mtod(m, struct ieee80211_frame_min *)((struct ieee80211_frame_min *)((m)->m_hdr.mh_data));
3367 frm = (const u_int8_t *)&wh[1];
3368
3369 /* read BlockAckReq Control field */
3370 ctl = LE_READ_2(&frm[0])((u_int16_t) ((((const u_int8_t *)(&frm[0]))[0]) | (((const
u_int8_t *)(&frm[0]))[1] << 8)))
;
3371 tid = ctl >> 12;
3372
3373 /* determine BlockAckReq frame variant */
3374 if (ctl & IEEE80211_BA_MULTI_TID0x0002) {
3375 /* Multi-TID BlockAckReq variant (PSMP only) */
3376 ntids = tid + 1;
3377
3378 if (m->m_lenm_hdr.mh_len < sizeof(*wh) + 2 + 4 * ntids) {
3379 DPRINTF(("MTBAR frame too short\n"));
3380 return;
3381 }
3382 frm += 2; /* skip BlockAckReq Control field */
3383 while (ntids-- > 0) {
3384 /* read MTBAR Information field */
3385 tid = LE_READ_2(&frm[0])((u_int16_t) ((((const u_int8_t *)(&frm[0]))[0]) | (((const
u_int8_t *)(&frm[0]))[1] << 8)))
>> 12;
3386 ssn = LE_READ_2(&frm[2])((u_int16_t) ((((const u_int8_t *)(&frm[2]))[0]) | (((const
u_int8_t *)(&frm[2]))[1] << 8)))
>> 4;
3387 ieee80211_bar_tid(ic, ni, tid, ssn);
3388 frm += 4;
3389 }
3390 } else {
3391 /* Basic or Compressed BlockAckReq variants */
3392 ssn = LE_READ_2(&frm[2])((u_int16_t) ((((const u_int8_t *)(&frm[2]))[0]) | (((const
u_int8_t *)(&frm[2]))[1] << 8)))
>> 4;
3393 ieee80211_bar_tid(ic, ni, tid, ssn);
3394 }
3395}
3396
3397/*
3398 * Process a BlockAckReq for a specific TID (see 9.10.7.6.3).
3399 * This is the common back-end for all BlockAckReq frame variants.
3400 */
3401void
3402ieee80211_bar_tid(struct ieee80211com *ic, struct ieee80211_node *ni,
3403 u_int8_t tid, u_int16_t ssn)
3404{
3405 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
3406
3407 /* check if we have a Block Ack agreement for RA/TID */
3408 if (ba->ba_state != IEEE80211_BA_AGREED2) {
3409 /* XXX not sure in PBAC case */
3410 /* send a DELBA with reason code UNKNOWN-BA */
3411 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)
)
3412 IEEE80211_ACTION_DELBA,((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)
)
3413 IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)((*(ic)->ic_send_mgmt)(ic, ni, 0xd0, (IEEE80211_CATEG_BA) <<
16 | (2), IEEE80211_REASON_SETUP_REQUIRED << 16 | tid)
)
;
3414 return;
3415 }
3416 /* check if it is a Protected Block Ack agreement */
3417 if ((ni->ni_flags & IEEE80211_NODE_MFP0x0080) &&
3418 (ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC0x1000)) {
3419 /* ADDBA Requests must be used in PBAC case */
3420 if (SEQ_LT(ssn, ba->ba_winstart)((((u_int16_t)(ssn) - (u_int16_t)(ba->ba_winstart)) & 0xfff
) > 2048)
||
3421 SEQ_LT(ba->ba_winend, ssn)((((u_int16_t)(ba->ba_winend) - (u_int16_t)(ssn)) & 0xfff
) > 2048)
)
3422 ic->ic_stats.is_pbac_errs++;
3423 return; /* PBAC, do not move window */
3424 }
3425 /* reset Block Ack inactivity timer */
3426 if (ba->ba_timeout_val != 0)
3427 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
3428
3429 if (SEQ_LT(ba->ba_winstart, ssn)((((u_int16_t)(ba->ba_winstart) - (u_int16_t)(ssn)) & 0xfff
) > 2048)
) {
3430 struct mbuf_list ml = MBUF_LIST_INITIALIZER(){ ((void *)0), ((void *)0), 0 };
3431 ieee80211_ba_move_window(ic, ni, tid, ssn, &ml);
3432 if_input(&ic->ic_ific_ac.ac_if, &ml);
3433 }
3434}