Bug Summary

File:net80211/ieee80211_input.c
Warning:line 2442, column 4
Assigned value is garbage or undefined

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

/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
)
46
Assuming the condition is false
47
Taking false branch
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)
48
Assuming the condition is true
49
Taking true branch
1469 return 0;
50
Returning without writing to 'rsn->rsn_pmkids'
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) {
43
Assuming the condition is false
44
Taking false branch
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);
45
Calling 'ieee80211_parse_rsn_body'
51
Returning from 'ieee80211_parse_rsn_body'
52
Returning without writing to 'rsn->rsn_pmkids'
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 ||
1
Assuming field 'ic_opmode' is equal to IEEE80211_M_HOSTAP
3
Taking false branch
2171 ic->ic_state != IEEE80211_S_RUN)
2
Assuming field 'ic_state' is equal to 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)) {
4
Assuming 'reassoc' is 0
5
'?' condition is false
6
Assuming the condition is false
7
Taking false branch
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)
) {
8
Assuming the condition is true
9
Taking false branch
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
9.1
'reassoc' is 0
9.1
'reassoc' is 0
) {
10
Taking false branch
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) {
11
Assuming the condition is true
12
Loop condition is true. Entering loop body
17
Assuming the condition is true
18
Loop condition is true. Entering loop body
23
Loop condition is true. Entering loop body
28
Loop condition is false. Execution continues on line 2238
2199 if (frm + 2 + frm[1] > efrm) {
13
Assuming the condition is false
14
Taking false branch
19
Assuming the condition is false
20
Taking false branch
24
Assuming the condition is false
25
Taking false branch
2200 ic->ic_stats.is_rx_elem_toosmall++;
2201 break;
2202 }
2203 switch (frm[0]) {
15
Control jumps to 'case IEEE80211_ELEMID_RSN:' at line 2213
21
Control jumps to 'case IEEE80211_ELEMID_SSID:' at line 2204
26
Control jumps to 'case IEEE80211_ELEMID_RATES:' at line 2207
2204 case IEEE80211_ELEMID_SSID:
2205 ssid = frm;
2206 break;
22
Execution continues on line 2235
2207 case IEEE80211_ELEMID_RATES:
2208 rates = frm;
2209 break;
27
Execution continues on line 2235
2210 case IEEE80211_ELEMID_XRATES:
2211 xrates = frm;
2212 break;
2213 case IEEE80211_ELEMID_RSN:
2214 rsnie = frm;
2215 break;
16
Execution continues on line 2235
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
28.1
'rates' is not equal to NULL
28.1
'rates' is not equal to NULL
== NULL((void *)0) || rates[1] > IEEE80211_RATE_MAXSIZE15) {
29
Assuming the condition is false
30
Taking false branch
2239 DPRINTF(("invalid supported rates element\n"));
2240 return;
2241 }
2242 /* SSID element is mandatory */
2243 if (ssid
30.1
'ssid' is not equal to NULL
30.1
'ssid' is not equal to NULL
== NULL((void *)0) || ssid[1] > IEEE80211_NWID_LEN32) {
31
Assuming the condition is false
32
Taking false branch
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 ||
33
Assuming the condition is false
35
Taking false branch
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))
) {
34
Assuming the condition is false
2250 DPRINTF(("SSID mismatch\n"));
2251 ic->ic_stats.is_rx_ssidmismatch++;
2252 return;
2253 }
2254
2255 if (ni->ni_state != IEEE80211_STA_AUTH &&
36
Assuming field 'ni_state' is equal to 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
36.1
Field 'ni_state' is not equal to IEEE80211_STA_ASSOC
36.1
Field 'ni_state' is not equal to IEEE80211_STA_ASSOC
== 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)) {
37
Assuming the condition is false
38
Taking false branch
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) {
39
Assuming the condition is false
40
Taking false branch
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
40.1
'rsnie' is not equal to NULL
40.1
'rsnie' is not equal to NULL
!= NULL((void *)0)) {
41
Taking true branch
2323 status = ieee80211_parse_rsn(ic, rsnie, &rsn);
42
Calling 'ieee80211_parse_rsn'
53
Returning from 'ieee80211_parse_rsn'
2324 if (status
53.1
'status' is equal to 0
53.1
'status' is equal to 0
!= 0)
54
Taking false branch
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) &&
55
Assuming the condition is true
57
Taking true branch
2329 (ic->ic_rsnprotos & IEEE80211_PROTO_RSN(1 << 0))) {
56
Assuming the condition is true
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) {
58
Assuming the condition is false
59
Taking false branch
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) {
60
Taking true branch
2354 if (ni->ni_rsnprotos
60.1
Field 'ni_rsnprotos' is not equal to IEEE80211_PROTO_NONE
60.1
Field 'ni_rsnprotos' is not equal to IEEE80211_PROTO_NONE
== IEEE80211_PROTO_NONE0) {
61
Taking false branch
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
61.1
Field 'rsn_nakms' is equal to 1
61.1
Field 'rsn_nakms' is equal to 1
!= 1 ||
63
Taking false branch
2370 !(rsn.rsn_akms & ic->ic_bss->ni_rsnakms)) {
62
Assuming the condition is false
2371 status = IEEE80211_STATUS_BAD_AKMP;
2372 ni->ni_rsnprotos = IEEE80211_PROTO_NONE0;
2373 goto end;
2374 }
2375 if (rsn.rsn_nciphers
63.1
Field 'rsn_nciphers' is equal to 1
63.1
Field 'rsn_nciphers' is equal to 1
!= 1 ||
65
Taking false branch
2376 !(rsn.rsn_ciphers & ic->ic_bss->ni_rsnciphers)) {
64
Assuming the condition is false
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) {
66
Assuming field 'rsn_groupcipher' is equal to field 'ni_rsngroupcipher'
67
Taking false branch
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) &&
68
Assuming the condition is false
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) &&
69
Assuming the condition is false
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) &&
70
Assuming the condition is false
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
70.1
'saveie' is not equal to NULL
70.1
'saveie' is not equal to NULL
== NULL((void *)0) ||
71
Taking false branch
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)) {
72
Calling 'ieee80211_is_8021x_akm'
74
Returning from 'ieee80211_is_8021x_akm'
75
Taking true branch
2441 struct ieee80211_pmk *pmk = NULL((void *)0);
2442 const u_int8_t *pmkid = rsn.rsn_pmkids;
76
Assigned value is garbage or undefined
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)))
;
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}

