Line data Source code
1 : /* $OpenBSD: ieee80211_input.c,v 1.202 2018/08/07 18:13:14 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 NBPFILTER > 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 :
61 : struct mbuf *ieee80211_defrag(struct ieee80211com *, struct mbuf *, int);
62 : void ieee80211_defrag_timeout(void *);
63 : void ieee80211_input_ba(struct ieee80211com *, struct mbuf *,
64 : struct ieee80211_node *, int, struct ieee80211_rxinfo *);
65 : void ieee80211_input_ba_flush(struct ieee80211com *, struct ieee80211_node *,
66 : struct ieee80211_rx_ba *);
67 : void ieee80211_input_ba_gap_timeout(void *arg);
68 : void ieee80211_ba_move_window(struct ieee80211com *,
69 : struct ieee80211_node *, u_int8_t, u_int16_t);
70 : void ieee80211_input_ba_seq(struct ieee80211com *,
71 : struct ieee80211_node *, uint8_t, uint16_t);
72 : struct mbuf *ieee80211_align_mbuf(struct mbuf *);
73 : void ieee80211_decap(struct ieee80211com *, struct mbuf *,
74 : struct ieee80211_node *, int);
75 : void ieee80211_amsdu_decap(struct ieee80211com *, struct mbuf *,
76 : struct ieee80211_node *, int);
77 : void ieee80211_deliver_data(struct ieee80211com *, struct mbuf *,
78 : struct ieee80211_node *, int);
79 : int ieee80211_parse_edca_params_body(struct ieee80211com *,
80 : const u_int8_t *);
81 : int ieee80211_parse_edca_params(struct ieee80211com *, const u_int8_t *);
82 : int ieee80211_parse_wmm_params(struct ieee80211com *, const u_int8_t *);
83 : enum ieee80211_cipher ieee80211_parse_rsn_cipher(const u_int8_t[]);
84 : enum ieee80211_akm ieee80211_parse_rsn_akm(const u_int8_t[]);
85 : int ieee80211_parse_rsn_body(struct ieee80211com *, const u_int8_t *,
86 : u_int, struct ieee80211_rsnparams *);
87 : int ieee80211_save_ie(const u_int8_t *, u_int8_t **);
88 : void ieee80211_recv_probe_resp(struct ieee80211com *, struct mbuf *,
89 : struct ieee80211_node *, struct ieee80211_rxinfo *, int);
90 : #ifndef IEEE80211_STA_ONLY
91 : void ieee80211_recv_probe_req(struct ieee80211com *, struct mbuf *,
92 : struct ieee80211_node *, struct ieee80211_rxinfo *);
93 : #endif
94 : void ieee80211_recv_auth(struct ieee80211com *, struct mbuf *,
95 : struct ieee80211_node *, struct ieee80211_rxinfo *);
96 : #ifndef IEEE80211_STA_ONLY
97 : void ieee80211_recv_assoc_req(struct ieee80211com *, struct mbuf *,
98 : struct ieee80211_node *, struct ieee80211_rxinfo *, int);
99 : #endif
100 : void ieee80211_recv_assoc_resp(struct ieee80211com *, struct mbuf *,
101 : struct ieee80211_node *, int);
102 : void ieee80211_recv_deauth(struct ieee80211com *, struct mbuf *,
103 : struct ieee80211_node *);
104 : void ieee80211_recv_disassoc(struct ieee80211com *, struct mbuf *,
105 : struct ieee80211_node *);
106 : void ieee80211_recv_addba_req(struct ieee80211com *, struct mbuf *,
107 : struct ieee80211_node *);
108 : void ieee80211_recv_addba_resp(struct ieee80211com *, struct mbuf *,
109 : struct ieee80211_node *);
110 : void ieee80211_recv_delba(struct ieee80211com *, struct mbuf *,
111 : struct ieee80211_node *);
112 : void ieee80211_recv_sa_query_req(struct ieee80211com *, struct mbuf *,
113 : struct ieee80211_node *);
114 : #ifndef IEEE80211_STA_ONLY
115 : void ieee80211_recv_sa_query_resp(struct ieee80211com *, struct mbuf *,
116 : struct ieee80211_node *);
117 : #endif
118 : void ieee80211_recv_action(struct ieee80211com *, struct mbuf *,
119 : struct ieee80211_node *);
120 : #ifndef IEEE80211_STA_ONLY
121 : void ieee80211_recv_pspoll(struct ieee80211com *, struct mbuf *,
122 : struct ieee80211_node *);
123 : #endif
124 : void ieee80211_recv_bar(struct ieee80211com *, struct mbuf *,
125 : struct ieee80211_node *);
126 : void ieee80211_bar_tid(struct ieee80211com *, struct ieee80211_node *,
127 : u_int8_t, u_int16_t);
128 :
129 : /*
130 : * Retrieve the length in bytes of an 802.11 header.
131 : */
132 : u_int
133 0 : ieee80211_get_hdrlen(const struct ieee80211_frame *wh)
134 : {
135 : u_int size = sizeof(*wh);
136 :
137 : /* NB: does not work with control frames */
138 0 : KASSERT(ieee80211_has_seq(wh));
139 :
140 0 : if (ieee80211_has_addr4(wh))
141 0 : size += IEEE80211_ADDR_LEN; /* i_addr4 */
142 0 : if (ieee80211_has_qos(wh))
143 0 : size += sizeof(u_int16_t); /* i_qos */
144 0 : if (ieee80211_has_htc(wh))
145 0 : size += sizeof(u_int32_t); /* i_ht */
146 0 : return size;
147 : }
148 :
149 : /*
150 : * Process a received frame. The node associated with the sender
151 : * should be supplied. If nothing was found in the node table then
152 : * the caller is assumed to supply a reference to ic_bss instead.
153 : * The RSSI and a timestamp are also supplied. The RSSI data is used
154 : * during AP scanning to select a AP to associate with; it can have
155 : * any units so long as values have consistent units and higher values
156 : * mean ``better signal''. The receive timestamp is currently not used
157 : * by the 802.11 layer.
158 : */
159 : void
160 0 : ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
161 : struct ieee80211_rxinfo *rxi)
162 : {
163 0 : struct ieee80211com *ic = (void *)ifp;
164 : struct ieee80211_frame *wh;
165 : u_int16_t *orxseq, nrxseq, qos;
166 : u_int8_t dir, type, subtype, tid;
167 : int hdrlen, hasqos;
168 :
169 0 : KASSERT(ni != NULL);
170 :
171 : /* in monitor mode, send everything directly to bpf */
172 0 : if (ic->ic_opmode == IEEE80211_M_MONITOR)
173 : goto out;
174 :
175 : /*
176 : * Do not process frames without an Address 2 field any further.
177 : * Only CTS and ACK control frames do not have this field.
178 : */
179 0 : if (m->m_len < sizeof(struct ieee80211_frame_min)) {
180 : DPRINTF(("frame too short, len %u\n", m->m_len));
181 0 : ic->ic_stats.is_rx_tooshort++;
182 0 : goto out;
183 : }
184 :
185 0 : wh = mtod(m, struct ieee80211_frame *);
186 0 : if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
187 : IEEE80211_FC0_VERSION_0) {
188 : DPRINTF(("frame with wrong version: %x\n", wh->i_fc[0]));
189 0 : ic->ic_stats.is_rx_badversion++;
190 0 : goto err;
191 : }
192 :
193 0 : dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
194 0 : type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
195 0 : subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
196 :
197 0 : if (type != IEEE80211_FC0_TYPE_CTL) {
198 0 : hdrlen = ieee80211_get_hdrlen(wh);
199 0 : if (m->m_len < hdrlen) {
200 : DPRINTF(("frame too short, len %u\n", m->m_len));
201 0 : ic->ic_stats.is_rx_tooshort++;
202 0 : goto err;
203 : }
204 : }
205 0 : if ((hasqos = ieee80211_has_qos(wh))) {
206 0 : qos = ieee80211_get_qos(wh);
207 0 : tid = qos & IEEE80211_QOS_TID;
208 0 : } else {
209 : qos = 0;
210 : tid = 0;
211 : }
212 :
213 0 : if (type == IEEE80211_FC0_TYPE_DATA && hasqos &&
214 0 : (subtype & IEEE80211_FC0_SUBTYPE_NODATA) == 0 &&
215 0 : !(rxi->rxi_flags & IEEE80211_RXI_AMPDU_DONE)) {
216 0 : int ba_state = ni->ni_rx_ba[tid].ba_state;
217 :
218 : /*
219 : * If Block Ack was explicitly requested, check
220 : * if we have a BA agreement for this RA/TID.
221 : */
222 0 : if ((qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
223 0 : IEEE80211_QOS_ACK_POLICY_BA &&
224 0 : ba_state != IEEE80211_BA_AGREED) {
225 : DPRINTF(("no BA agreement for %s, TID %d\n",
226 : ether_sprintf(ni->ni_macaddr), tid));
227 : /* send a DELBA with reason code UNKNOWN-BA */
228 0 : IEEE80211_SEND_ACTION(ic, ni,
229 : IEEE80211_CATEG_BA, IEEE80211_ACTION_DELBA,
230 : IEEE80211_REASON_SETUP_REQUIRED << 16 | tid);
231 0 : goto err;
232 : }
233 :
234 : /*
235 : * Check if we have an explicit or implicit
236 : * Block Ack Request for a valid BA agreement.
237 : */
238 0 : if (ba_state == IEEE80211_BA_AGREED &&
239 : ((qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
240 0 : IEEE80211_QOS_ACK_POLICY_BA ||
241 0 : (qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
242 : IEEE80211_QOS_ACK_POLICY_NORMAL)) {
243 : /* go through A-MPDU reordering */
244 0 : ieee80211_input_ba(ic, m, ni, tid, rxi);
245 0 : return; /* don't free m! */
246 : }
247 0 : }
248 :
249 : /* duplicate detection (see 9.2.9) */
250 0 : if (ieee80211_has_seq(wh) &&
251 0 : ic->ic_state != IEEE80211_S_SCAN) {
252 0 : nrxseq = letoh16(*(u_int16_t *)wh->i_seq) >>
253 : IEEE80211_SEQ_SEQ_SHIFT;
254 0 : if (hasqos)
255 0 : orxseq = &ni->ni_qos_rxseqs[tid];
256 : else
257 0 : orxseq = &ni->ni_rxseq;
258 0 : if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
259 0 : nrxseq == *orxseq) {
260 : /* duplicate, silently discarded */
261 0 : ic->ic_stats.is_rx_dup++;
262 0 : goto out;
263 : }
264 0 : *orxseq = nrxseq;
265 0 : }
266 0 : if (ic->ic_state > IEEE80211_S_SCAN) {
267 0 : ni->ni_rssi = rxi->rxi_rssi;
268 0 : ni->ni_rstamp = rxi->rxi_tstamp;
269 0 : ni->ni_inact = 0;
270 :
271 0 : if (ic->ic_state == IEEE80211_S_RUN && ic->ic_bgscan_start) {
272 : /* Cancel or start background scan based on RSSI. */
273 0 : if ((*ic->ic_node_checkrssi)(ic, ni))
274 0 : timeout_del(&ic->ic_bgscan_timeout);
275 0 : else if (!timeout_pending(&ic->ic_bgscan_timeout) &&
276 0 : (ic->ic_flags & IEEE80211_F_BGSCAN) == 0 &&
277 0 : (ic->ic_flags & IEEE80211_F_DESBSSID) == 0)
278 0 : timeout_add_msec(&ic->ic_bgscan_timeout,
279 0 : 500 * (ic->ic_bgscan_fail + 1));
280 : }
281 : }
282 :
283 : #ifndef IEEE80211_STA_ONLY
284 0 : if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
285 0 : (ic->ic_caps & IEEE80211_C_APPMGT) &&
286 0 : ni->ni_state == IEEE80211_STA_ASSOC) {
287 0 : if (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) {
288 0 : if (ni->ni_pwrsave == IEEE80211_PS_AWAKE) {
289 : /* turn on PS mode */
290 0 : ni->ni_pwrsave = IEEE80211_PS_DOZE;
291 : DPRINTF(("PS mode on for %s\n",
292 : ether_sprintf(wh->i_addr2)));
293 0 : }
294 0 : } else if (ni->ni_pwrsave == IEEE80211_PS_DOZE) {
295 : struct mbuf *m;
296 :
297 : /* turn off PS mode */
298 0 : ni->ni_pwrsave = IEEE80211_PS_AWAKE;
299 : DPRINTF(("PS mode off for %s\n",
300 : ether_sprintf(wh->i_addr2)));
301 :
302 0 : (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
303 :
304 : /* dequeue buffered unicast frames */
305 0 : while ((m = mq_dequeue(&ni->ni_savedq)) != NULL) {
306 0 : mq_enqueue(&ic->ic_pwrsaveq, m);
307 0 : if_start(ifp);
308 : }
309 0 : }
310 : }
311 : #endif
312 0 : switch (type) {
313 : case IEEE80211_FC0_TYPE_DATA:
314 0 : switch (ic->ic_opmode) {
315 : case IEEE80211_M_STA:
316 0 : if (dir != IEEE80211_FC1_DIR_FROMDS) {
317 0 : ic->ic_stats.is_rx_wrongdir++;
318 0 : goto out;
319 : }
320 0 : if (ic->ic_state != IEEE80211_S_SCAN &&
321 0 : !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
322 : /* Source address is not our BSS. */
323 : DPRINTF(("discard frame from SA %s\n",
324 : ether_sprintf(wh->i_addr2)));
325 0 : ic->ic_stats.is_rx_wrongbss++;
326 0 : goto out;
327 : }
328 0 : if ((ifp->if_flags & IFF_SIMPLEX) &&
329 0 : IEEE80211_IS_MULTICAST(wh->i_addr1) &&
330 0 : IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
331 : /*
332 : * In IEEE802.11 network, multicast frame
333 : * sent from me is broadcasted from AP.
334 : * It should be silently discarded for
335 : * SIMPLEX interface.
336 : */
337 0 : ic->ic_stats.is_rx_mcastecho++;
338 0 : goto out;
339 : }
340 : break;
341 : #ifndef IEEE80211_STA_ONLY
342 : case IEEE80211_M_IBSS:
343 : case IEEE80211_M_AHDEMO:
344 0 : if (dir != IEEE80211_FC1_DIR_NODS) {
345 0 : ic->ic_stats.is_rx_wrongdir++;
346 0 : goto out;
347 : }
348 0 : if (ic->ic_state != IEEE80211_S_SCAN &&
349 0 : !IEEE80211_ADDR_EQ(wh->i_addr3,
350 0 : ic->ic_bss->ni_bssid) &&
351 0 : !IEEE80211_ADDR_EQ(wh->i_addr3,
352 : etherbroadcastaddr)) {
353 : /* Destination is not our BSS or broadcast. */
354 : DPRINTF(("discard data frame to DA %s\n",
355 : ether_sprintf(wh->i_addr3)));
356 0 : ic->ic_stats.is_rx_wrongbss++;
357 0 : goto out;
358 : }
359 : break;
360 : case IEEE80211_M_HOSTAP:
361 0 : if (dir != IEEE80211_FC1_DIR_TODS) {
362 0 : ic->ic_stats.is_rx_wrongdir++;
363 0 : goto out;
364 : }
365 0 : if (ic->ic_state != IEEE80211_S_SCAN &&
366 0 : !IEEE80211_ADDR_EQ(wh->i_addr1,
367 0 : ic->ic_bss->ni_bssid) &&
368 0 : !IEEE80211_ADDR_EQ(wh->i_addr1,
369 : etherbroadcastaddr)) {
370 : /* BSS is not us or broadcast. */
371 : DPRINTF(("discard data frame to BSS %s\n",
372 : ether_sprintf(wh->i_addr1)));
373 0 : ic->ic_stats.is_rx_wrongbss++;
374 0 : goto out;
375 : }
376 : /* check if source STA is associated */
377 0 : if (ni == ic->ic_bss) {
378 : DPRINTF(("data from unknown src %s\n",
379 : ether_sprintf(wh->i_addr2)));
380 : /* NB: caller deals with reference */
381 0 : ni = ieee80211_find_node(ic, wh->i_addr2);
382 0 : if (ni == NULL)
383 0 : ni = ieee80211_dup_bss(ic, wh->i_addr2);
384 0 : if (ni != NULL) {
385 0 : IEEE80211_SEND_MGMT(ic, ni,
386 : IEEE80211_FC0_SUBTYPE_DEAUTH,
387 : IEEE80211_REASON_NOT_AUTHED);
388 0 : }
389 0 : ic->ic_stats.is_rx_notassoc++;
390 0 : goto err;
391 : }
392 0 : if (ni->ni_state != IEEE80211_STA_ASSOC) {
393 : DPRINTF(("data from unassoc src %s\n",
394 : ether_sprintf(wh->i_addr2)));
395 0 : IEEE80211_SEND_MGMT(ic, ni,
396 : IEEE80211_FC0_SUBTYPE_DISASSOC,
397 : IEEE80211_REASON_NOT_ASSOCED);
398 0 : ic->ic_stats.is_rx_notassoc++;
399 0 : goto err;
400 : }
401 : break;
402 : #endif /* IEEE80211_STA_ONLY */
403 : default:
404 : /* can't get there */
405 : goto out;
406 : }
407 :
408 0 : if ((ic->ic_flags & IEEE80211_F_WEPON) ||
409 0 : ((ic->ic_flags & IEEE80211_F_RSNON) &&
410 0 : (ni->ni_flags & IEEE80211_NODE_RXPROT))) {
411 : /* protection is on for Rx */
412 0 : if (!(rxi->rxi_flags & IEEE80211_RXI_HWDEC)) {
413 0 : if (!(wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
414 : /* drop unencrypted */
415 0 : ic->ic_stats.is_rx_unencrypted++;
416 0 : goto err;
417 : }
418 : /* do software decryption */
419 0 : m = ieee80211_decrypt(ic, m, ni);
420 0 : if (m == NULL) {
421 0 : ic->ic_stats.is_rx_wepfail++;
422 0 : goto err;
423 : }
424 0 : wh = mtod(m, struct ieee80211_frame *);
425 0 : }
426 0 : } else if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) ||
427 0 : (rxi->rxi_flags & IEEE80211_RXI_HWDEC)) {
428 : /* frame encrypted but protection off for Rx */
429 0 : ic->ic_stats.is_rx_nowep++;
430 0 : goto out;
431 : }
432 :
433 : #if NBPFILTER > 0
434 : /* copy to listener after decrypt */
435 0 : if (ic->ic_rawbpf)
436 0 : bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);
437 : #endif
438 :
439 0 : if ((ni->ni_flags & IEEE80211_NODE_HT) &&
440 0 : hasqos && (qos & IEEE80211_QOS_AMSDU))
441 0 : ieee80211_amsdu_decap(ic, m, ni, hdrlen);
442 : else
443 0 : ieee80211_decap(ic, m, ni, hdrlen);
444 0 : return;
445 :
446 : case IEEE80211_FC0_TYPE_MGT:
447 0 : if (dir != IEEE80211_FC1_DIR_NODS) {
448 0 : ic->ic_stats.is_rx_wrongdir++;
449 0 : goto err;
450 : }
451 : #ifndef IEEE80211_STA_ONLY
452 0 : if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
453 0 : ic->ic_stats.is_rx_ahdemo_mgt++;
454 0 : goto out;
455 : }
456 : #endif
457 : /* drop frames without interest */
458 0 : if (ic->ic_state == IEEE80211_S_SCAN) {
459 0 : if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
460 0 : subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
461 0 : ic->ic_stats.is_rx_mgtdiscard++;
462 0 : goto out;
463 : }
464 : }
465 :
466 0 : if (ni->ni_flags & IEEE80211_NODE_RXMGMTPROT) {
467 : /* MMPDU protection is on for Rx */
468 0 : if (subtype == IEEE80211_FC0_SUBTYPE_DISASSOC ||
469 0 : subtype == IEEE80211_FC0_SUBTYPE_DEAUTH ||
470 0 : subtype == IEEE80211_FC0_SUBTYPE_ACTION) {
471 0 : if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
472 0 : !(wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
473 : /* unicast mgmt not encrypted */
474 : goto out;
475 : }
476 : /* do software decryption */
477 0 : m = ieee80211_decrypt(ic, m, ni);
478 0 : if (m == NULL) {
479 : /* XXX stats */
480 : goto out;
481 : }
482 0 : wh = mtod(m, struct ieee80211_frame *);
483 0 : }
484 0 : } else if ((ic->ic_flags & IEEE80211_F_RSNON) &&
485 0 : (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
486 : /* encrypted but MMPDU Rx protection off for TA */
487 : goto out;
488 : }
489 :
490 : #if NBPFILTER > 0
491 0 : if (bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN) != 0) {
492 : /*
493 : * Drop mbuf if it was filtered by bpf. Normally,
494 : * this is done in ether_input() but IEEE 802.11
495 : * management frames are a special case.
496 : */
497 0 : m_freem(m);
498 0 : return;
499 : }
500 : #endif
501 0 : (*ic->ic_recv_mgmt)(ic, m, ni, rxi, subtype);
502 0 : m_freem(m);
503 0 : return;
504 :
505 : case IEEE80211_FC0_TYPE_CTL:
506 0 : ic->ic_stats.is_rx_ctl++;
507 0 : switch (subtype) {
508 : #ifndef IEEE80211_STA_ONLY
509 : case IEEE80211_FC0_SUBTYPE_PS_POLL:
510 0 : ieee80211_recv_pspoll(ic, m, ni);
511 0 : break;
512 : #endif
513 : case IEEE80211_FC0_SUBTYPE_BAR:
514 0 : ieee80211_recv_bar(ic, m, ni);
515 0 : break;
516 : default:
517 : break;
518 : }
519 : goto out;
520 :
521 : default:
522 : DPRINTF(("bad frame type %x\n", type));
523 : /* should not come here */
524 : break;
525 : }
526 : err:
527 0 : ifp->if_ierrors++;
528 : out:
529 0 : if (m != NULL) {
530 : #if NBPFILTER > 0
531 0 : if (ic->ic_rawbpf)
532 0 : bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);
533 : #endif
534 0 : m_freem(m);
535 0 : }
536 0 : }
537 :
538 : /*
539 : * Handle defragmentation (see 9.5 and Annex C). We support the concurrent
540 : * reception of fragments of three fragmented MSDUs or MMPDUs.
541 : */
542 : struct mbuf *
543 0 : ieee80211_defrag(struct ieee80211com *ic, struct mbuf *m, int hdrlen)
544 : {
545 : const struct ieee80211_frame *owh, *wh;
546 : struct ieee80211_defrag *df;
547 : u_int16_t rxseq, seq;
548 : u_int8_t frag;
549 : int i;
550 :
551 0 : wh = mtod(m, struct ieee80211_frame *);
552 0 : rxseq = letoh16(*(const u_int16_t *)wh->i_seq);
553 0 : seq = rxseq >> IEEE80211_SEQ_SEQ_SHIFT;
554 0 : frag = rxseq & IEEE80211_SEQ_FRAG_MASK;
555 :
556 0 : if (frag == 0 && !(wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG))
557 0 : return m; /* not fragmented */
558 :
559 0 : if (frag == 0) {
560 : /* first fragment, setup entry in the fragment cache */
561 0 : if (++ic->ic_defrag_cur == IEEE80211_DEFRAG_SIZE)
562 0 : ic->ic_defrag_cur = 0;
563 0 : df = &ic->ic_defrag[ic->ic_defrag_cur];
564 0 : m_freem(df->df_m); /* discard old entry */
565 0 : df->df_seq = seq;
566 0 : df->df_frag = 0;
567 0 : df->df_m = m;
568 : /* start receive MSDU timer of aMaxReceiveLifetime */
569 0 : timeout_add_sec(&df->df_to, 1);
570 0 : return NULL; /* MSDU or MMPDU not yet complete */
571 : }
572 :
573 : /* find matching entry in the fragment cache */
574 0 : for (i = 0; i < IEEE80211_DEFRAG_SIZE; i++) {
575 0 : df = &ic->ic_defrag[i];
576 0 : if (df->df_m == NULL)
577 : continue;
578 0 : if (df->df_seq != seq || df->df_frag + 1 != frag)
579 : continue;
580 0 : owh = mtod(df->df_m, struct ieee80211_frame *);
581 : /* frame type, source and destination must match */
582 0 : if (((wh->i_fc[0] ^ owh->i_fc[0]) & IEEE80211_FC0_TYPE_MASK) ||
583 0 : !IEEE80211_ADDR_EQ(wh->i_addr1, owh->i_addr1) ||
584 0 : !IEEE80211_ADDR_EQ(wh->i_addr2, owh->i_addr2))
585 : continue;
586 : /* matching entry found */
587 : break;
588 : }
589 0 : if (i == IEEE80211_DEFRAG_SIZE) {
590 : /* no matching entry found, discard fragment */
591 0 : ic->ic_if.if_ierrors++;
592 0 : m_freem(m);
593 0 : return NULL;
594 : }
595 :
596 0 : df->df_frag = frag;
597 : /* strip 802.11 header and concatenate fragment */
598 0 : m_adj(m, hdrlen);
599 0 : m_cat(df->df_m, m);
600 0 : df->df_m->m_pkthdr.len += m->m_pkthdr.len;
601 :
602 0 : if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
603 0 : return NULL; /* MSDU or MMPDU not yet complete */
604 :
605 : /* MSDU or MMPDU complete */
606 0 : timeout_del(&df->df_to);
607 0 : m = df->df_m;
608 0 : df->df_m = NULL;
609 0 : return m;
610 0 : }
611 :
612 : /*
613 : * Receive MSDU defragmentation timer exceeds aMaxReceiveLifetime.
614 : */
615 : void
616 0 : ieee80211_defrag_timeout(void *arg)
617 : {
618 0 : struct ieee80211_defrag *df = arg;
619 0 : int s = splnet();
620 :
621 : /* discard all received fragments */
622 0 : m_freem(df->df_m);
623 0 : df->df_m = NULL;
624 :
625 0 : splx(s);
626 0 : }
627 :
628 : /*
629 : * Process a received data MPDU related to a specific HT-immediate Block Ack
630 : * agreement (see 9.10.7.6).
631 : */
632 : void
633 0 : ieee80211_input_ba(struct ieee80211com *ic, struct mbuf *m,
634 : struct ieee80211_node *ni, int tid, struct ieee80211_rxinfo *rxi)
635 : {
636 0 : struct ifnet *ifp = &ic->ic_if;
637 0 : struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
638 : struct ieee80211_frame *wh;
639 : int idx, count;
640 : u_int16_t sn;
641 :
642 0 : wh = mtod(m, struct ieee80211_frame *);
643 0 : sn = letoh16(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
644 :
645 : /* reset Block Ack inactivity timer */
646 0 : if (ba->ba_timeout_val != 0)
647 0 : timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
648 :
649 0 : if (SEQ_LT(sn, ba->ba_winstart)) { /* SN < WinStartB */
650 0 : ic->ic_stats.is_ht_rx_frame_below_ba_winstart++;
651 0 : m_freem(m); /* discard the MPDU */
652 0 : return;
653 : }
654 0 : if (SEQ_LT(ba->ba_winend, sn)) { /* WinEndB < SN */
655 0 : ic->ic_stats.is_ht_rx_frame_above_ba_winend++;
656 0 : count = (sn - ba->ba_winend) & 0xfff;
657 0 : if (count > ba->ba_winsize) {
658 : /*
659 : * Check whether we're consistently behind the window,
660 : * and let the window move forward if neccessary.
661 : */
662 0 : if (ba->ba_winmiss < IEEE80211_BA_MAX_WINMISS) {
663 0 : if (ba->ba_missedsn == ((sn - 1) & 0xfff))
664 0 : ba->ba_winmiss++;
665 : else
666 0 : ba->ba_winmiss = 0;
667 0 : ba->ba_missedsn = sn;
668 0 : ifp->if_ierrors++;
669 0 : m_freem(m); /* discard the MPDU */
670 0 : return;
671 : }
672 :
673 : /* It appears the window has moved for real. */
674 0 : ic->ic_stats.is_ht_rx_ba_window_jump++;
675 0 : ba->ba_winmiss = 0;
676 0 : ba->ba_missedsn = 0;
677 0 : ieee80211_ba_move_window(ic, ni, tid, sn);
678 0 : } else {
679 0 : ic->ic_stats.is_ht_rx_ba_window_slide++;
680 0 : ieee80211_input_ba_seq(ic, ni, tid,
681 0 : (ba->ba_winstart + count) & 0xfff);
682 0 : ieee80211_input_ba_flush(ic, ni, ba);
683 : }
684 : }
685 : /* WinStartB <= SN <= WinEndB */
686 :
687 0 : ba->ba_winmiss = 0;
688 0 : ba->ba_missedsn = 0;
689 0 : idx = (sn - ba->ba_winstart) & 0xfff;
690 0 : idx = (ba->ba_head + idx) % IEEE80211_BA_MAX_WINSZ;
691 : /* store the received MPDU in the buffer */
692 0 : if (ba->ba_buf[idx].m != NULL) {
693 0 : ifp->if_ierrors++;
694 0 : ic->ic_stats.is_ht_rx_ba_no_buf++;
695 0 : m_freem(m);
696 0 : return;
697 : }
698 0 : ba->ba_buf[idx].m = m;
699 : /* store Rx meta-data too */
700 0 : rxi->rxi_flags |= IEEE80211_RXI_AMPDU_DONE;
701 0 : ba->ba_buf[idx].rxi = *rxi;
702 :
703 0 : if (ba->ba_buf[ba->ba_head].m == NULL)
704 0 : timeout_add_msec(&ba->ba_gap_to, IEEE80211_BA_GAP_TIMEOUT);
705 0 : else if (timeout_pending(&ba->ba_gap_to))
706 0 : timeout_del(&ba->ba_gap_to);
707 :
708 0 : ieee80211_input_ba_flush(ic, ni, ba);
709 0 : }
710 :
711 : /*
712 : * Forward buffered frames with sequence number lower than max_seq.
713 : * See 802.11-2012 9.21.7.6.2 b.
714 : */
715 : void
716 0 : ieee80211_input_ba_seq(struct ieee80211com *ic, struct ieee80211_node *ni,
717 : uint8_t tid, uint16_t max_seq)
718 : {
719 0 : struct ifnet *ifp = &ic->ic_if;
720 0 : struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
721 : struct ieee80211_frame *wh;
722 : uint16_t seq;
723 : int i = 0;
724 :
725 0 : while (i++ < ba->ba_winsize) {
726 : /* gaps may exist */
727 0 : if (ba->ba_buf[ba->ba_head].m != NULL) {
728 0 : wh = mtod(ba->ba_buf[ba->ba_head].m,
729 : struct ieee80211_frame *);
730 0 : KASSERT(ieee80211_has_seq(wh));
731 0 : seq = letoh16(*(u_int16_t *)wh->i_seq) >>
732 : IEEE80211_SEQ_SEQ_SHIFT;
733 0 : if (!SEQ_LT(seq, max_seq))
734 0 : return;
735 0 : ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m,
736 0 : ni, &ba->ba_buf[ba->ba_head].rxi);
737 0 : ba->ba_buf[ba->ba_head].m = NULL;
738 0 : } else
739 0 : ic->ic_stats.is_ht_rx_ba_frame_lost++;
740 0 : ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
741 : }
742 0 : }
743 :
744 : /* Flush a consecutive sequence of frames from the reorder buffer. */
745 : void
746 0 : ieee80211_input_ba_flush(struct ieee80211com *ic, struct ieee80211_node *ni,
747 : struct ieee80211_rx_ba *ba)
748 :
749 : {
750 0 : struct ifnet *ifp = &ic->ic_if;
751 :
752 : /* pass reordered MPDUs up to the next MAC process */
753 0 : while (ba->ba_buf[ba->ba_head].m != NULL) {
754 0 : ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m, ni,
755 0 : &ba->ba_buf[ba->ba_head].rxi);
756 0 : ba->ba_buf[ba->ba_head].m = NULL;
757 :
758 0 : ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
759 : /* move window forward */
760 0 : ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
761 : }
762 0 : ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
763 0 : }
764 :
765 : /*
766 : * Forcibly move the BA window forward to remove a leading gap which has
767 : * been causing frames to linger in the reordering buffer for too long.
768 : * A leading gap will occur if a particular A-MPDU subframe never arrives
769 : * or if a bug in the sender causes sequence numbers to jump forward by > 1.
770 : */
771 : void
772 0 : ieee80211_input_ba_gap_timeout(void *arg)
773 : {
774 0 : struct ieee80211_rx_ba *ba = arg;
775 0 : struct ieee80211_node *ni = ba->ba_ni;
776 0 : struct ieee80211com *ic = ni->ni_ic;
777 : int s, skipped;
778 :
779 0 : ic->ic_stats.is_ht_rx_ba_window_gap_timeout++;
780 :
781 0 : s = splnet();
782 :
783 : skipped = 0;
784 0 : while (skipped < ba->ba_winsize && ba->ba_buf[ba->ba_head].m == NULL) {
785 : /* move window forward */
786 0 : ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
787 0 : ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
788 0 : skipped++;
789 0 : ic->ic_stats.is_ht_rx_ba_frame_lost++;
790 : }
791 0 : if (skipped > 0)
792 0 : ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
793 :
794 0 : ieee80211_input_ba_flush(ic, ni, ba);
795 :
796 0 : splx(s);
797 0 : }
798 :
799 :
800 : /*
801 : * Change the value of WinStartB (move window forward) upon reception of a
802 : * BlockAckReq frame or an ADDBA Request (PBAC).
803 : */
804 : void
805 0 : ieee80211_ba_move_window(struct ieee80211com *ic, struct ieee80211_node *ni,
806 : u_int8_t tid, u_int16_t ssn)
807 : {
808 0 : struct ifnet *ifp = &ic->ic_if;
809 0 : struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
810 : int count;
811 :
812 : /* assert(WinStartB <= SSN) */
813 :
814 0 : count = (ssn - ba->ba_winstart) & 0xfff;
815 0 : if (count > ba->ba_winsize) /* no overlap */
816 0 : count = ba->ba_winsize;
817 0 : while (count-- > 0) {
818 : /* gaps may exist */
819 0 : if (ba->ba_buf[ba->ba_head].m != NULL) {
820 0 : ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m, ni,
821 0 : &ba->ba_buf[ba->ba_head].rxi);
822 0 : ba->ba_buf[ba->ba_head].m = NULL;
823 0 : } else
824 0 : ic->ic_stats.is_ht_rx_ba_frame_lost++;
825 0 : ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
826 : }
827 : /* move window forward */
828 0 : ba->ba_winstart = ssn;
829 :
830 0 : ieee80211_input_ba_flush(ic, ni, ba);
831 0 : }
832 :
833 : void
834 0 : ieee80211_deliver_data(struct ieee80211com *ic, struct mbuf *m,
835 : struct ieee80211_node *ni, int mcast)
836 : {
837 0 : struct ifnet *ifp = &ic->ic_if;
838 : struct ether_header *eh;
839 : struct mbuf *m1;
840 :
841 0 : eh = mtod(m, struct ether_header *);
842 :
843 0 : if ((ic->ic_flags & IEEE80211_F_RSNON) && !ni->ni_port_valid &&
844 0 : eh->ether_type != htons(ETHERTYPE_PAE)) {
845 : DPRINTF(("port not valid: %s\n",
846 : ether_sprintf(eh->ether_dhost)));
847 0 : ic->ic_stats.is_rx_unauth++;
848 0 : m_freem(m);
849 0 : return;
850 : }
851 :
852 : /*
853 : * Perform as a bridge within the AP. Notice that we do not
854 : * bridge EAPOL frames as suggested in C.1.1 of IEEE Std 802.1X.
855 : * And we do not forward unicast frames received on a multicast address.
856 : */
857 : m1 = NULL;
858 : #ifndef IEEE80211_STA_ONLY
859 0 : if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
860 0 : !(ic->ic_flags & IEEE80211_F_NOBRIDGE) &&
861 0 : eh->ether_type != htons(ETHERTYPE_PAE)) {
862 : struct ieee80211_node *ni1;
863 :
864 0 : if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
865 0 : m1 = m_dup_pkt(m, ETHER_ALIGN, M_DONTWAIT);
866 0 : if (m1 == NULL)
867 0 : ifp->if_oerrors++;
868 : else
869 0 : m1->m_flags |= M_MCAST;
870 0 : } else if (!mcast) {
871 0 : ni1 = ieee80211_find_node(ic, eh->ether_dhost);
872 0 : if (ni1 != NULL &&
873 0 : ni1->ni_state == IEEE80211_STA_ASSOC) {
874 : m1 = m;
875 : m = NULL;
876 0 : }
877 : }
878 0 : if (m1 != NULL) {
879 0 : if (if_enqueue(ifp, m1))
880 0 : ifp->if_oerrors++;
881 : }
882 0 : }
883 : #endif
884 0 : if (m != NULL) {
885 0 : if ((ic->ic_flags & IEEE80211_F_RSNON) &&
886 0 : eh->ether_type == htons(ETHERTYPE_PAE)) {
887 0 : ifp->if_ipackets++;
888 : #if NBPFILTER > 0
889 : /*
890 : * If we forward frame into transmitter of the AP,
891 : * we don't need to duplicate for DLT_EN10MB.
892 : */
893 0 : if (ifp->if_bpf && m1 == NULL)
894 0 : bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
895 : #endif
896 0 : ieee80211_eapol_key_input(ic, m, ni);
897 0 : } else {
898 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
899 0 : ml_enqueue(&ml, m);
900 0 : if_input(ifp, &ml);
901 0 : }
902 : }
903 0 : }
904 :
905 : void
906 0 : ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
907 : struct ieee80211_node *ni, int hdrlen)
908 : {
909 0 : struct ether_header eh;
910 : struct ieee80211_frame *wh;
911 : struct llc *llc;
912 : int mcast;
913 :
914 0 : if (m->m_len < hdrlen + LLC_SNAPFRAMELEN &&
915 0 : (m = m_pullup(m, hdrlen + LLC_SNAPFRAMELEN)) == NULL) {
916 0 : ic->ic_stats.is_rx_decap++;
917 0 : return;
918 : }
919 0 : wh = mtod(m, struct ieee80211_frame *);
920 0 : mcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
921 0 : switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
922 : case IEEE80211_FC1_DIR_NODS:
923 0 : IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1);
924 0 : IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2);
925 0 : break;
926 : case IEEE80211_FC1_DIR_TODS:
927 0 : IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3);
928 0 : IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2);
929 0 : break;
930 : case IEEE80211_FC1_DIR_FROMDS:
931 0 : IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1);
932 0 : IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr3);
933 0 : break;
934 : case IEEE80211_FC1_DIR_DSTODS:
935 0 : IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3);
936 0 : IEEE80211_ADDR_COPY(eh.ether_shost,
937 : ((struct ieee80211_frame_addr4 *)wh)->i_addr4);
938 0 : break;
939 : }
940 0 : llc = (struct llc *)((caddr_t)wh + hdrlen);
941 0 : if (llc->llc_dsap == LLC_SNAP_LSAP &&
942 0 : llc->llc_ssap == LLC_SNAP_LSAP &&
943 0 : llc->llc_control == LLC_UI &&
944 0 : llc->llc_snap.org_code[0] == 0 &&
945 0 : llc->llc_snap.org_code[1] == 0 &&
946 0 : llc->llc_snap.org_code[2] == 0) {
947 0 : eh.ether_type = llc->llc_snap.ether_type;
948 0 : m_adj(m, hdrlen + LLC_SNAPFRAMELEN - ETHER_HDR_LEN);
949 0 : } else {
950 0 : eh.ether_type = htons(m->m_pkthdr.len - hdrlen);
951 0 : m_adj(m, hdrlen - ETHER_HDR_LEN);
952 : }
953 0 : memcpy(mtod(m, caddr_t), &eh, ETHER_HDR_LEN);
954 : if (!ALIGNED_POINTER(mtod(m, caddr_t) + ETHER_HDR_LEN, u_int32_t)) {
955 : struct mbuf *m0 = m;
956 : m = m_dup_pkt(m0, ETHER_ALIGN, M_NOWAIT);
957 : m_freem(m0);
958 : if (m == NULL) {
959 : ic->ic_stats.is_rx_decap++;
960 : return;
961 : }
962 : }
963 0 : ieee80211_deliver_data(ic, m, ni, mcast);
964 0 : }
965 :
966 : /*
967 : * Decapsulate an Aggregate MSDU (see 7.2.2.2).
968 : */
969 : void
970 0 : ieee80211_amsdu_decap(struct ieee80211com *ic, struct mbuf *m,
971 : struct ieee80211_node *ni, int hdrlen)
972 : {
973 : struct mbuf *n;
974 : struct ether_header *eh;
975 : struct llc *llc;
976 : int len, pad, mcast;
977 : struct ieee80211_frame *wh;
978 :
979 0 : wh = mtod(m, struct ieee80211_frame *);
980 0 : mcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
981 :
982 : /* strip 802.11 header */
983 0 : m_adj(m, hdrlen);
984 :
985 0 : for (;;) {
986 : /* process an A-MSDU subframe */
987 0 : if (m->m_len < ETHER_HDR_LEN + LLC_SNAPFRAMELEN) {
988 0 : m = m_pullup(m, ETHER_HDR_LEN + LLC_SNAPFRAMELEN);
989 0 : if (m == NULL) {
990 0 : ic->ic_stats.is_rx_decap++;
991 0 : break;
992 : }
993 : }
994 0 : eh = mtod(m, struct ether_header *);
995 : /* examine 802.3 header */
996 0 : len = ntohs(eh->ether_type);
997 0 : if (len < LLC_SNAPFRAMELEN) {
998 : DPRINTF(("A-MSDU subframe too short (%d)\n", len));
999 : /* stop processing A-MSDU subframes */
1000 0 : ic->ic_stats.is_rx_decap++;
1001 0 : m_freem(m);
1002 0 : break;
1003 : }
1004 0 : llc = (struct llc *)&eh[1];
1005 : /* examine 802.2 LLC header */
1006 0 : if (llc->llc_dsap == LLC_SNAP_LSAP &&
1007 0 : llc->llc_ssap == LLC_SNAP_LSAP &&
1008 0 : llc->llc_control == LLC_UI &&
1009 0 : llc->llc_snap.org_code[0] == 0 &&
1010 0 : llc->llc_snap.org_code[1] == 0 &&
1011 0 : llc->llc_snap.org_code[2] == 0) {
1012 : /* convert to Ethernet II header */
1013 0 : eh->ether_type = llc->llc_snap.ether_type;
1014 : /* strip LLC+SNAP headers */
1015 0 : memmove((u_int8_t *)eh + LLC_SNAPFRAMELEN, eh,
1016 : ETHER_HDR_LEN);
1017 0 : m_adj(m, LLC_SNAPFRAMELEN);
1018 0 : len -= LLC_SNAPFRAMELEN;
1019 0 : }
1020 0 : len += ETHER_HDR_LEN;
1021 0 : if (len > m->m_pkthdr.len) {
1022 : /* stop processing A-MSDU subframes */
1023 : DPRINTF(("A-MSDU subframe too long (%d)\n", len));
1024 0 : ic->ic_stats.is_rx_decap++;
1025 0 : m_freem(m);
1026 0 : break;
1027 : }
1028 :
1029 : /* "detach" our A-MSDU subframe from the others */
1030 0 : n = m_split(m, len, M_NOWAIT);
1031 0 : if (n == NULL) {
1032 : /* stop processing A-MSDU subframes */
1033 0 : ic->ic_stats.is_rx_decap++;
1034 0 : m_freem(m);
1035 0 : break;
1036 : }
1037 0 : ieee80211_deliver_data(ic, m, ni, mcast);
1038 :
1039 0 : if (n->m_pkthdr.len == 0) {
1040 0 : m_freem(n);
1041 0 : break;
1042 : }
1043 : m = n;
1044 : /* remove padding */
1045 0 : pad = ((len + 3) & ~3) - len;
1046 0 : m_adj(m, pad);
1047 : }
1048 0 : }
1049 :
1050 : /*
1051 : * Parse an EDCA Parameter Set element (see 7.3.2.27).
1052 : */
1053 : int
1054 0 : ieee80211_parse_edca_params_body(struct ieee80211com *ic, const u_int8_t *frm)
1055 : {
1056 : u_int updtcount;
1057 : int aci;
1058 :
1059 : /*
1060 : * Check if EDCA parameters have changed XXX if we miss more than
1061 : * 15 consecutive beacons, we might not detect changes to EDCA
1062 : * parameters due to wraparound of the 4-bit Update Count field.
1063 : */
1064 0 : updtcount = frm[0] & 0xf;
1065 0 : if (updtcount == ic->ic_edca_updtcount)
1066 0 : return 0; /* no changes to EDCA parameters, ignore */
1067 0 : ic->ic_edca_updtcount = updtcount;
1068 :
1069 0 : frm += 2; /* skip QoS Info & Reserved fields */
1070 :
1071 : /* parse AC Parameter Records */
1072 0 : for (aci = 0; aci < EDCA_NUM_AC; aci++) {
1073 0 : struct ieee80211_edca_ac_params *ac = &ic->ic_edca_ac[aci];
1074 :
1075 0 : ac->ac_acm = (frm[0] >> 4) & 0x1;
1076 0 : ac->ac_aifsn = frm[0] & 0xf;
1077 0 : ac->ac_ecwmin = frm[1] & 0xf;
1078 0 : ac->ac_ecwmax = frm[1] >> 4;
1079 0 : ac->ac_txoplimit = LE_READ_2(frm + 2);
1080 0 : frm += 4;
1081 : }
1082 : /* give drivers a chance to update their settings */
1083 0 : if ((ic->ic_flags & IEEE80211_F_QOS) && ic->ic_updateedca != NULL)
1084 0 : (*ic->ic_updateedca)(ic);
1085 :
1086 0 : return 0;
1087 0 : }
1088 :
1089 : int
1090 0 : ieee80211_parse_edca_params(struct ieee80211com *ic, const u_int8_t *frm)
1091 : {
1092 0 : if (frm[1] < 18) {
1093 0 : ic->ic_stats.is_rx_elem_toosmall++;
1094 0 : return IEEE80211_REASON_IE_INVALID;
1095 : }
1096 0 : return ieee80211_parse_edca_params_body(ic, frm + 2);
1097 0 : }
1098 :
1099 : int
1100 0 : ieee80211_parse_wmm_params(struct ieee80211com *ic, const u_int8_t *frm)
1101 : {
1102 0 : if (frm[1] < 24) {
1103 0 : ic->ic_stats.is_rx_elem_toosmall++;
1104 0 : return IEEE80211_REASON_IE_INVALID;
1105 : }
1106 0 : return ieee80211_parse_edca_params_body(ic, frm + 8);
1107 0 : }
1108 :
1109 : enum ieee80211_cipher
1110 0 : ieee80211_parse_rsn_cipher(const u_int8_t selector[4])
1111 : {
1112 0 : if (memcmp(selector, MICROSOFT_OUI, 3) == 0) { /* WPA */
1113 0 : switch (selector[3]) {
1114 : case 0: /* use group data cipher suite */
1115 0 : return IEEE80211_CIPHER_USEGROUP;
1116 : case 1: /* WEP-40 */
1117 0 : return IEEE80211_CIPHER_WEP40;
1118 : case 2: /* TKIP */
1119 0 : return IEEE80211_CIPHER_TKIP;
1120 : case 4: /* CCMP (RSNA default) */
1121 0 : return IEEE80211_CIPHER_CCMP;
1122 : case 5: /* WEP-104 */
1123 0 : return IEEE80211_CIPHER_WEP104;
1124 : }
1125 0 : } else if (memcmp(selector, IEEE80211_OUI, 3) == 0) { /* RSN */
1126 : /* see 802.11-2012 Table 8-99 */
1127 0 : switch (selector[3]) {
1128 : case 0: /* use group data cipher suite */
1129 0 : return IEEE80211_CIPHER_USEGROUP;
1130 : case 1: /* WEP-40 */
1131 0 : return IEEE80211_CIPHER_WEP40;
1132 : case 2: /* TKIP */
1133 0 : return IEEE80211_CIPHER_TKIP;
1134 : case 4: /* CCMP (RSNA default) */
1135 0 : return IEEE80211_CIPHER_CCMP;
1136 : case 5: /* WEP-104 */
1137 0 : return IEEE80211_CIPHER_WEP104;
1138 : case 6: /* BIP */
1139 0 : return IEEE80211_CIPHER_BIP;
1140 : }
1141 : }
1142 0 : return IEEE80211_CIPHER_NONE; /* ignore unknown ciphers */
1143 0 : }
1144 :
1145 : enum ieee80211_akm
1146 0 : ieee80211_parse_rsn_akm(const u_int8_t selector[4])
1147 : {
1148 0 : if (memcmp(selector, MICROSOFT_OUI, 3) == 0) { /* WPA */
1149 0 : switch (selector[3]) {
1150 : case 1: /* IEEE 802.1X (RSNA default) */
1151 0 : return IEEE80211_AKM_8021X;
1152 : case 2: /* PSK */
1153 0 : return IEEE80211_AKM_PSK;
1154 : }
1155 0 : } else if (memcmp(selector, IEEE80211_OUI, 3) == 0) { /* RSN */
1156 : /* from IEEE Std 802.11i-2004 - Table 20dc */
1157 0 : switch (selector[3]) {
1158 : case 1: /* IEEE 802.1X (RSNA default) */
1159 0 : return IEEE80211_AKM_8021X;
1160 : case 2: /* PSK */
1161 0 : return IEEE80211_AKM_PSK;
1162 : case 5: /* IEEE 802.1X with SHA256 KDF */
1163 0 : return IEEE80211_AKM_SHA256_8021X;
1164 : case 6: /* PSK with SHA256 KDF */
1165 0 : return IEEE80211_AKM_SHA256_PSK;
1166 : }
1167 : }
1168 0 : return IEEE80211_AKM_NONE; /* ignore unknown AKMs */
1169 0 : }
1170 :
1171 : /*
1172 : * Parse an RSN element (see 802.11-2012 8.4.2.27)
1173 : */
1174 : int
1175 0 : ieee80211_parse_rsn_body(struct ieee80211com *ic, const u_int8_t *frm,
1176 : u_int len, struct ieee80211_rsnparams *rsn)
1177 : {
1178 : const u_int8_t *efrm;
1179 : u_int16_t m, n, s;
1180 :
1181 0 : efrm = frm + len;
1182 :
1183 : /* check Version field */
1184 0 : if (LE_READ_2(frm) != 1)
1185 0 : return IEEE80211_STATUS_RSN_IE_VER_UNSUP;
1186 0 : frm += 2;
1187 :
1188 : /* all fields after the Version field are optional */
1189 :
1190 : /* if Cipher Suite missing, default to CCMP */
1191 0 : rsn->rsn_groupcipher = IEEE80211_CIPHER_CCMP;
1192 0 : rsn->rsn_nciphers = 1;
1193 0 : rsn->rsn_ciphers = IEEE80211_CIPHER_CCMP;
1194 : /* if Group Management Cipher Suite missing, defaut to BIP */
1195 0 : rsn->rsn_groupmgmtcipher = IEEE80211_CIPHER_BIP;
1196 : /* if AKM Suite missing, default to 802.1X */
1197 0 : rsn->rsn_nakms = 1;
1198 0 : rsn->rsn_akms = IEEE80211_AKM_8021X;
1199 : /* if RSN capabilities missing, default to 0 */
1200 0 : rsn->rsn_caps = 0;
1201 0 : rsn->rsn_npmkids = 0;
1202 :
1203 : /* read Group Data Cipher Suite field */
1204 0 : if (frm + 4 > efrm)
1205 0 : return 0;
1206 0 : rsn->rsn_groupcipher = ieee80211_parse_rsn_cipher(frm);
1207 0 : if (rsn->rsn_groupcipher == IEEE80211_CIPHER_NONE ||
1208 0 : rsn->rsn_groupcipher == IEEE80211_CIPHER_USEGROUP ||
1209 0 : rsn->rsn_groupcipher == IEEE80211_CIPHER_BIP)
1210 0 : return IEEE80211_STATUS_BAD_GROUP_CIPHER;
1211 : frm += 4;
1212 :
1213 : /* read Pairwise Cipher Suite Count field */
1214 0 : if (frm + 2 > efrm)
1215 0 : return 0;
1216 0 : m = rsn->rsn_nciphers = LE_READ_2(frm);
1217 : frm += 2;
1218 :
1219 : /* read Pairwise Cipher Suite List */
1220 0 : if (frm + m * 4 > efrm)
1221 0 : return IEEE80211_STATUS_IE_INVALID;
1222 0 : rsn->rsn_ciphers = IEEE80211_CIPHER_NONE;
1223 0 : while (m-- > 0) {
1224 0 : rsn->rsn_ciphers |= ieee80211_parse_rsn_cipher(frm);
1225 0 : frm += 4;
1226 : }
1227 0 : if (rsn->rsn_ciphers & IEEE80211_CIPHER_USEGROUP) {
1228 0 : if (rsn->rsn_ciphers != IEEE80211_CIPHER_USEGROUP)
1229 0 : return IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
1230 0 : if (rsn->rsn_groupcipher == IEEE80211_CIPHER_CCMP)
1231 0 : return IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
1232 : }
1233 :
1234 : /* read AKM Suite List Count field */
1235 0 : if (frm + 2 > efrm)
1236 0 : return 0;
1237 0 : n = rsn->rsn_nakms = LE_READ_2(frm);
1238 : frm += 2;
1239 :
1240 : /* read AKM Suite List */
1241 0 : if (frm + n * 4 > efrm)
1242 0 : return IEEE80211_STATUS_IE_INVALID;
1243 0 : rsn->rsn_akms = IEEE80211_AKM_NONE;
1244 0 : while (n-- > 0) {
1245 0 : rsn->rsn_akms |= ieee80211_parse_rsn_akm(frm);
1246 0 : frm += 4;
1247 : }
1248 :
1249 : /* read RSN Capabilities field */
1250 0 : if (frm + 2 > efrm)
1251 0 : return 0;
1252 0 : rsn->rsn_caps = LE_READ_2(frm);
1253 : frm += 2;
1254 :
1255 : /* read PMKID Count field */
1256 0 : if (frm + 2 > efrm)
1257 0 : return 0;
1258 0 : s = rsn->rsn_npmkids = LE_READ_2(frm);
1259 : frm += 2;
1260 :
1261 : /* read PMKID List */
1262 0 : if (frm + s * IEEE80211_PMKID_LEN > efrm)
1263 0 : return IEEE80211_STATUS_IE_INVALID;
1264 0 : if (s != 0) {
1265 0 : rsn->rsn_pmkids = frm;
1266 : frm += s * IEEE80211_PMKID_LEN;
1267 0 : }
1268 :
1269 : /* read Group Management Cipher Suite field */
1270 0 : if (frm + 4 > efrm)
1271 0 : return 0;
1272 0 : rsn->rsn_groupmgmtcipher = ieee80211_parse_rsn_cipher(frm);
1273 0 : if (rsn->rsn_groupmgmtcipher != IEEE80211_CIPHER_BIP)
1274 0 : return IEEE80211_STATUS_BAD_GROUP_CIPHER;
1275 :
1276 0 : return IEEE80211_STATUS_SUCCESS;
1277 0 : }
1278 :
1279 : int
1280 0 : ieee80211_parse_rsn(struct ieee80211com *ic, const u_int8_t *frm,
1281 : struct ieee80211_rsnparams *rsn)
1282 : {
1283 0 : if (frm[1] < 2) {
1284 0 : ic->ic_stats.is_rx_elem_toosmall++;
1285 0 : return IEEE80211_STATUS_IE_INVALID;
1286 : }
1287 0 : return ieee80211_parse_rsn_body(ic, frm + 2, frm[1], rsn);
1288 0 : }
1289 :
1290 : int
1291 0 : ieee80211_parse_wpa(struct ieee80211com *ic, const u_int8_t *frm,
1292 : struct ieee80211_rsnparams *rsn)
1293 : {
1294 0 : if (frm[1] < 6) {
1295 0 : ic->ic_stats.is_rx_elem_toosmall++;
1296 0 : return IEEE80211_STATUS_IE_INVALID;
1297 : }
1298 0 : return ieee80211_parse_rsn_body(ic, frm + 6, frm[1] - 4, rsn);
1299 0 : }
1300 :
1301 : /*
1302 : * Create (or update) a copy of an information element.
1303 : */
1304 : int
1305 0 : ieee80211_save_ie(const u_int8_t *frm, u_int8_t **ie)
1306 : {
1307 0 : int olen = *ie ? 2 + (*ie)[1] : 0;
1308 0 : int len = 2 + frm[1];
1309 :
1310 0 : if (*ie == NULL || olen != len) {
1311 0 : if (*ie != NULL)
1312 0 : free(*ie, M_DEVBUF, olen);
1313 0 : *ie = malloc(len, M_DEVBUF, M_NOWAIT);
1314 0 : if (*ie == NULL)
1315 0 : return ENOMEM;
1316 : }
1317 0 : memcpy(*ie, frm, len);
1318 0 : return 0;
1319 0 : }
1320 :
1321 : /*-
1322 : * Beacon/Probe response frame format:
1323 : * [8] Timestamp
1324 : * [2] Beacon interval
1325 : * [2] Capability
1326 : * [tlv] Service Set Identifier (SSID)
1327 : * [tlv] Supported rates
1328 : * [tlv] DS Parameter Set (802.11g)
1329 : * [tlv] ERP Information (802.11g)
1330 : * [tlv] Extended Supported Rates (802.11g)
1331 : * [tlv] RSN (802.11i)
1332 : * [tlv] EDCA Parameter Set (802.11e)
1333 : * [tlv] QoS Capability (Beacon only, 802.11e)
1334 : * [tlv] HT Capabilities (802.11n)
1335 : * [tlv] HT Operation (802.11n)
1336 : */
1337 : void
1338 0 : ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
1339 : struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int isprobe)
1340 : {
1341 : const struct ieee80211_frame *wh;
1342 : const u_int8_t *frm, *efrm;
1343 : const u_int8_t *tstamp, *ssid, *rates, *xrates, *edcaie, *wmmie;
1344 : const u_int8_t *rsnie, *wpaie, *htcaps, *htop;
1345 : u_int16_t capinfo, bintval;
1346 : u_int8_t chan, bchan, erp, dtim_count, dtim_period;
1347 : int is_new;
1348 :
1349 : /*
1350 : * We process beacon/probe response frames for:
1351 : * o station mode: to collect state
1352 : * updates such as 802.11g slot time and for passive
1353 : * scanning of APs
1354 : * o adhoc mode: to discover neighbors
1355 : * o hostap mode: for passive scanning of neighbor APs
1356 : * o when scanning
1357 : * In other words, in all modes other than monitor (which
1358 : * does not process incoming frames) and adhoc-demo (which
1359 : * does not use management frames at all).
1360 : */
1361 : #ifdef DIAGNOSTIC
1362 0 : if (ic->ic_opmode != IEEE80211_M_STA &&
1363 : #ifndef IEEE80211_STA_ONLY
1364 0 : ic->ic_opmode != IEEE80211_M_IBSS &&
1365 0 : ic->ic_opmode != IEEE80211_M_HOSTAP &&
1366 : #endif
1367 0 : ic->ic_state != IEEE80211_S_SCAN) {
1368 0 : panic("%s: impossible operating mode", __func__);
1369 : }
1370 : #endif
1371 : /* make sure all mandatory fixed fields are present */
1372 0 : if (m->m_len < sizeof(*wh) + 12) {
1373 : DPRINTF(("frame too short\n"));
1374 0 : return;
1375 : }
1376 0 : wh = mtod(m, struct ieee80211_frame *);
1377 0 : frm = (const u_int8_t *)&wh[1];
1378 0 : efrm = mtod(m, u_int8_t *) + m->m_len;
1379 :
1380 0 : tstamp = frm; frm += 8;
1381 0 : bintval = LE_READ_2(frm); frm += 2;
1382 0 : capinfo = LE_READ_2(frm); frm += 2;
1383 :
1384 : ssid = rates = xrates = edcaie = wmmie = rsnie = wpaie = NULL;
1385 : htcaps = htop = NULL;
1386 0 : bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1387 : chan = bchan;
1388 : erp = 0;
1389 : dtim_count = dtim_period = 0;
1390 0 : while (frm + 2 <= efrm) {
1391 0 : if (frm + 2 + frm[1] > efrm) {
1392 0 : ic->ic_stats.is_rx_elem_toosmall++;
1393 0 : break;
1394 : }
1395 0 : switch (frm[0]) {
1396 : case IEEE80211_ELEMID_SSID:
1397 : ssid = frm;
1398 0 : break;
1399 : case IEEE80211_ELEMID_RATES:
1400 : rates = frm;
1401 0 : break;
1402 : case IEEE80211_ELEMID_DSPARMS:
1403 0 : if (frm[1] < 1) {
1404 0 : ic->ic_stats.is_rx_elem_toosmall++;
1405 0 : break;
1406 : }
1407 0 : chan = frm[2];
1408 0 : break;
1409 : case IEEE80211_ELEMID_XRATES:
1410 : xrates = frm;
1411 0 : break;
1412 : case IEEE80211_ELEMID_ERP:
1413 0 : if (frm[1] < 1) {
1414 0 : ic->ic_stats.is_rx_elem_toosmall++;
1415 0 : break;
1416 : }
1417 0 : erp = frm[2];
1418 0 : break;
1419 : case IEEE80211_ELEMID_RSN:
1420 : rsnie = frm;
1421 0 : break;
1422 : case IEEE80211_ELEMID_EDCAPARMS:
1423 : edcaie = frm;
1424 0 : break;
1425 : case IEEE80211_ELEMID_HTCAPS:
1426 : htcaps = frm;
1427 0 : break;
1428 : case IEEE80211_ELEMID_HTOP:
1429 : htop = frm;
1430 0 : break;
1431 : case IEEE80211_ELEMID_TIM:
1432 0 : if (frm[1] > 3) {
1433 0 : dtim_count = frm[2];
1434 0 : dtim_period = frm[3];
1435 0 : }
1436 : break;
1437 : case IEEE80211_ELEMID_VENDOR:
1438 0 : if (frm[1] < 4) {
1439 0 : ic->ic_stats.is_rx_elem_toosmall++;
1440 0 : break;
1441 : }
1442 0 : if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
1443 0 : if (frm[5] == 1)
1444 0 : wpaie = frm;
1445 0 : else if (frm[1] >= 5 &&
1446 0 : frm[5] == 2 && frm[6] == 1)
1447 0 : wmmie = frm;
1448 : }
1449 : break;
1450 : }
1451 0 : frm += 2 + frm[1];
1452 : }
1453 : /* supported rates element is mandatory */
1454 0 : if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
1455 : DPRINTF(("invalid supported rates element\n"));
1456 0 : return;
1457 : }
1458 : /* SSID element is mandatory */
1459 0 : if (ssid == NULL || ssid[1] > IEEE80211_NWID_LEN) {
1460 : DPRINTF(("invalid SSID element\n"));
1461 0 : return;
1462 : }
1463 :
1464 : if (
1465 : #if IEEE80211_CHAN_MAX < 255
1466 : chan > IEEE80211_CHAN_MAX ||
1467 : #endif
1468 0 : isclr(ic->ic_chan_active, chan)) {
1469 : DPRINTF(("ignore %s with invalid channel %u\n",
1470 : isprobe ? "probe response" : "beacon", chan));
1471 0 : ic->ic_stats.is_rx_badchan++;
1472 0 : return;
1473 : }
1474 0 : if ((ic->ic_state != IEEE80211_S_SCAN ||
1475 0 : !(ic->ic_caps & IEEE80211_C_SCANALL)) &&
1476 0 : chan != bchan) {
1477 : /*
1478 : * Frame was received on a channel different from the
1479 : * one indicated in the DS params element id;
1480 : * silently discard it.
1481 : *
1482 : * NB: this can happen due to signal leakage.
1483 : */
1484 : DPRINTF(("ignore %s on channel %u marked for channel %u\n",
1485 : isprobe ? "probe response" : "beacon", bchan, chan));
1486 0 : ic->ic_stats.is_rx_chanmismatch++;
1487 0 : return;
1488 : }
1489 : /*
1490 : * Use mac, channel and rssi so we collect only the
1491 : * best potential AP with the equal bssid while scanning.
1492 : * Collecting all potential APs may result in bloat of
1493 : * the node tree. This call will return NULL if the node
1494 : * for this APs does not exist or if the new node is the
1495 : * potential better one.
1496 : */
1497 0 : ni = ieee80211_find_node_for_beacon(ic, wh->i_addr2,
1498 0 : &ic->ic_channels[chan], ssid, rxi->rxi_rssi);
1499 0 : if (ni != NULL) {
1500 : /*
1501 : * If we are doing a directed scan for an AP with a hidden SSID
1502 : * we must collect the SSID from a probe response to override
1503 : * a non-zero-length SSID filled with zeroes that we may have
1504 : * received earlier in a beacon.
1505 : */
1506 0 : if (isprobe && ssid[1] != 0 && ni->ni_essid[0] == '\0') {
1507 0 : ni->ni_esslen = ssid[1];
1508 0 : memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1509 : /* we know that ssid[1] <= IEEE80211_NWID_LEN */
1510 0 : memcpy(ni->ni_essid, &ssid[2], ssid[1]);
1511 0 : }
1512 :
1513 0 : return;
1514 : }
1515 :
1516 : #ifdef IEEE80211_DEBUG
1517 : if (ieee80211_debug > 1 &&
1518 : (ni == NULL || ic->ic_state == IEEE80211_S_SCAN ||
1519 : (ic->ic_flags & IEEE80211_F_BGSCAN))) {
1520 : printf("%s: %s%s on chan %u (bss chan %u) ",
1521 : __func__, (ni == NULL ? "new " : ""),
1522 : isprobe ? "probe response" : "beacon",
1523 : chan, bchan);
1524 : ieee80211_print_essid(ssid + 2, ssid[1]);
1525 : printf(" from %s\n", ether_sprintf((u_int8_t *)wh->i_addr2));
1526 : printf("%s: caps 0x%x bintval %u erp 0x%x\n",
1527 : __func__, capinfo, bintval, erp);
1528 : }
1529 : #endif
1530 :
1531 0 : if ((ni = ieee80211_find_node(ic, wh->i_addr2)) == NULL) {
1532 0 : ni = ieee80211_alloc_node(ic, wh->i_addr2);
1533 0 : if (ni == NULL)
1534 0 : return;
1535 : is_new = 1;
1536 0 : } else
1537 : is_new = 0;
1538 :
1539 0 : if (htcaps)
1540 0 : ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
1541 0 : if (htop && !ieee80211_setup_htop(ni, htop + 2, htop[1], 1))
1542 0 : htop = NULL; /* invalid HTOP */
1543 :
1544 0 : ni->ni_dtimcount = dtim_count;
1545 0 : ni->ni_dtimperiod = dtim_period;
1546 :
1547 : /*
1548 : * When operating in station mode, check for state updates
1549 : * while we're associated.
1550 : */
1551 0 : if (ic->ic_opmode == IEEE80211_M_STA &&
1552 0 : ic->ic_state == IEEE80211_S_RUN &&
1553 0 : ni->ni_state == IEEE80211_STA_BSS) {
1554 : /*
1555 : * Check if protection mode has changed since last beacon.
1556 : */
1557 0 : if (ni->ni_erp != erp) {
1558 : DPRINTF(("[%s] erp change: was 0x%x, now 0x%x\n",
1559 : ether_sprintf((u_int8_t *)wh->i_addr2),
1560 : ni->ni_erp, erp));
1561 0 : if (ic->ic_curmode == IEEE80211_MODE_11G &&
1562 0 : (erp & IEEE80211_ERP_USE_PROTECTION))
1563 0 : ic->ic_flags |= IEEE80211_F_USEPROT;
1564 : else
1565 0 : ic->ic_flags &= ~IEEE80211_F_USEPROT;
1566 0 : ic->ic_bss->ni_erp = erp;
1567 0 : }
1568 0 : if (htop && (ic->ic_bss->ni_flags & IEEE80211_NODE_HT)) {
1569 : enum ieee80211_htprot htprot_last, htprot;
1570 : htprot_last =
1571 0 : ((ic->ic_bss->ni_htop1 & IEEE80211_HTOP1_PROT_MASK)
1572 : >> IEEE80211_HTOP1_PROT_SHIFT);
1573 0 : htprot = ((ni->ni_htop1 & IEEE80211_HTOP1_PROT_MASK) >>
1574 : IEEE80211_HTOP1_PROT_SHIFT);
1575 0 : if (htprot_last != htprot) {
1576 : DPRINTF(("[%s] htprot change: was %d, now %d\n",
1577 : ether_sprintf((u_int8_t *)wh->i_addr2),
1578 : htprot_last, htprot));
1579 0 : ic->ic_stats.is_ht_prot_change++;
1580 0 : ic->ic_bss->ni_htop1 = ni->ni_htop1;
1581 0 : if (ic->ic_update_htprot)
1582 0 : ic->ic_update_htprot(ic, ic->ic_bss);
1583 : }
1584 0 : }
1585 :
1586 : /*
1587 : * Check if AP short slot time setting has changed
1588 : * since last beacon and give the driver a chance to
1589 : * update the hardware.
1590 : */
1591 0 : if ((ni->ni_capinfo ^ capinfo) &
1592 : IEEE80211_CAPINFO_SHORT_SLOTTIME) {
1593 0 : ieee80211_set_shortslottime(ic,
1594 0 : ic->ic_curmode == IEEE80211_MODE_11A ||
1595 0 : (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1596 0 : }
1597 :
1598 : /*
1599 : * Reset management timer. If it is non-zero in RUN state, the
1600 : * driver sent a probe request after a missed beacon event.
1601 : * This probe response indicates the AP is still serving us
1602 : * so don't allow ieee80211_watchdog() to move us into SCAN.
1603 : */
1604 0 : if ((ic->ic_flags & IEEE80211_F_BGSCAN) == 0)
1605 0 : ic->ic_mgt_timer = 0;
1606 : }
1607 : /*
1608 : * We do not try to update EDCA parameters if QoS was not negotiated
1609 : * with the AP at association time.
1610 : */
1611 0 : if (ni->ni_flags & IEEE80211_NODE_QOS) {
1612 : /* always prefer EDCA IE over Wi-Fi Alliance WMM IE */
1613 0 : if ((edcaie != NULL &&
1614 0 : ieee80211_parse_edca_params(ic, edcaie) == 0) ||
1615 0 : (wmmie != NULL &&
1616 0 : ieee80211_parse_wmm_params(ic, wmmie) == 0))
1617 0 : ni->ni_flags |= IEEE80211_NODE_QOS;
1618 : else
1619 0 : ni->ni_flags &= ~IEEE80211_NODE_QOS;
1620 : }
1621 :
1622 0 : if (ic->ic_state == IEEE80211_S_SCAN ||
1623 0 : (ic->ic_flags & IEEE80211_F_BGSCAN)) {
1624 0 : struct ieee80211_rsnparams rsn, wpa;
1625 :
1626 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
1627 0 : ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE;
1628 0 : ni->ni_rsnakms = 0;
1629 0 : ni->ni_supported_rsnakms = 0;
1630 0 : ni->ni_rsnciphers = 0;
1631 0 : ni->ni_rsngroupcipher = 0;
1632 0 : ni->ni_rsngroupmgmtcipher = 0;
1633 0 : ni->ni_rsncaps = 0;
1634 :
1635 0 : if (rsnie != NULL &&
1636 0 : ieee80211_parse_rsn(ic, rsnie, &rsn) == 0) {
1637 0 : ni->ni_supported_rsnprotos |= IEEE80211_PROTO_RSN;
1638 0 : ni->ni_supported_rsnakms |= rsn.rsn_akms;
1639 0 : }
1640 0 : if (wpaie != NULL &&
1641 0 : ieee80211_parse_wpa(ic, wpaie, &wpa) == 0) {
1642 0 : ni->ni_supported_rsnprotos |= IEEE80211_PROTO_WPA;
1643 0 : ni->ni_supported_rsnakms |= wpa.rsn_akms;
1644 0 : }
1645 :
1646 : /*
1647 : * If the AP advertises both WPA and RSN IEs (WPA1+WPA2),
1648 : * we only use the highest protocol version we support.
1649 : */
1650 0 : if (rsnie != NULL &&
1651 0 : (ni->ni_supported_rsnprotos & IEEE80211_PROTO_RSN) &&
1652 0 : (ic->ic_rsnprotos & IEEE80211_PROTO_RSN)) {
1653 0 : if (ieee80211_save_ie(rsnie, &ni->ni_rsnie) == 0
1654 : #ifndef IEEE80211_STA_ONLY
1655 0 : && ic->ic_opmode != IEEE80211_M_HOSTAP
1656 : #endif
1657 : ) {
1658 0 : ni->ni_rsnprotos = IEEE80211_PROTO_RSN;
1659 0 : ni->ni_rsnakms = rsn.rsn_akms;
1660 0 : ni->ni_rsnciphers = rsn.rsn_ciphers;
1661 0 : ni->ni_rsngroupcipher = rsn.rsn_groupcipher;
1662 0 : ni->ni_rsngroupmgmtcipher =
1663 0 : rsn.rsn_groupmgmtcipher;
1664 0 : ni->ni_rsncaps = rsn.rsn_caps;
1665 0 : }
1666 0 : } else if (wpaie != NULL &&
1667 0 : (ni->ni_supported_rsnprotos & IEEE80211_PROTO_WPA) &&
1668 0 : (ic->ic_rsnprotos & IEEE80211_PROTO_WPA)) {
1669 0 : if (ieee80211_save_ie(wpaie, &ni->ni_rsnie) == 0
1670 : #ifndef IEEE80211_STA_ONLY
1671 0 : && ic->ic_opmode != IEEE80211_M_HOSTAP
1672 : #endif
1673 : ) {
1674 0 : ni->ni_rsnprotos = IEEE80211_PROTO_WPA;
1675 0 : ni->ni_rsnakms = wpa.rsn_akms;
1676 0 : ni->ni_rsnciphers = wpa.rsn_ciphers;
1677 0 : ni->ni_rsngroupcipher = wpa.rsn_groupcipher;
1678 0 : ni->ni_rsngroupmgmtcipher =
1679 0 : wpa.rsn_groupmgmtcipher;
1680 0 : ni->ni_rsncaps = wpa.rsn_caps;
1681 0 : }
1682 : }
1683 0 : }
1684 :
1685 0 : if (ssid[1] != 0 && ni->ni_essid[0] == '\0') {
1686 0 : ni->ni_esslen = ssid[1];
1687 0 : memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1688 : /* we know that ssid[1] <= IEEE80211_NWID_LEN */
1689 0 : memcpy(ni->ni_essid, &ssid[2], ssid[1]);
1690 0 : }
1691 0 : IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
1692 : /* XXX validate channel # */
1693 0 : ni->ni_chan = &ic->ic_channels[chan];
1694 0 : if (ic->ic_state == IEEE80211_S_SCAN &&
1695 0 : IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) {
1696 : /*
1697 : * During a scan on 5Ghz, prefer RSSI measured for probe
1698 : * response frames. i.e. don't allow beacons to lower the
1699 : * measured RSSI. Some 5GHz APs send beacons with much
1700 : * less Tx power than they use for probe responses.
1701 : */
1702 0 : if (isprobe)
1703 0 : ni->ni_rssi = rxi->rxi_rssi;
1704 0 : else if (ni->ni_rssi < rxi->rxi_rssi)
1705 0 : ni->ni_rssi = rxi->rxi_rssi;
1706 : } else
1707 0 : ni->ni_rssi = rxi->rxi_rssi;
1708 0 : ni->ni_rstamp = rxi->rxi_tstamp;
1709 0 : memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp));
1710 0 : ni->ni_intval = bintval;
1711 0 : ni->ni_capinfo = capinfo;
1712 0 : ni->ni_erp = erp;
1713 : /* NB: must be after ni_chan is setup */
1714 0 : ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
1715 : #ifndef IEEE80211_STA_ONLY
1716 0 : if (ic->ic_opmode == IEEE80211_M_IBSS && is_new && isprobe) {
1717 : /*
1718 : * Fake an association so the driver can setup it's
1719 : * private state. The rate set has been setup above;
1720 : * there is no handshake as in ap/station operation.
1721 : */
1722 0 : if (ic->ic_newassoc)
1723 0 : (*ic->ic_newassoc)(ic, ni, 1);
1724 : }
1725 : #endif
1726 0 : }
1727 :
1728 : #ifndef IEEE80211_STA_ONLY
1729 : /*-
1730 : * Probe request frame format:
1731 : * [tlv] SSID
1732 : * [tlv] Supported rates
1733 : * [tlv] Extended Supported Rates (802.11g)
1734 : * [tlv] HT Capabilities (802.11n)
1735 : */
1736 : void
1737 0 : ieee80211_recv_probe_req(struct ieee80211com *ic, struct mbuf *m,
1738 : struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi)
1739 : {
1740 : const struct ieee80211_frame *wh;
1741 : const u_int8_t *frm, *efrm;
1742 : const u_int8_t *ssid, *rates, *xrates, *htcaps;
1743 : u_int8_t rate;
1744 :
1745 0 : if (ic->ic_opmode == IEEE80211_M_STA ||
1746 0 : ic->ic_state != IEEE80211_S_RUN)
1747 0 : return;
1748 :
1749 0 : wh = mtod(m, struct ieee80211_frame *);
1750 0 : frm = (const u_int8_t *)&wh[1];
1751 0 : efrm = mtod(m, u_int8_t *) + m->m_len;
1752 :
1753 : ssid = rates = xrates = htcaps = NULL;
1754 0 : while (frm + 2 <= efrm) {
1755 0 : if (frm + 2 + frm[1] > efrm) {
1756 0 : ic->ic_stats.is_rx_elem_toosmall++;
1757 0 : break;
1758 : }
1759 0 : switch (frm[0]) {
1760 : case IEEE80211_ELEMID_SSID:
1761 : ssid = frm;
1762 0 : break;
1763 : case IEEE80211_ELEMID_RATES:
1764 : rates = frm;
1765 0 : break;
1766 : case IEEE80211_ELEMID_XRATES:
1767 : xrates = frm;
1768 0 : break;
1769 : case IEEE80211_ELEMID_HTCAPS:
1770 : htcaps = frm;
1771 0 : break;
1772 : }
1773 0 : frm += 2 + frm[1];
1774 : }
1775 : /* supported rates element is mandatory */
1776 0 : if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
1777 : DPRINTF(("invalid supported rates element\n"));
1778 0 : return;
1779 : }
1780 : /* SSID element is mandatory */
1781 0 : if (ssid == NULL || ssid[1] > IEEE80211_NWID_LEN) {
1782 : DPRINTF(("invalid SSID element\n"));
1783 0 : return;
1784 : }
1785 : /* check that the specified SSID (if not wildcard) matches ours */
1786 0 : if (ssid[1] != 0 && (ssid[1] != ic->ic_bss->ni_esslen ||
1787 0 : memcmp(&ssid[2], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen))) {
1788 : DPRINTF(("SSID mismatch\n"));
1789 0 : ic->ic_stats.is_rx_ssidmismatch++;
1790 0 : return;
1791 : }
1792 : /* refuse wildcard SSID if we're hiding our SSID in beacons */
1793 0 : if (ssid[1] == 0 && (ic->ic_flags & IEEE80211_F_HIDENWID)) {
1794 : DPRINTF(("wildcard SSID rejected"));
1795 0 : ic->ic_stats.is_rx_ssidmismatch++;
1796 0 : return;
1797 : }
1798 :
1799 0 : if (ni == ic->ic_bss) {
1800 0 : ni = ieee80211_find_node(ic, wh->i_addr2);
1801 0 : if (ni == NULL)
1802 0 : ni = ieee80211_dup_bss(ic, wh->i_addr2);
1803 0 : if (ni == NULL)
1804 0 : return;
1805 : DPRINTF(("new probe req from %s\n",
1806 : ether_sprintf((u_int8_t *)wh->i_addr2)));
1807 : }
1808 0 : ni->ni_rssi = rxi->rxi_rssi;
1809 0 : ni->ni_rstamp = rxi->rxi_tstamp;
1810 0 : rate = ieee80211_setup_rates(ic, ni, rates, xrates,
1811 : IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
1812 : IEEE80211_F_DODEL);
1813 0 : if (rate & IEEE80211_RATE_BASIC) {
1814 : DPRINTF(("rate mismatch for %s\n",
1815 : ether_sprintf((u_int8_t *)wh->i_addr2)));
1816 0 : return;
1817 : }
1818 0 : if (htcaps)
1819 0 : ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
1820 : else
1821 0 : ieee80211_clear_htcaps(ni);
1822 0 : IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
1823 0 : }
1824 : #endif /* IEEE80211_STA_ONLY */
1825 :
1826 : /*-
1827 : * Authentication frame format:
1828 : * [2] Authentication algorithm number
1829 : * [2] Authentication transaction sequence number
1830 : * [2] Status code
1831 : */
1832 : void
1833 0 : ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m,
1834 : struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi)
1835 : {
1836 : const struct ieee80211_frame *wh;
1837 : const u_int8_t *frm;
1838 : u_int16_t algo, seq, status;
1839 :
1840 : /* make sure all mandatory fixed fields are present */
1841 0 : if (m->m_len < sizeof(*wh) + 6) {
1842 : DPRINTF(("frame too short\n"));
1843 0 : return;
1844 : }
1845 0 : wh = mtod(m, struct ieee80211_frame *);
1846 0 : frm = (const u_int8_t *)&wh[1];
1847 :
1848 0 : algo = LE_READ_2(frm); frm += 2;
1849 0 : seq = LE_READ_2(frm); frm += 2;
1850 0 : status = LE_READ_2(frm); frm += 2;
1851 : DPRINTF(("auth %d seq %d from %s\n", algo, seq,
1852 : ether_sprintf((u_int8_t *)wh->i_addr2)));
1853 :
1854 : /* only "open" auth mode is supported */
1855 0 : if (algo != IEEE80211_AUTH_ALG_OPEN) {
1856 : DPRINTF(("unsupported auth algorithm %d from %s\n",
1857 : algo, ether_sprintf((u_int8_t *)wh->i_addr2)));
1858 0 : ic->ic_stats.is_rx_auth_unsupported++;
1859 : #ifndef IEEE80211_STA_ONLY
1860 0 : if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1861 : /* XXX hack to workaround calling convention */
1862 0 : IEEE80211_SEND_MGMT(ic, ni,
1863 : IEEE80211_FC0_SUBTYPE_AUTH,
1864 : IEEE80211_STATUS_ALG << 16 | ((seq + 1) & 0xffff));
1865 0 : }
1866 : #endif
1867 0 : return;
1868 : }
1869 0 : ieee80211_auth_open(ic, wh, ni, rxi, seq, status);
1870 0 : }
1871 :
1872 : #ifndef IEEE80211_STA_ONLY
1873 : /*-
1874 : * (Re)Association request frame format:
1875 : * [2] Capability information
1876 : * [2] Listen interval
1877 : * [6*] Current AP address (Reassociation only)
1878 : * [tlv] SSID
1879 : * [tlv] Supported rates
1880 : * [tlv] Extended Supported Rates (802.11g)
1881 : * [tlv] RSN (802.11i)
1882 : * [tlv] QoS Capability (802.11e)
1883 : * [tlv] HT Capabilities (802.11n)
1884 : */
1885 : void
1886 0 : ieee80211_recv_assoc_req(struct ieee80211com *ic, struct mbuf *m,
1887 : struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int reassoc)
1888 : {
1889 : const struct ieee80211_frame *wh;
1890 : const u_int8_t *frm, *efrm;
1891 : const u_int8_t *ssid, *rates, *xrates, *rsnie, *wpaie, *htcaps;
1892 : u_int16_t capinfo, bintval;
1893 : int resp, status = 0;
1894 0 : struct ieee80211_rsnparams rsn;
1895 : u_int8_t rate;
1896 : const u_int8_t *saveie = NULL;
1897 :
1898 0 : if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
1899 0 : ic->ic_state != IEEE80211_S_RUN)
1900 0 : return;
1901 :
1902 : /* make sure all mandatory fixed fields are present */
1903 0 : if (m->m_len < sizeof(*wh) + (reassoc ? 10 : 4)) {
1904 : DPRINTF(("frame too short\n"));
1905 0 : return;
1906 : }
1907 0 : wh = mtod(m, struct ieee80211_frame *);
1908 0 : frm = (const u_int8_t *)&wh[1];
1909 0 : efrm = mtod(m, u_int8_t *) + m->m_len;
1910 :
1911 0 : if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
1912 : DPRINTF(("ignore other bss from %s\n",
1913 : ether_sprintf((u_int8_t *)wh->i_addr2)));
1914 0 : ic->ic_stats.is_rx_assoc_bss++;
1915 0 : return;
1916 : }
1917 0 : capinfo = LE_READ_2(frm); frm += 2;
1918 0 : bintval = LE_READ_2(frm); frm += 2;
1919 0 : if (reassoc) {
1920 0 : frm += IEEE80211_ADDR_LEN; /* skip current AP address */
1921 : resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
1922 0 : } else
1923 : resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
1924 :
1925 : ssid = rates = xrates = rsnie = wpaie = htcaps = NULL;
1926 0 : while (frm + 2 <= efrm) {
1927 0 : if (frm + 2 + frm[1] > efrm) {
1928 0 : ic->ic_stats.is_rx_elem_toosmall++;
1929 0 : break;
1930 : }
1931 0 : switch (frm[0]) {
1932 : case IEEE80211_ELEMID_SSID:
1933 : ssid = frm;
1934 0 : break;
1935 : case IEEE80211_ELEMID_RATES:
1936 : rates = frm;
1937 0 : break;
1938 : case IEEE80211_ELEMID_XRATES:
1939 : xrates = frm;
1940 0 : break;
1941 : case IEEE80211_ELEMID_RSN:
1942 : rsnie = frm;
1943 0 : break;
1944 : case IEEE80211_ELEMID_QOS_CAP:
1945 : break;
1946 : case IEEE80211_ELEMID_HTCAPS:
1947 : htcaps = frm;
1948 0 : break;
1949 : case IEEE80211_ELEMID_VENDOR:
1950 0 : if (frm[1] < 4) {
1951 0 : ic->ic_stats.is_rx_elem_toosmall++;
1952 0 : break;
1953 : }
1954 0 : if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
1955 0 : if (frm[5] == 1)
1956 0 : wpaie = frm;
1957 : }
1958 : break;
1959 : }
1960 0 : frm += 2 + frm[1];
1961 : }
1962 : /* supported rates element is mandatory */
1963 0 : if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
1964 : DPRINTF(("invalid supported rates element\n"));
1965 0 : return;
1966 : }
1967 : /* SSID element is mandatory */
1968 0 : if (ssid == NULL || ssid[1] > IEEE80211_NWID_LEN) {
1969 : DPRINTF(("invalid SSID element\n"));
1970 0 : return;
1971 : }
1972 : /* check that the specified SSID matches ours */
1973 0 : if (ssid[1] != ic->ic_bss->ni_esslen ||
1974 0 : memcmp(&ssid[2], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen)) {
1975 : DPRINTF(("SSID mismatch\n"));
1976 0 : ic->ic_stats.is_rx_ssidmismatch++;
1977 0 : return;
1978 : }
1979 :
1980 0 : if (ni->ni_state != IEEE80211_STA_AUTH &&
1981 0 : ni->ni_state != IEEE80211_STA_ASSOC) {
1982 : DPRINTF(("deny %sassoc from %s, not authenticated\n",
1983 : reassoc ? "re" : "",
1984 : ether_sprintf((u_int8_t *)wh->i_addr2)));
1985 0 : ni = ieee80211_find_node(ic, wh->i_addr2);
1986 0 : if (ni == NULL)
1987 0 : ni = ieee80211_dup_bss(ic, wh->i_addr2);
1988 0 : if (ni != NULL) {
1989 0 : IEEE80211_SEND_MGMT(ic, ni,
1990 : IEEE80211_FC0_SUBTYPE_DEAUTH,
1991 : IEEE80211_REASON_ASSOC_NOT_AUTHED);
1992 0 : }
1993 0 : ic->ic_stats.is_rx_assoc_notauth++;
1994 0 : return;
1995 : }
1996 :
1997 0 : if (ni->ni_state == IEEE80211_STA_ASSOC &&
1998 0 : (ni->ni_flags & IEEE80211_NODE_MFP)) {
1999 0 : if (ni->ni_flags & IEEE80211_NODE_SA_QUERY_FAILED) {
2000 : /* send a protected Disassociate frame */
2001 0 : IEEE80211_SEND_MGMT(ic, ni,
2002 : IEEE80211_FC0_SUBTYPE_DISASSOC,
2003 : IEEE80211_REASON_AUTH_EXPIRE);
2004 : /* terminate the old SA */
2005 0 : ieee80211_node_leave(ic, ni);
2006 0 : } else {
2007 : /* reject the (Re)Association Request temporarily */
2008 0 : IEEE80211_SEND_MGMT(ic, ni, resp,
2009 : IEEE80211_STATUS_TRY_AGAIN_LATER);
2010 : /* start SA Query procedure if not already engaged */
2011 0 : if (!(ni->ni_flags & IEEE80211_NODE_SA_QUERY))
2012 0 : ieee80211_sa_query_request(ic, ni);
2013 : /* do not modify association state */
2014 : }
2015 0 : return;
2016 : }
2017 :
2018 0 : if (!(capinfo & IEEE80211_CAPINFO_ESS)) {
2019 0 : ic->ic_stats.is_rx_assoc_capmismatch++;
2020 : status = IEEE80211_STATUS_CAPINFO;
2021 0 : goto end;
2022 : }
2023 0 : rate = ieee80211_setup_rates(ic, ni, rates, xrates,
2024 : IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
2025 : IEEE80211_F_DODEL);
2026 0 : if (rate & IEEE80211_RATE_BASIC) {
2027 0 : ic->ic_stats.is_rx_assoc_norate++;
2028 : status = IEEE80211_STATUS_BASIC_RATE;
2029 0 : goto end;
2030 : }
2031 :
2032 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2033 0 : ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE;
2034 0 : ni->ni_rsnakms = 0;
2035 0 : ni->ni_supported_rsnakms = 0;
2036 0 : ni->ni_rsnciphers = 0;
2037 0 : ni->ni_rsngroupcipher = 0;
2038 0 : ni->ni_rsngroupmgmtcipher = 0;
2039 0 : ni->ni_rsncaps = 0;
2040 :
2041 : /*
2042 : * A station should never include both a WPA and an RSN IE
2043 : * in its (Re)Association Requests, but if it does, we only
2044 : * consider the IE of the highest version of the protocol
2045 : * that is allowed (ie RSN over WPA).
2046 : */
2047 0 : if (rsnie != NULL) {
2048 0 : status = ieee80211_parse_rsn(ic, rsnie, &rsn);
2049 0 : if (status != 0)
2050 : goto end;
2051 0 : ni->ni_supported_rsnprotos = IEEE80211_PROTO_RSN;
2052 0 : ni->ni_supported_rsnakms = rsn.rsn_akms;
2053 0 : if ((ic->ic_flags & IEEE80211_F_RSNON) &&
2054 0 : (ic->ic_rsnprotos & IEEE80211_PROTO_RSN)) {
2055 0 : ni->ni_rsnprotos = IEEE80211_PROTO_RSN;
2056 : saveie = rsnie;
2057 0 : }
2058 0 : } else if (wpaie != NULL) {
2059 0 : status = ieee80211_parse_wpa(ic, wpaie, &rsn);
2060 0 : if (status != 0)
2061 : goto end;
2062 0 : ni->ni_supported_rsnprotos = IEEE80211_PROTO_WPA;
2063 0 : ni->ni_supported_rsnakms = rsn.rsn_akms;
2064 0 : if ((ic->ic_flags & IEEE80211_F_RSNON) &&
2065 0 : (ic->ic_rsnprotos & IEEE80211_PROTO_WPA)) {
2066 0 : ni->ni_rsnprotos = IEEE80211_PROTO_WPA;
2067 : saveie = wpaie;
2068 0 : }
2069 : }
2070 :
2071 0 : if (ic->ic_flags & IEEE80211_F_RSNON) {
2072 0 : if (ni->ni_rsnprotos == IEEE80211_PROTO_NONE) {
2073 : /*
2074 : * In an RSN, an AP shall not associate with STAs
2075 : * that fail to include the RSN IE in the
2076 : * (Re)Association Request.
2077 : */
2078 : status = IEEE80211_STATUS_IE_INVALID;
2079 0 : goto end;
2080 : }
2081 : /*
2082 : * The initiating STA's RSN IE shall include one authentication
2083 : * and pairwise cipher suite among those advertised by the
2084 : * targeted AP. It shall also specify the group cipher suite
2085 : * specified by the targeted AP.
2086 : */
2087 0 : if (rsn.rsn_nakms != 1 ||
2088 0 : !(rsn.rsn_akms & ic->ic_bss->ni_rsnakms)) {
2089 : status = IEEE80211_STATUS_BAD_AKMP;
2090 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2091 0 : goto end;
2092 : }
2093 0 : if (rsn.rsn_nciphers != 1 ||
2094 0 : !(rsn.rsn_ciphers & ic->ic_bss->ni_rsnciphers)) {
2095 : status = IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
2096 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2097 0 : goto end;
2098 : }
2099 0 : if (rsn.rsn_groupcipher != ic->ic_bss->ni_rsngroupcipher) {
2100 : status = IEEE80211_STATUS_BAD_GROUP_CIPHER;
2101 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2102 0 : goto end;
2103 : }
2104 :
2105 0 : if ((ic->ic_bss->ni_rsncaps & IEEE80211_RSNCAP_MFPR) &&
2106 0 : !(rsn.rsn_caps & IEEE80211_RSNCAP_MFPC)) {
2107 : status = IEEE80211_STATUS_MFP_POLICY;
2108 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2109 0 : goto end;
2110 : }
2111 0 : if ((ic->ic_bss->ni_rsncaps & IEEE80211_RSNCAP_MFPC) &&
2112 0 : (rsn.rsn_caps & (IEEE80211_RSNCAP_MFPC |
2113 0 : IEEE80211_RSNCAP_MFPR)) == IEEE80211_RSNCAP_MFPR) {
2114 : /* STA advertises an invalid setting */
2115 : status = IEEE80211_STATUS_MFP_POLICY;
2116 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2117 0 : goto end;
2118 : }
2119 : /*
2120 : * A STA that has associated with Management Frame Protection
2121 : * enabled shall not use cipher suite pairwise selector WEP40,
2122 : * WEP104, TKIP, or "Use Group cipher suite".
2123 : */
2124 0 : if ((rsn.rsn_caps & IEEE80211_RSNCAP_MFPC) &&
2125 0 : (rsn.rsn_ciphers != IEEE80211_CIPHER_CCMP ||
2126 0 : rsn.rsn_groupmgmtcipher !=
2127 0 : ic->ic_bss->ni_rsngroupmgmtcipher)) {
2128 : status = IEEE80211_STATUS_MFP_POLICY;
2129 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2130 0 : goto end;
2131 : }
2132 :
2133 : /*
2134 : * Disallow new associations using TKIP if countermeasures
2135 : * are active.
2136 : */
2137 0 : if ((ic->ic_flags & IEEE80211_F_COUNTERM) &&
2138 0 : (rsn.rsn_ciphers == IEEE80211_CIPHER_TKIP ||
2139 0 : rsn.rsn_groupcipher == IEEE80211_CIPHER_TKIP)) {
2140 : status = IEEE80211_STATUS_CIPHER_REJ_POLICY;
2141 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2142 0 : goto end;
2143 : }
2144 :
2145 : /* everything looks fine, save IE and parameters */
2146 0 : if (saveie == NULL ||
2147 0 : ieee80211_save_ie(saveie, &ni->ni_rsnie) != 0) {
2148 : status = IEEE80211_STATUS_TOOMANY;
2149 0 : ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
2150 0 : goto end;
2151 : }
2152 0 : ni->ni_rsnakms = rsn.rsn_akms;
2153 0 : ni->ni_rsnciphers = rsn.rsn_ciphers;
2154 0 : ni->ni_rsngroupcipher = ic->ic_bss->ni_rsngroupcipher;
2155 0 : ni->ni_rsngroupmgmtcipher = ic->ic_bss->ni_rsngroupmgmtcipher;
2156 0 : ni->ni_rsncaps = rsn.rsn_caps;
2157 :
2158 0 : if (ieee80211_is_8021x_akm(ni->ni_rsnakms)) {
2159 : struct ieee80211_pmk *pmk = NULL;
2160 0 : const u_int8_t *pmkid = rsn.rsn_pmkids;
2161 : /*
2162 : * Check if we have a cached PMK entry matching one
2163 : * of the PMKIDs specified in the RSN IE.
2164 : */
2165 0 : while (rsn.rsn_npmkids-- > 0) {
2166 0 : pmk = ieee80211_pmksa_find(ic, ni, pmkid);
2167 0 : if (pmk != NULL)
2168 : break;
2169 0 : pmkid += IEEE80211_PMKID_LEN;
2170 : }
2171 0 : if (pmk != NULL) {
2172 0 : memcpy(ni->ni_pmk, pmk->pmk_key,
2173 : IEEE80211_PMK_LEN);
2174 0 : memcpy(ni->ni_pmkid, pmk->pmk_pmkid,
2175 : IEEE80211_PMKID_LEN);
2176 0 : ni->ni_flags |= IEEE80211_NODE_PMK;
2177 0 : }
2178 0 : }
2179 : }
2180 :
2181 0 : ni->ni_rssi = rxi->rxi_rssi;
2182 0 : ni->ni_rstamp = rxi->rxi_tstamp;
2183 0 : ni->ni_intval = bintval;
2184 0 : ni->ni_capinfo = capinfo;
2185 0 : ni->ni_chan = ic->ic_bss->ni_chan;
2186 0 : if (htcaps)
2187 0 : ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
2188 : else
2189 0 : ieee80211_clear_htcaps(ni);
2190 : end:
2191 0 : if (status != 0) {
2192 0 : IEEE80211_SEND_MGMT(ic, ni, resp, status);
2193 0 : ieee80211_node_leave(ic, ni);
2194 0 : } else
2195 0 : ieee80211_node_join(ic, ni, resp);
2196 0 : }
2197 : #endif /* IEEE80211_STA_ONLY */
2198 :
2199 : /*-
2200 : * (Re)Association response frame format:
2201 : * [2] Capability information
2202 : * [2] Status code
2203 : * [2] Association ID (AID)
2204 : * [tlv] Supported rates
2205 : * [tlv] Extended Supported Rates (802.11g)
2206 : * [tlv] EDCA Parameter Set (802.11e)
2207 : * [tlv] HT Capabilities (802.11n)
2208 : * [tlv] HT Operation (802.11n)
2209 : */
2210 : void
2211 0 : ieee80211_recv_assoc_resp(struct ieee80211com *ic, struct mbuf *m,
2212 : struct ieee80211_node *ni, int reassoc)
2213 : {
2214 0 : struct ifnet *ifp = &ic->ic_if;
2215 : const struct ieee80211_frame *wh;
2216 : const u_int8_t *frm, *efrm;
2217 : const u_int8_t *rates, *xrates, *edcaie, *wmmie, *htcaps, *htop;
2218 : u_int16_t capinfo, status, associd;
2219 : u_int8_t rate;
2220 :
2221 0 : if (ic->ic_opmode != IEEE80211_M_STA ||
2222 0 : ic->ic_state != IEEE80211_S_ASSOC) {
2223 0 : ic->ic_stats.is_rx_mgtdiscard++;
2224 0 : return;
2225 : }
2226 :
2227 : /* make sure all mandatory fixed fields are present */
2228 0 : if (m->m_len < sizeof(*wh) + 6) {
2229 : DPRINTF(("frame too short\n"));
2230 0 : return;
2231 : }
2232 0 : wh = mtod(m, struct ieee80211_frame *);
2233 0 : frm = (const u_int8_t *)&wh[1];
2234 0 : efrm = mtod(m, u_int8_t *) + m->m_len;
2235 :
2236 0 : capinfo = LE_READ_2(frm); frm += 2;
2237 0 : status = LE_READ_2(frm); frm += 2;
2238 0 : if (status != IEEE80211_STATUS_SUCCESS) {
2239 0 : if (ifp->if_flags & IFF_DEBUG)
2240 0 : printf("%s: %sassociation failed (status %d)"
2241 0 : " for %s\n", ifp->if_xname,
2242 0 : reassoc ? "re" : "",
2243 0 : status, ether_sprintf((u_int8_t *)wh->i_addr3));
2244 0 : if (ni != ic->ic_bss)
2245 0 : ni->ni_fails++;
2246 0 : ic->ic_stats.is_rx_auth_fail++;
2247 0 : return;
2248 : }
2249 0 : associd = LE_READ_2(frm); frm += 2;
2250 :
2251 : rates = xrates = edcaie = wmmie = htcaps = htop = NULL;
2252 0 : while (frm + 2 <= efrm) {
2253 0 : if (frm + 2 + frm[1] > efrm) {
2254 0 : ic->ic_stats.is_rx_elem_toosmall++;
2255 0 : break;
2256 : }
2257 0 : switch (frm[0]) {
2258 : case IEEE80211_ELEMID_RATES:
2259 : rates = frm;
2260 0 : break;
2261 : case IEEE80211_ELEMID_XRATES:
2262 : xrates = frm;
2263 0 : break;
2264 : case IEEE80211_ELEMID_EDCAPARMS:
2265 : edcaie = frm;
2266 0 : break;
2267 : case IEEE80211_ELEMID_HTCAPS:
2268 : htcaps = frm;
2269 0 : break;
2270 : case IEEE80211_ELEMID_HTOP:
2271 : htop = frm;
2272 0 : break;
2273 : case IEEE80211_ELEMID_VENDOR:
2274 0 : if (frm[1] < 4) {
2275 0 : ic->ic_stats.is_rx_elem_toosmall++;
2276 0 : break;
2277 : }
2278 0 : if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
2279 0 : if (frm[1] >= 5 && frm[5] == 2 && frm[6] == 1)
2280 0 : wmmie = frm;
2281 : }
2282 : break;
2283 : }
2284 0 : frm += 2 + frm[1];
2285 : }
2286 : /* supported rates element is mandatory */
2287 0 : if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
2288 : DPRINTF(("invalid supported rates element\n"));
2289 0 : return;
2290 : }
2291 0 : rate = ieee80211_setup_rates(ic, ni, rates, xrates,
2292 : IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
2293 : IEEE80211_F_DODEL);
2294 0 : if (rate & IEEE80211_RATE_BASIC) {
2295 : DPRINTF(("rate mismatch for %s\n",
2296 : ether_sprintf((u_int8_t *)wh->i_addr2)));
2297 0 : ic->ic_stats.is_rx_assoc_norate++;
2298 0 : return;
2299 : }
2300 0 : ni->ni_capinfo = capinfo;
2301 0 : ni->ni_associd = associd;
2302 0 : if (edcaie != NULL || wmmie != NULL) {
2303 : /* force update of EDCA parameters */
2304 0 : ic->ic_edca_updtcount = -1;
2305 :
2306 0 : if ((edcaie != NULL &&
2307 0 : ieee80211_parse_edca_params(ic, edcaie) == 0) ||
2308 0 : (wmmie != NULL &&
2309 0 : ieee80211_parse_wmm_params(ic, wmmie) == 0))
2310 0 : ni->ni_flags |= IEEE80211_NODE_QOS;
2311 : else /* for Reassociation */
2312 0 : ni->ni_flags &= ~IEEE80211_NODE_QOS;
2313 : }
2314 0 : if (htcaps)
2315 0 : ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
2316 0 : if (htop)
2317 0 : ieee80211_setup_htop(ni, htop + 2, htop[1], 0);
2318 0 : ieee80211_ht_negotiate(ic, ni);
2319 :
2320 : /* Hop into 11n mode after associating to an HT AP in a non-11n mode. */
2321 0 : if (ni->ni_flags & IEEE80211_NODE_HT)
2322 0 : ieee80211_setmode(ic, IEEE80211_MODE_11N);
2323 : else
2324 0 : ieee80211_setmode(ic, ieee80211_chan2mode(ic, ni->ni_chan));
2325 : /*
2326 : * Reset the erp state (mostly the slot time) now that
2327 : * our operating mode has been nailed down.
2328 : */
2329 0 : ieee80211_reset_erp(ic);
2330 :
2331 : /*
2332 : * Configure state now that we are associated.
2333 : */
2334 0 : if (ic->ic_curmode == IEEE80211_MODE_11A ||
2335 0 : (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
2336 0 : ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
2337 : else
2338 0 : ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
2339 :
2340 0 : ieee80211_set_shortslottime(ic,
2341 0 : ic->ic_curmode == IEEE80211_MODE_11A ||
2342 0 : (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
2343 : /*
2344 : * Honor ERP protection.
2345 : */
2346 0 : if ((ic->ic_curmode == IEEE80211_MODE_11G ||
2347 0 : (ic->ic_curmode == IEEE80211_MODE_11N &&
2348 0 : IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))) &&
2349 0 : (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
2350 0 : ic->ic_flags |= IEEE80211_F_USEPROT;
2351 : else
2352 0 : ic->ic_flags &= ~IEEE80211_F_USEPROT;
2353 : /*
2354 : * If not an RSNA, mark the port as valid, otherwise wait for
2355 : * 802.1X authentication and 4-way handshake to complete..
2356 : */
2357 0 : if (ic->ic_flags & IEEE80211_F_RSNON) {
2358 : /* XXX ic->ic_mgt_timer = 5; */
2359 0 : ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART;
2360 0 : } else if (ic->ic_flags & IEEE80211_F_WEPON)
2361 0 : ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
2362 :
2363 0 : ieee80211_new_state(ic, IEEE80211_S_RUN,
2364 : IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
2365 0 : }
2366 :
2367 : /*-
2368 : * Deauthentication frame format:
2369 : * [2] Reason code
2370 : */
2371 : void
2372 0 : ieee80211_recv_deauth(struct ieee80211com *ic, struct mbuf *m,
2373 : struct ieee80211_node *ni)
2374 : {
2375 : const struct ieee80211_frame *wh;
2376 : const u_int8_t *frm;
2377 : u_int16_t reason;
2378 :
2379 : /* make sure all mandatory fixed fields are present */
2380 0 : if (m->m_len < sizeof(*wh) + 2) {
2381 : DPRINTF(("frame too short\n"));
2382 0 : return;
2383 : }
2384 0 : wh = mtod(m, struct ieee80211_frame *);
2385 0 : frm = (const u_int8_t *)&wh[1];
2386 :
2387 0 : reason = LE_READ_2(frm);
2388 :
2389 0 : ic->ic_stats.is_rx_deauth++;
2390 0 : switch (ic->ic_opmode) {
2391 : case IEEE80211_M_STA: {
2392 0 : int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
2393 0 : ic->ic_state == IEEE80211_S_RUN);
2394 0 : if (!bgscan) /* ignore deauth during bgscan */
2395 0 : ieee80211_new_state(ic, IEEE80211_S_AUTH,
2396 : IEEE80211_FC0_SUBTYPE_DEAUTH);
2397 : }
2398 0 : break;
2399 : #ifndef IEEE80211_STA_ONLY
2400 : case IEEE80211_M_HOSTAP:
2401 0 : if (ni != ic->ic_bss) {
2402 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
2403 0 : printf("%s: station %s deauthenticated "
2404 : "by peer (reason %d)\n",
2405 0 : ic->ic_if.if_xname,
2406 0 : ether_sprintf(ni->ni_macaddr),
2407 0 : reason);
2408 0 : ieee80211_node_leave(ic, ni);
2409 0 : }
2410 : break;
2411 : #endif
2412 : default:
2413 : break;
2414 : }
2415 0 : }
2416 :
2417 : /*-
2418 : * Disassociation frame format:
2419 : * [2] Reason code
2420 : */
2421 : void
2422 0 : ieee80211_recv_disassoc(struct ieee80211com *ic, struct mbuf *m,
2423 : struct ieee80211_node *ni)
2424 : {
2425 : const struct ieee80211_frame *wh;
2426 : const u_int8_t *frm;
2427 : u_int16_t reason;
2428 :
2429 : /* make sure all mandatory fixed fields are present */
2430 0 : if (m->m_len < sizeof(*wh) + 2) {
2431 : DPRINTF(("frame too short\n"));
2432 0 : return;
2433 : }
2434 0 : wh = mtod(m, struct ieee80211_frame *);
2435 0 : frm = (const u_int8_t *)&wh[1];
2436 :
2437 0 : reason = LE_READ_2(frm);
2438 :
2439 0 : ic->ic_stats.is_rx_disassoc++;
2440 0 : switch (ic->ic_opmode) {
2441 : case IEEE80211_M_STA: {
2442 0 : int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
2443 0 : ic->ic_state == IEEE80211_S_RUN);
2444 0 : if (!bgscan) /* ignore disassoc during bgscan */
2445 0 : ieee80211_new_state(ic, IEEE80211_S_ASSOC,
2446 : IEEE80211_FC0_SUBTYPE_DISASSOC);
2447 : }
2448 0 : break;
2449 : #ifndef IEEE80211_STA_ONLY
2450 : case IEEE80211_M_HOSTAP:
2451 0 : if (ni != ic->ic_bss) {
2452 0 : if (ic->ic_if.if_flags & IFF_DEBUG)
2453 0 : printf("%s: station %s disassociated "
2454 : "by peer (reason %d)\n",
2455 0 : ic->ic_if.if_xname,
2456 0 : ether_sprintf(ni->ni_macaddr),
2457 0 : reason);
2458 0 : ieee80211_node_leave(ic, ni);
2459 0 : }
2460 : break;
2461 : #endif
2462 : default:
2463 : break;
2464 : }
2465 0 : }
2466 :
2467 : /*-
2468 : * ADDBA Request frame format:
2469 : * [1] Category
2470 : * [1] Action
2471 : * [1] Dialog Token
2472 : * [2] Block Ack Parameter Set
2473 : * [2] Block Ack Timeout Value
2474 : * [2] Block Ack Starting Sequence Control
2475 : */
2476 : void
2477 0 : ieee80211_recv_addba_req(struct ieee80211com *ic, struct mbuf *m,
2478 : struct ieee80211_node *ni)
2479 : {
2480 : const struct ieee80211_frame *wh;
2481 : const u_int8_t *frm;
2482 : struct ieee80211_rx_ba *ba;
2483 : u_int16_t params, ssn, bufsz, timeout;
2484 : u_int8_t token, tid;
2485 : int err = 0;
2486 :
2487 0 : if (!(ni->ni_flags & IEEE80211_NODE_HT)) {
2488 : DPRINTF(("received ADDBA req from non-HT STA %s\n",
2489 : ether_sprintf(ni->ni_macaddr)));
2490 0 : return;
2491 : }
2492 0 : if (m->m_len < sizeof(*wh) + 9) {
2493 : DPRINTF(("frame too short\n"));
2494 0 : return;
2495 : }
2496 : /* MLME-ADDBA.indication */
2497 0 : wh = mtod(m, struct ieee80211_frame *);
2498 0 : frm = (const u_int8_t *)&wh[1];
2499 :
2500 0 : token = frm[2];
2501 0 : params = LE_READ_2(&frm[3]);
2502 0 : tid = ((params & IEEE80211_ADDBA_TID_MASK) >>
2503 : IEEE80211_ADDBA_TID_SHIFT);
2504 0 : bufsz = (params & IEEE80211_ADDBA_BUFSZ_MASK) >>
2505 : IEEE80211_ADDBA_BUFSZ_SHIFT;
2506 0 : timeout = LE_READ_2(&frm[5]);
2507 0 : ssn = LE_READ_2(&frm[7]) >> 4;
2508 :
2509 0 : ba = &ni->ni_rx_ba[tid];
2510 : /* check if we already have a Block Ack agreement for this RA/TID */
2511 0 : if (ba->ba_state == IEEE80211_BA_AGREED) {
2512 : /* XXX should we update the timeout value? */
2513 : /* reset Block Ack inactivity timer */
2514 0 : if (ba->ba_timeout_val != 0)
2515 0 : timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
2516 :
2517 : /* check if it's a Protected Block Ack agreement */
2518 0 : if (!(ni->ni_flags & IEEE80211_NODE_MFP) ||
2519 0 : !(ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC))
2520 0 : return; /* not a PBAC, ignore */
2521 :
2522 : /* PBAC: treat the ADDBA Request like a BlockAckReq */
2523 0 : if (SEQ_LT(ba->ba_winstart, ssn))
2524 0 : ieee80211_ba_move_window(ic, ni, tid, ssn);
2525 0 : return;
2526 : }
2527 :
2528 : /* if PBAC required but RA does not support it, refuse request */
2529 0 : if ((ic->ic_flags & IEEE80211_F_PBAR) &&
2530 0 : (!(ni->ni_flags & IEEE80211_NODE_MFP) ||
2531 0 : !(ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC)))
2532 : goto refuse;
2533 : /*
2534 : * If the TID for which the Block Ack agreement is requested is
2535 : * configured with a no-ACK policy, refuse the agreement.
2536 : */
2537 0 : if (ic->ic_tid_noack & (1 << tid))
2538 : goto refuse;
2539 :
2540 : /* check that we support the requested Block Ack Policy */
2541 0 : if (!(ic->ic_htcaps & IEEE80211_HTCAP_DELAYEDBA) &&
2542 0 : !(params & IEEE80211_ADDBA_BA_POLICY))
2543 : goto refuse;
2544 :
2545 : /* setup Block Ack agreement */
2546 0 : ba->ba_state = IEEE80211_BA_INIT;
2547 0 : ba->ba_timeout_val = timeout * IEEE80211_DUR_TU;
2548 0 : ba->ba_ni = ni;
2549 0 : ba->ba_token = token;
2550 0 : timeout_set(&ba->ba_to, ieee80211_rx_ba_timeout, ba);
2551 0 : timeout_set(&ba->ba_gap_to, ieee80211_input_ba_gap_timeout, ba);
2552 0 : ba->ba_winsize = bufsz;
2553 0 : if (ba->ba_winsize == 0 || ba->ba_winsize > IEEE80211_BA_MAX_WINSZ)
2554 0 : ba->ba_winsize = IEEE80211_BA_MAX_WINSZ;
2555 0 : ba->ba_params = (params & IEEE80211_ADDBA_BA_POLICY);
2556 0 : ba->ba_params |= ((ba->ba_winsize << IEEE80211_ADDBA_BUFSZ_SHIFT) |
2557 0 : (tid << IEEE80211_ADDBA_TID_SHIFT) | IEEE80211_ADDBA_AMSDU);
2558 0 : ba->ba_winstart = ssn;
2559 0 : ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
2560 : /* allocate and setup our reordering buffer */
2561 0 : ba->ba_buf = malloc(IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf),
2562 : M_DEVBUF, M_NOWAIT | M_ZERO);
2563 0 : if (ba->ba_buf == NULL)
2564 : goto refuse;
2565 :
2566 0 : ba->ba_head = 0;
2567 :
2568 : /* notify drivers of this new Block Ack agreement */
2569 0 : if (ic->ic_ampdu_rx_start != NULL)
2570 0 : err = ic->ic_ampdu_rx_start(ic, ni, tid);
2571 0 : if (err == EBUSY) {
2572 : /* driver will accept or refuse agreement when done */
2573 0 : return;
2574 0 : } else if (err) {
2575 : /* driver failed to setup, rollback */
2576 0 : ieee80211_addba_req_refuse(ic, ni, tid);
2577 0 : } else
2578 0 : ieee80211_addba_req_accept(ic, ni, tid);
2579 0 : return;
2580 :
2581 : refuse:
2582 : /* MLME-ADDBA.response */
2583 0 : IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
2584 : IEEE80211_ACTION_ADDBA_RESP,
2585 : IEEE80211_STATUS_REFUSED << 16 | token << 8 | tid);
2586 0 : }
2587 :
2588 : void
2589 0 : ieee80211_addba_req_accept(struct ieee80211com *ic, struct ieee80211_node *ni,
2590 : uint8_t tid)
2591 : {
2592 0 : struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
2593 :
2594 0 : ba->ba_state = IEEE80211_BA_AGREED;
2595 0 : ic->ic_stats.is_ht_rx_ba_agreements++;
2596 : /* start Block Ack inactivity timer */
2597 0 : if (ba->ba_timeout_val != 0)
2598 0 : timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
2599 :
2600 : /* MLME-ADDBA.response */
2601 0 : IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
2602 : IEEE80211_ACTION_ADDBA_RESP,
2603 : IEEE80211_STATUS_SUCCESS << 16 | ba->ba_token << 8 | tid);
2604 0 : }
2605 :
2606 : void
2607 0 : ieee80211_addba_req_refuse(struct ieee80211com *ic, struct ieee80211_node *ni,
2608 : uint8_t tid)
2609 : {
2610 0 : struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
2611 :
2612 0 : free(ba->ba_buf, M_DEVBUF,
2613 : IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf));
2614 0 : ba->ba_buf = NULL;
2615 :
2616 : /* MLME-ADDBA.response */
2617 0 : IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
2618 : IEEE80211_ACTION_ADDBA_RESP,
2619 : IEEE80211_STATUS_REFUSED << 16 | ba->ba_token << 8 | tid);
2620 0 : }
2621 :
2622 : /*-
2623 : * ADDBA Response frame format:
2624 : * [1] Category
2625 : * [1] Action
2626 : * [1] Dialog Token
2627 : * [2] Status Code
2628 : * [2] Block Ack Parameter Set
2629 : * [2] Block Ack Timeout Value
2630 : */
2631 : void
2632 0 : ieee80211_recv_addba_resp(struct ieee80211com *ic, struct mbuf *m,
2633 : struct ieee80211_node *ni)
2634 : {
2635 : const struct ieee80211_frame *wh;
2636 : const u_int8_t *frm;
2637 : struct ieee80211_tx_ba *ba;
2638 : u_int16_t status, params, bufsz, timeout;
2639 : u_int8_t token, tid;
2640 :
2641 0 : if (m->m_len < sizeof(*wh) + 9) {
2642 : DPRINTF(("frame too short\n"));
2643 0 : return;
2644 : }
2645 0 : wh = mtod(m, struct ieee80211_frame *);
2646 0 : frm = (const u_int8_t *)&wh[1];
2647 :
2648 0 : token = frm[2];
2649 0 : status = LE_READ_2(&frm[3]);
2650 0 : params = LE_READ_2(&frm[5]);
2651 0 : tid = (params >> 2) & 0xf;
2652 0 : bufsz = (params >> 6) & 0x3ff;
2653 0 : timeout = LE_READ_2(&frm[7]);
2654 :
2655 : DPRINTF(("received ADDBA resp from %s, TID %d, status %d\n",
2656 : ether_sprintf(ni->ni_macaddr), tid, status));
2657 :
2658 : /*
2659 : * Ignore if no ADDBA request has been sent for this RA/TID or
2660 : * if we already have a Block Ack agreement.
2661 : */
2662 0 : ba = &ni->ni_tx_ba[tid];
2663 0 : if (ba->ba_state != IEEE80211_BA_REQUESTED) {
2664 : DPRINTF(("no matching ADDBA req found\n"));
2665 0 : return;
2666 : }
2667 0 : if (token != ba->ba_token) {
2668 : DPRINTF(("ignoring ADDBA resp from %s: token %x!=%x\n",
2669 : ether_sprintf(ni->ni_macaddr), token, ba->ba_token));
2670 0 : return;
2671 : }
2672 : /* we got an ADDBA Response matching our request, stop timeout */
2673 0 : timeout_del(&ba->ba_to);
2674 :
2675 0 : if (status != IEEE80211_STATUS_SUCCESS) {
2676 : /* MLME-ADDBA.confirm(Failure) */
2677 0 : ba->ba_state = IEEE80211_BA_INIT;
2678 0 : return;
2679 : }
2680 : /* MLME-ADDBA.confirm(Success) */
2681 0 : ba->ba_state = IEEE80211_BA_AGREED;
2682 0 : ic->ic_stats.is_ht_tx_ba_agreements++;
2683 :
2684 : /* notify drivers of this new Block Ack agreement */
2685 0 : if (ic->ic_ampdu_tx_start != NULL)
2686 0 : (void)ic->ic_ampdu_tx_start(ic, ni, tid);
2687 :
2688 : /* start Block Ack inactivity timeout */
2689 0 : if (ba->ba_timeout_val != 0)
2690 0 : timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
2691 0 : }
2692 :
2693 : /*-
2694 : * DELBA frame format:
2695 : * [1] Category
2696 : * [1] Action
2697 : * [2] DELBA Parameter Set
2698 : * [2] Reason Code
2699 : */
2700 : void
2701 0 : ieee80211_recv_delba(struct ieee80211com *ic, struct mbuf *m,
2702 : struct ieee80211_node *ni)
2703 : {
2704 : const struct ieee80211_frame *wh;
2705 : const u_int8_t *frm;
2706 : u_int16_t params, reason;
2707 : u_int8_t tid;
2708 : int i;
2709 :
2710 0 : if (m->m_len < sizeof(*wh) + 6) {
2711 : DPRINTF(("frame too short\n"));
2712 0 : return;
2713 : }
2714 0 : wh = mtod(m, struct ieee80211_frame *);
2715 0 : frm = (const u_int8_t *)&wh[1];
2716 :
2717 0 : params = LE_READ_2(&frm[2]);
2718 0 : reason = LE_READ_2(&frm[4]);
2719 0 : tid = params >> 12;
2720 :
2721 : DPRINTF(("received DELBA from %s, TID %d, reason %d\n",
2722 : ether_sprintf(ni->ni_macaddr), tid, reason));
2723 :
2724 0 : if (params & IEEE80211_DELBA_INITIATOR) {
2725 : /* MLME-DELBA.indication(Originator) */
2726 0 : struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
2727 :
2728 0 : if (ba->ba_state != IEEE80211_BA_AGREED) {
2729 : DPRINTF(("no matching Block Ack agreement\n"));
2730 0 : return;
2731 : }
2732 : /* notify drivers of the end of the Block Ack agreement */
2733 0 : if (ic->ic_ampdu_rx_stop != NULL)
2734 0 : ic->ic_ampdu_rx_stop(ic, ni, tid);
2735 :
2736 0 : ba->ba_state = IEEE80211_BA_INIT;
2737 : /* stop Block Ack inactivity timer */
2738 0 : timeout_del(&ba->ba_to);
2739 0 : timeout_del(&ba->ba_gap_to);
2740 :
2741 0 : if (ba->ba_buf != NULL) {
2742 : /* free all MSDUs stored in reordering buffer */
2743 0 : for (i = 0; i < IEEE80211_BA_MAX_WINSZ; i++)
2744 0 : m_freem(ba->ba_buf[i].m);
2745 : /* free reordering buffer */
2746 0 : free(ba->ba_buf, M_DEVBUF,
2747 : IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf));
2748 0 : ba->ba_buf = NULL;
2749 0 : }
2750 0 : } else {
2751 : /* MLME-DELBA.indication(Recipient) */
2752 0 : struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
2753 :
2754 0 : if (ba->ba_state != IEEE80211_BA_AGREED) {
2755 : DPRINTF(("no matching Block Ack agreement\n"));
2756 0 : return;
2757 : }
2758 : /* notify drivers of the end of the Block Ack agreement */
2759 0 : if (ic->ic_ampdu_tx_stop != NULL)
2760 0 : ic->ic_ampdu_tx_stop(ic, ni, tid);
2761 :
2762 0 : ba->ba_state = IEEE80211_BA_INIT;
2763 : /* stop Block Ack inactivity timer */
2764 0 : timeout_del(&ba->ba_to);
2765 0 : }
2766 0 : }
2767 :
2768 : /*-
2769 : * SA Query Request frame format:
2770 : * [1] Category
2771 : * [1] Action
2772 : * [2] Transaction Identifier
2773 : */
2774 : void
2775 0 : ieee80211_recv_sa_query_req(struct ieee80211com *ic, struct mbuf *m,
2776 : struct ieee80211_node *ni)
2777 : {
2778 : const struct ieee80211_frame *wh;
2779 : const u_int8_t *frm;
2780 :
2781 0 : if (ic->ic_opmode != IEEE80211_M_STA ||
2782 0 : !(ni->ni_flags & IEEE80211_NODE_MFP)) {
2783 : DPRINTF(("unexpected SA Query req from %s\n",
2784 : ether_sprintf(ni->ni_macaddr)));
2785 0 : return;
2786 : }
2787 0 : if (m->m_len < sizeof(*wh) + 4) {
2788 : DPRINTF(("frame too short\n"));
2789 0 : return;
2790 : }
2791 0 : wh = mtod(m, struct ieee80211_frame *);
2792 0 : frm = (const u_int8_t *)&wh[1];
2793 :
2794 : /* MLME-SAQuery.indication */
2795 :
2796 : /* save Transaction Identifier for SA Query Response */
2797 0 : ni->ni_sa_query_trid = LE_READ_2(&frm[2]);
2798 :
2799 : /* MLME-SAQuery.response */
2800 0 : IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_SA_QUERY,
2801 : IEEE80211_ACTION_SA_QUERY_RESP, 0);
2802 0 : }
2803 :
2804 : #ifndef IEEE80211_STA_ONLY
2805 : /*-
2806 : * SA Query Response frame format:
2807 : * [1] Category
2808 : * [1] Action
2809 : * [2] Transaction Identifier
2810 : */
2811 : void
2812 0 : ieee80211_recv_sa_query_resp(struct ieee80211com *ic, struct mbuf *m,
2813 : struct ieee80211_node *ni)
2814 : {
2815 : const struct ieee80211_frame *wh;
2816 : const u_int8_t *frm;
2817 :
2818 : /* ignore if we're not engaged in an SA Query with that STA */
2819 0 : if (!(ni->ni_flags & IEEE80211_NODE_SA_QUERY)) {
2820 : DPRINTF(("unexpected SA Query resp from %s\n",
2821 : ether_sprintf(ni->ni_macaddr)));
2822 0 : return;
2823 : }
2824 0 : if (m->m_len < sizeof(*wh) + 4) {
2825 : DPRINTF(("frame too short\n"));
2826 0 : return;
2827 : }
2828 0 : wh = mtod(m, struct ieee80211_frame *);
2829 0 : frm = (const u_int8_t *)&wh[1];
2830 :
2831 : /* check that Transaction Identifier matches */
2832 0 : if (ni->ni_sa_query_trid != LE_READ_2(&frm[2])) {
2833 : DPRINTF(("transaction identifier does not match\n"));
2834 0 : return;
2835 : }
2836 : /* MLME-SAQuery.confirm */
2837 0 : timeout_del(&ni->ni_sa_query_to);
2838 0 : ni->ni_flags &= ~IEEE80211_NODE_SA_QUERY;
2839 0 : }
2840 : #endif
2841 :
2842 : /*-
2843 : * Action frame format:
2844 : * [1] Category
2845 : * [1] Action
2846 : */
2847 : void
2848 0 : ieee80211_recv_action(struct ieee80211com *ic, struct mbuf *m,
2849 : struct ieee80211_node *ni)
2850 : {
2851 : const struct ieee80211_frame *wh;
2852 : const u_int8_t *frm;
2853 :
2854 0 : if (m->m_len < sizeof(*wh) + 2) {
2855 : DPRINTF(("frame too short\n"));
2856 0 : return;
2857 : }
2858 0 : wh = mtod(m, struct ieee80211_frame *);
2859 0 : frm = (const u_int8_t *)&wh[1];
2860 :
2861 0 : switch (frm[0]) {
2862 : case IEEE80211_CATEG_BA:
2863 0 : switch (frm[1]) {
2864 : case IEEE80211_ACTION_ADDBA_REQ:
2865 0 : ieee80211_recv_addba_req(ic, m, ni);
2866 0 : break;
2867 : case IEEE80211_ACTION_ADDBA_RESP:
2868 0 : ieee80211_recv_addba_resp(ic, m, ni);
2869 0 : break;
2870 : case IEEE80211_ACTION_DELBA:
2871 0 : ieee80211_recv_delba(ic, m, ni);
2872 0 : break;
2873 : }
2874 : break;
2875 : case IEEE80211_CATEG_SA_QUERY:
2876 0 : switch (frm[1]) {
2877 : case IEEE80211_ACTION_SA_QUERY_REQ:
2878 0 : ieee80211_recv_sa_query_req(ic, m, ni);
2879 0 : break;
2880 : #ifndef IEEE80211_STA_ONLY
2881 : case IEEE80211_ACTION_SA_QUERY_RESP:
2882 0 : ieee80211_recv_sa_query_resp(ic, m, ni);
2883 0 : break;
2884 : #endif
2885 : }
2886 : break;
2887 : default:
2888 : DPRINTF(("action frame category %d not handled\n", frm[0]));
2889 : break;
2890 : }
2891 0 : }
2892 :
2893 : void
2894 0 : ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
2895 : struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int subtype)
2896 : {
2897 0 : switch (subtype) {
2898 : case IEEE80211_FC0_SUBTYPE_BEACON:
2899 0 : ieee80211_recv_probe_resp(ic, m, ni, rxi, 0);
2900 0 : break;
2901 : case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
2902 0 : ieee80211_recv_probe_resp(ic, m, ni, rxi, 1);
2903 0 : break;
2904 : #ifndef IEEE80211_STA_ONLY
2905 : case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
2906 0 : ieee80211_recv_probe_req(ic, m, ni, rxi);
2907 0 : break;
2908 : #endif
2909 : case IEEE80211_FC0_SUBTYPE_AUTH:
2910 0 : ieee80211_recv_auth(ic, m, ni, rxi);
2911 0 : break;
2912 : #ifndef IEEE80211_STA_ONLY
2913 : case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
2914 0 : ieee80211_recv_assoc_req(ic, m, ni, rxi, 0);
2915 0 : break;
2916 : case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
2917 0 : ieee80211_recv_assoc_req(ic, m, ni, rxi, 1);
2918 0 : break;
2919 : #endif
2920 : case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
2921 0 : ieee80211_recv_assoc_resp(ic, m, ni, 0);
2922 0 : break;
2923 : case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
2924 0 : ieee80211_recv_assoc_resp(ic, m, ni, 1);
2925 0 : break;
2926 : case IEEE80211_FC0_SUBTYPE_DEAUTH:
2927 0 : ieee80211_recv_deauth(ic, m, ni);
2928 0 : break;
2929 : case IEEE80211_FC0_SUBTYPE_DISASSOC:
2930 0 : ieee80211_recv_disassoc(ic, m, ni);
2931 0 : break;
2932 : case IEEE80211_FC0_SUBTYPE_ACTION:
2933 0 : ieee80211_recv_action(ic, m, ni);
2934 0 : break;
2935 : default:
2936 : DPRINTF(("mgmt frame with subtype 0x%x not handled\n",
2937 : subtype));
2938 0 : ic->ic_stats.is_rx_badsubtype++;
2939 0 : break;
2940 : }
2941 0 : }
2942 :
2943 : #ifndef IEEE80211_STA_ONLY
2944 : /*
2945 : * Process an incoming PS-Poll control frame (see 11.2).
2946 : */
2947 : void
2948 0 : ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m,
2949 : struct ieee80211_node *ni)
2950 : {
2951 0 : struct ifnet *ifp = &ic->ic_if;
2952 : struct ieee80211_frame_pspoll *psp;
2953 : struct ieee80211_frame *wh;
2954 : u_int16_t aid;
2955 :
2956 0 : if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
2957 0 : !(ic->ic_caps & IEEE80211_C_APPMGT) ||
2958 0 : ni->ni_state != IEEE80211_STA_ASSOC)
2959 0 : return;
2960 :
2961 0 : if (m->m_len < sizeof(*psp)) {
2962 : DPRINTF(("frame too short, len %u\n", m->m_len));
2963 0 : ic->ic_stats.is_rx_tooshort++;
2964 0 : return;
2965 : }
2966 0 : psp = mtod(m, struct ieee80211_frame_pspoll *);
2967 0 : if (!IEEE80211_ADDR_EQ(psp->i_bssid, ic->ic_bss->ni_bssid)) {
2968 : DPRINTF(("discard pspoll frame to BSS %s\n",
2969 : ether_sprintf(psp->i_bssid)));
2970 0 : ic->ic_stats.is_rx_wrongbss++;
2971 0 : return;
2972 : }
2973 0 : aid = letoh16(*(u_int16_t *)psp->i_aid);
2974 0 : if (aid != ni->ni_associd) {
2975 : DPRINTF(("invalid pspoll aid %x from %s\n", aid,
2976 : ether_sprintf(psp->i_ta)));
2977 0 : return;
2978 : }
2979 :
2980 : /* take the first queued frame and put it out.. */
2981 0 : m = mq_dequeue(&ni->ni_savedq);
2982 0 : if (m == NULL)
2983 0 : return;
2984 0 : if (mq_empty(&ni->ni_savedq)) {
2985 : /* last queued frame, turn off the TIM bit */
2986 0 : (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
2987 0 : } else {
2988 : /* more queued frames, set the more data bit */
2989 0 : wh = mtod(m, struct ieee80211_frame *);
2990 0 : wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
2991 : }
2992 0 : mq_enqueue(&ic->ic_pwrsaveq, m);
2993 0 : if_start(ifp);
2994 0 : }
2995 : #endif /* IEEE80211_STA_ONLY */
2996 :
2997 : /*
2998 : * Process an incoming BlockAckReq control frame (see 7.2.1.7).
2999 : */
3000 : void
3001 0 : ieee80211_recv_bar(struct ieee80211com *ic, struct mbuf *m,
3002 : struct ieee80211_node *ni)
3003 : {
3004 : const struct ieee80211_frame_min *wh;
3005 : const u_int8_t *frm;
3006 : u_int16_t ctl, ssn;
3007 : u_int8_t tid, ntids;
3008 :
3009 0 : if (!(ni->ni_flags & IEEE80211_NODE_HT)) {
3010 : DPRINTF(("received BlockAckReq from non-HT STA %s\n",
3011 : ether_sprintf(ni->ni_macaddr)));
3012 0 : return;
3013 : }
3014 0 : if (m->m_len < sizeof(*wh) + 4) {
3015 : DPRINTF(("frame too short\n"));
3016 0 : return;
3017 : }
3018 0 : wh = mtod(m, struct ieee80211_frame_min *);
3019 0 : frm = (const u_int8_t *)&wh[1];
3020 :
3021 : /* read BlockAckReq Control field */
3022 0 : ctl = LE_READ_2(&frm[0]);
3023 0 : tid = ctl >> 12;
3024 :
3025 : /* determine BlockAckReq frame variant */
3026 0 : if (ctl & IEEE80211_BA_MULTI_TID) {
3027 : /* Multi-TID BlockAckReq variant (PSMP only) */
3028 0 : ntids = tid + 1;
3029 :
3030 0 : if (m->m_len < sizeof(*wh) + 2 + 4 * ntids) {
3031 : DPRINTF(("MTBAR frame too short\n"));
3032 0 : return;
3033 : }
3034 0 : frm += 2; /* skip BlockAckReq Control field */
3035 0 : while (ntids-- > 0) {
3036 : /* read MTBAR Information field */
3037 0 : tid = LE_READ_2(&frm[0]) >> 12;
3038 0 : ssn = LE_READ_2(&frm[2]) >> 4;
3039 0 : ieee80211_bar_tid(ic, ni, tid, ssn);
3040 0 : frm += 4;
3041 : }
3042 : } else {
3043 : /* Basic or Compressed BlockAckReq variants */
3044 0 : ssn = LE_READ_2(&frm[2]) >> 4;
3045 0 : ieee80211_bar_tid(ic, ni, tid, ssn);
3046 : }
3047 0 : }
3048 :
3049 : /*
3050 : * Process a BlockAckReq for a specific TID (see 9.10.7.6.3).
3051 : * This is the common back-end for all BlockAckReq frame variants.
3052 : */
3053 : void
3054 0 : ieee80211_bar_tid(struct ieee80211com *ic, struct ieee80211_node *ni,
3055 : u_int8_t tid, u_int16_t ssn)
3056 : {
3057 0 : struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
3058 :
3059 : /* check if we have a Block Ack agreement for RA/TID */
3060 0 : if (ba->ba_state != IEEE80211_BA_AGREED) {
3061 : /* XXX not sure in PBAC case */
3062 : /* send a DELBA with reason code UNKNOWN-BA */
3063 0 : IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
3064 : IEEE80211_ACTION_DELBA,
3065 : IEEE80211_REASON_SETUP_REQUIRED << 16 | tid);
3066 0 : return;
3067 : }
3068 : /* check if it is a Protected Block Ack agreement */
3069 0 : if ((ni->ni_flags & IEEE80211_NODE_MFP) &&
3070 0 : (ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC)) {
3071 : /* ADDBA Requests must be used in PBAC case */
3072 0 : if (SEQ_LT(ssn, ba->ba_winstart) ||
3073 0 : SEQ_LT(ba->ba_winend, ssn))
3074 0 : ic->ic_stats.is_pbac_errs++;
3075 0 : return; /* PBAC, do not move window */
3076 : }
3077 : /* reset Block Ack inactivity timer */
3078 0 : if (ba->ba_timeout_val != 0)
3079 0 : timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
3080 :
3081 0 : if (SEQ_LT(ba->ba_winstart, ssn))
3082 0 : ieee80211_ba_move_window(ic, ni, tid, ssn);
3083 0 : }
|