/usr/src/sys/net80211/ieee80211_crypto.h

1/* $OpenBSD: ieee80211_crypto.h,v 1.27 2020/05/15 14:21:09 stsp Exp $ */
2
3/*-
4 * Copyright (c) 2007,2008 Damien Bergamini <damien.bergamini@free.fr>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef _NET80211_IEEE80211_CRYPTO_H_
20#define _NET80211_IEEE80211_CRYPTO_H_
21
22/*
23 * 802.11 protocol crypto-related definitions.
24 */
25
26/*
27 * 802.11 ciphers.
28 */
29enum ieee80211_cipher {
30 IEEE80211_CIPHER_NONE = 0x00000000,
31 IEEE80211_CIPHER_USEGROUP = 0x00000001,
32 IEEE80211_CIPHER_WEP40 = 0x00000002,
33 IEEE80211_CIPHER_TKIP = 0x00000004,
34 IEEE80211_CIPHER_CCMP = 0x00000008,
35 IEEE80211_CIPHER_WEP104 = 0x00000010,
36 IEEE80211_CIPHER_BIP = 0x00000020 /* 11w */
37};
38
39/*
40 * 802.11 Authentication and Key Management Protocols.
41 */
42enum ieee80211_akm {
43 IEEE80211_AKM_NONE = 0x00000000,
44 IEEE80211_AKM_8021X = 0x00000001,
45 IEEE80211_AKM_PSK = 0x00000002,
46 IEEE80211_AKM_SHA256_8021X = 0x00000004, /* 11w */
47 IEEE80211_AKM_SHA256_PSK = 0x00000008 /* 11w */
48};
49
50#define IEEE80211_TKIP_HDRLEN8 8
51#define IEEE80211_TKIP_MICLEN8 8
52#define IEEE80211_TKIP_ICVLEN4 4
53#define IEEE80211_CCMP_HDRLEN8 8
54#define IEEE80211_CCMP_MICLEN8 8
55
56#define IEEE80211_PMK_LEN32 32
57
58#ifdef _KERNEL1
59
60static __inline int
61ieee80211_is_8021x_akm(enum ieee80211_akm akm)
62{
63 return akm
72.1
'akm' is equal to IEEE80211_AKM_8021X
72.1
'akm' is equal to IEEE80211_AKM_8021X
== IEEE80211_AKM_8021X ||
73
Returning the value 1, which participates in a condition later
64 akm == IEEE80211_AKM_SHA256_8021X;
65}
66
67static __inline int
68ieee80211_is_sha256_akm(enum ieee80211_akm akm)
69{
70 return akm == IEEE80211_AKM_SHA256_8021X ||
71 akm == IEEE80211_AKM_SHA256_PSK;
72}
73
74struct ieee80211_key {
75 u_int8_t k_id; /* identifier (0-5) */
76 enum ieee80211_cipher k_cipher;
77 u_int k_flags;
78#define IEEE80211_KEY_GROUP0x00000001 0x00000001 /* group data key */
79#define IEEE80211_KEY_TX0x00000002 0x00000002 /* Tx+Rx */
80#define IEEE80211_KEY_IGTK0x00000004 0x00000004 /* integrity group key */
81#define IEEE80211_KEY_SWCRYPTO0x00000080 0x00000080 /* loaded for software crypto */
82
83 u_int k_len;
84 u_int64_t k_rsc[IEEE80211_NUM_TID16];
85 u_int64_t k_mgmt_rsc;
86 u_int64_t k_tsc;
87 u_int8_t k_key[32];
88 void *k_priv;
89};
90
91#define IEEE80211_KEYBUF_SIZE16 16
92
93/*
94 * Entry in the PMKSA cache.
95 */
96struct ieee80211_pmk {
97 enum ieee80211_akm pmk_akm;
98 u_int32_t pmk_lifetime;
99#define IEEE80211_PMK_INFINITE0 0
100
101 u_int8_t pmk_pmkid[IEEE80211_PMKID_LEN16];
102 u_int8_t pmk_macaddr[IEEE80211_ADDR_LEN6];
103 u_int8_t pmk_key[IEEE80211_PMK_LEN32];
104
105 TAILQ_ENTRY(ieee80211_pmk)struct { struct ieee80211_pmk *tqe_next; struct ieee80211_pmk
**tqe_prev; }
pmk_next;
106};
107
108/* forward references */
109struct ieee80211com;
110struct ieee80211_node;
111
112void ieee80211_crypto_attach(struct ifnet *);
113void ieee80211_crypto_detach(struct ifnet *);
114
115void ieee80211_crypto_clear_groupkeys(struct ieee80211com *);
116struct ieee80211_key *ieee80211_get_txkey(struct ieee80211com *,
117 const struct ieee80211_frame *, struct ieee80211_node *);
118struct ieee80211_key *ieee80211_get_rxkey(struct ieee80211com *,
119 struct mbuf *, struct ieee80211_node *);
120struct mbuf *ieee80211_encrypt(struct ieee80211com *, struct mbuf *,
121 struct ieee80211_key *);
122struct mbuf *ieee80211_decrypt(struct ieee80211com *, struct mbuf *,
123 struct ieee80211_node *);
124
125int ieee80211_set_key(struct ieee80211com *, struct ieee80211_node *,
126 struct ieee80211_key *);
127void ieee80211_delete_key(struct ieee80211com *, struct ieee80211_node *,
128 struct ieee80211_key *);
129
130void ieee80211_eapol_key_mic(struct ieee80211_eapol_key *,
131 const u_int8_t *);
132int ieee80211_eapol_key_check_mic(struct ieee80211_eapol_key *,
133 const u_int8_t *);
134#ifndef IEEE80211_STA_ONLY
135void ieee80211_eapol_key_encrypt(struct ieee80211com *,
136 struct ieee80211_eapol_key *, const u_int8_t *);
137#endif
138int ieee80211_eapol_key_decrypt(struct ieee80211_eapol_key *,
139 const u_int8_t *);
140
141struct ieee80211_pmk *ieee80211_pmksa_add(struct ieee80211com *,
142 enum ieee80211_akm, const u_int8_t *, const u_int8_t *, u_int32_t);
143struct ieee80211_pmk *ieee80211_pmksa_find(struct ieee80211com *,
144 struct ieee80211_node *, const u_int8_t *);
145void ieee80211_derive_ptk(enum ieee80211_akm, const u_int8_t *,
146 const u_int8_t *, const u_int8_t *, const u_int8_t *,
147 const u_int8_t *, struct ieee80211_ptk *);
148int ieee80211_cipher_keylen(enum ieee80211_cipher);
149
150int ieee80211_wep_set_key(struct ieee80211com *, struct ieee80211_key *);
151void ieee80211_wep_delete_key(struct ieee80211com *,
152 struct ieee80211_key *);
153struct mbuf *ieee80211_wep_encrypt(struct ieee80211com *, struct mbuf *,
154 struct ieee80211_key *);
155struct mbuf *ieee80211_wep_decrypt(struct ieee80211com *, struct mbuf *,
156 struct ieee80211_key *);
157
158int ieee80211_tkip_set_key(struct ieee80211com *, struct ieee80211_key *);
159void ieee80211_tkip_delete_key(struct ieee80211com *,
160 struct ieee80211_key *);
161struct mbuf *ieee80211_tkip_encrypt(struct ieee80211com *,
162 struct mbuf *, struct ieee80211_key *);
163int ieee80211_tkip_get_tsc(uint64_t *, uint64_t **, struct mbuf *,
164 struct ieee80211_key *);
165struct mbuf *ieee80211_tkip_decrypt(struct ieee80211com *,
166 struct mbuf *, struct ieee80211_key *);
167void ieee80211_tkip_mic(struct mbuf *, int, const u_int8_t *,
168 u_int8_t[IEEE80211_TKIP_MICLEN8]);
169void ieee80211_michael_mic_failure(struct ieee80211com *, u_int64_t);
170#ifndef IEEE80211_STA_ONLY
171void ieee80211_michael_mic_failure_timeout(void *);
172#endif
173
174int ieee80211_ccmp_set_key(struct ieee80211com *, struct ieee80211_key *);
175void ieee80211_ccmp_delete_key(struct ieee80211com *,
176 struct ieee80211_key *);
177struct mbuf *ieee80211_ccmp_encrypt(struct ieee80211com *, struct mbuf *,
178 struct ieee80211_key *);
179int ieee80211_ccmp_get_pn(uint64_t *, uint64_t **, struct mbuf *,
180 struct ieee80211_key *);
181struct mbuf *ieee80211_ccmp_decrypt(struct ieee80211com *, struct mbuf *,
182 struct ieee80211_key *);
183
184int ieee80211_bip_set_key(struct ieee80211com *, struct ieee80211_key *);
185void ieee80211_bip_delete_key(struct ieee80211com *,
186 struct ieee80211_key *);
187struct mbuf *ieee80211_bip_encap(struct ieee80211com *, struct mbuf *,
188 struct ieee80211_key *);
189struct mbuf *ieee80211_bip_decap(struct ieee80211com *, struct mbuf *,
190 struct ieee80211_key *);
191
192#endif /* _KERNEL */
193#endif /* _NET80211_IEEE80211_CRYPTO_H_ */