1 /*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD: releng/6.3/sys/net80211/ieee80211_input.c 173109 2007-10-28 18:04:15Z sam $");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/mbuf.h>
39 #include <sys/malloc.h>
40 #include <sys/endian.h>
41 #include <sys/kernel.h>
42
43 #include <sys/socket.h>
44
45 #include <net/if.h>
46 #include <net/if_media.h>
47 #include <net/ethernet.h>
48 #include <net/if_llc.h>
49 #include <net/if_vlan_var.h>
50
51 #include <net80211/ieee80211_var.h>
52
53 #include <net/bpf.h>
54
55 #ifdef IEEE80211_DEBUG
56 #include <machine/stdarg.h>
57
58 /*
59 * Decide if a received management frame should be
60 * printed when debugging is enabled. This filters some
61 * of the less interesting frames that come frequently
62 * (e.g. beacons).
63 */
64 static __inline int
65 doprint(struct ieee80211com *ic, int subtype)
66 {
67 switch (subtype) {
68 case IEEE80211_FC0_SUBTYPE_BEACON:
69 return (ic->ic_flags & IEEE80211_F_SCAN);
70 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
71 return (ic->ic_opmode == IEEE80211_M_IBSS);
72 }
73 return 1;
74 }
75
76 static const u_int8_t *ieee80211_getbssid(struct ieee80211com *,
77 const struct ieee80211_frame *);
78 #endif /* IEEE80211_DEBUG */
79
80 static struct mbuf *ieee80211_defrag(struct ieee80211com *,
81 struct ieee80211_node *, struct mbuf *, int);
82 static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *, int);
83 static void ieee80211_send_error(struct ieee80211com *, struct ieee80211_node *,
84 const u_int8_t *mac, int subtype, int arg);
85 static void ieee80211_deliver_data(struct ieee80211com *,
86 struct ieee80211_node *, struct mbuf *);
87 static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
88 static void ieee80211_recv_pspoll(struct ieee80211com *,
89 struct ieee80211_node *, struct mbuf *);
90
91 /*
92 * Process a received frame. The node associated with the sender
93 * should be supplied. If nothing was found in the node table then
94 * the caller is assumed to supply a reference to ic_bss instead.
95 * The RSSI and a timestamp are also supplied. The RSSI data is used
96 * during AP scanning to select a AP to associate with; it can have
97 * any units so long as values have consistent units and higher values
98 * mean ``better signal''. The receive timestamp is currently not used
99 * by the 802.11 layer.
100 */
101 int
102 ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
103 struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
104 {
105 #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
106 #define HAS_SEQ(type) ((type & 0x4) == 0)
107 struct ifnet *ifp = ic->ic_ifp;
108 struct ieee80211_frame *wh;
109 struct ieee80211_key *key;
110 struct ether_header *eh;
111 int hdrspace;
112 u_int8_t dir, type, subtype;
113 u_int8_t *bssid;
114 u_int16_t rxseq;
115
116 KASSERT(ni != NULL, ("null node"));
117 ni->ni_inact = ni->ni_inact_reload;
118
119 /* trim CRC here so WEP can find its own CRC at the end of packet. */
120 if (m->m_flags & M_HASFCS) {
121 m_adj(m, -IEEE80211_CRC_LEN);
122 m->m_flags &= ~M_HASFCS;
123 }
124 type = -1; /* undefined */
125 /*
126 * In monitor mode, send everything directly to bpf.
127 * XXX may want to include the CRC
128 */
129 if (ic->ic_opmode == IEEE80211_M_MONITOR)
130 goto out;
131
132 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
133 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
134 ni->ni_macaddr, NULL,
135 "too short (1): len %u", m->m_pkthdr.len);
136 ic->ic_stats.is_rx_tooshort++;
137 goto out;
138 }
139 /*
140 * Bit of a cheat here, we use a pointer for a 3-address
141 * frame format but don't reference fields past outside
142 * ieee80211_frame_min w/o first validating the data is
143 * present.
144 */
145 wh = mtod(m, struct ieee80211_frame *);
146
147 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
148 IEEE80211_FC0_VERSION_0) {
149 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
150 ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]);
151 ic->ic_stats.is_rx_badversion++;
152 goto err;
153 }
154
155 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
156 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
157 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
158 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
159 switch (ic->ic_opmode) {
160 case IEEE80211_M_STA:
161 bssid = wh->i_addr2;
162 if (!IEEE80211_ADDR_EQ(bssid, ni->ni_bssid)) {
163 /* not interested in */
164 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
165 bssid, NULL, "%s", "not to bss");
166 ic->ic_stats.is_rx_wrongbss++;
167 goto out;
168 }
169 break;
170 case IEEE80211_M_IBSS:
171 case IEEE80211_M_AHDEMO:
172 case IEEE80211_M_HOSTAP:
173 if (dir != IEEE80211_FC1_DIR_NODS)
174 bssid = wh->i_addr1;
175 else if (type == IEEE80211_FC0_TYPE_CTL)
176 bssid = wh->i_addr1;
177 else {
178 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
179 IEEE80211_DISCARD_MAC(ic,
180 IEEE80211_MSG_ANY, ni->ni_macaddr,
181 NULL, "too short (2): len %u",
182 m->m_pkthdr.len);
183 ic->ic_stats.is_rx_tooshort++;
184 goto out;
185 }
186 bssid = wh->i_addr3;
187 }
188 if (type != IEEE80211_FC0_TYPE_DATA)
189 break;
190 /*
191 * Data frame, validate the bssid.
192 */
193 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) &&
194 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
195 /* not interested in */
196 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
197 bssid, NULL, "%s", "not to bss");
198 ic->ic_stats.is_rx_wrongbss++;
199 goto out;
200 }
201 /*
202 * For adhoc mode we cons up a node when it doesn't
203 * exist. This should probably done after an ACL check.
204 */
205 if (ni == ic->ic_bss &&
206 ic->ic_opmode != IEEE80211_M_HOSTAP &&
207 !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
208 /*
209 * Fake up a node for this newly
210 * discovered member of the IBSS.
211 */
212 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
213 wh->i_addr2);
214 if (ni == NULL) {
215 /* NB: stat kept for alloc failure */
216 goto err;
217 }
218 }
219 break;
220 default:
221 goto out;
222 }
223 ni->ni_rssi = rssi;
224 ni->ni_rstamp = rstamp;
225 if (HAS_SEQ(type)) {
226 u_int8_t tid;
227 if (IEEE80211_QOS_HAS_SEQ(wh)) {
228 tid = ((struct ieee80211_qosframe *)wh)->
229 i_qos[0] & IEEE80211_QOS_TID;
230 if (TID_TO_WME_AC(tid) >= WME_AC_VI)
231 ic->ic_wme.wme_hipri_traffic++;
232 tid++;
233 } else
234 tid = IEEE80211_NONQOS_TID;
235 rxseq = le16toh(*(u_int16_t *)wh->i_seq);
236 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
237 SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
238 /* duplicate, discard */
239 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
240 bssid, "duplicate",
241 "seqno <%u,%u> fragno <%u,%u> tid %u",
242 rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
243 ni->ni_rxseqs[tid] >>
244 IEEE80211_SEQ_SEQ_SHIFT,
245 rxseq & IEEE80211_SEQ_FRAG_MASK,
246 ni->ni_rxseqs[tid] &
247 IEEE80211_SEQ_FRAG_MASK,
248 tid);
249 ic->ic_stats.is_rx_dup++;
250 IEEE80211_NODE_STAT(ni, rx_dup);
251 goto out;
252 }
253 ni->ni_rxseqs[tid] = rxseq;
254 }
255 }
256
257 switch (type) {
258 case IEEE80211_FC0_TYPE_DATA:
259 hdrspace = ieee80211_hdrspace(ic, wh);
260 if (m->m_len < hdrspace &&
261 (m = m_pullup(m, hdrspace)) == NULL) {
262 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
263 ni->ni_macaddr, NULL,
264 "data too short: expecting %u", hdrspace);
265 ic->ic_stats.is_rx_tooshort++;
266 goto out; /* XXX */
267 }
268 switch (ic->ic_opmode) {
269 case IEEE80211_M_STA:
270 if (dir != IEEE80211_FC1_DIR_FROMDS) {
271 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
272 wh, "data", "%s", "unknown dir 0x%x", dir);
273 ic->ic_stats.is_rx_wrongdir++;
274 goto out;
275 }
276 if ((ifp->if_flags & IFF_SIMPLEX) &&
277 IEEE80211_IS_MULTICAST(wh->i_addr1) &&
278 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
279 /*
280 * In IEEE802.11 network, multicast packet
281 * sent from me is broadcasted from AP.
282 * It should be silently discarded for
283 * SIMPLEX interface.
284 */
285 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
286 wh, NULL, "%s", "multicast echo");
287 ic->ic_stats.is_rx_mcastecho++;
288 goto out;
289 }
290 break;
291 case IEEE80211_M_IBSS:
292 case IEEE80211_M_AHDEMO:
293 if (dir != IEEE80211_FC1_DIR_NODS) {
294 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
295 wh, "data", "%s", "unknown dir 0x%x", dir);
296 ic->ic_stats.is_rx_wrongdir++;
297 goto out;
298 }
299 /* XXX no power-save support */
300 break;
301 case IEEE80211_M_HOSTAP:
302 if (dir != IEEE80211_FC1_DIR_TODS) {
303 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
304 wh, "data", "%s", "unknown dir 0x%x", dir);
305 ic->ic_stats.is_rx_wrongdir++;
306 goto out;
307 }
308 /* check if source STA is associated */
309 if (ni == ic->ic_bss) {
310 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
311 wh, "data", "%s", "unknown src");
312 ieee80211_send_error(ic, ni, wh->i_addr2,
313 IEEE80211_FC0_SUBTYPE_DEAUTH,
314 IEEE80211_REASON_NOT_AUTHED);
315 ic->ic_stats.is_rx_notassoc++;
316 goto err;
317 }
318 if (ni->ni_associd == 0) {
319 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
320 wh, "data", "%s", "unassoc src");
321 IEEE80211_SEND_MGMT(ic, ni,
322 IEEE80211_FC0_SUBTYPE_DISASSOC,
323 IEEE80211_REASON_NOT_ASSOCED);
324 ic->ic_stats.is_rx_notassoc++;
325 goto err;
326 }
327
328 /*
329 * Check for power save state change.
330 */
331 if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^
332 (ni->ni_flags & IEEE80211_NODE_PWR_MGT)))
333 ieee80211_node_pwrsave(ni,
334 wh->i_fc[1] & IEEE80211_FC1_PWR_MGT);
335 break;
336 default:
337 /* XXX here to keep compiler happy */
338 goto out;
339 }
340
341 /*
342 * Handle privacy requirements. Note that we
343 * must not be preempted from here until after
344 * we (potentially) call ieee80211_crypto_demic;
345 * otherwise we may violate assumptions in the
346 * crypto cipher modules used to do delayed update
347 * of replay sequence numbers.
348 */
349 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
350 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
351 /*
352 * Discard encrypted frames when privacy is off.
353 */
354 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
355 wh, "WEP", "%s", "PRIVACY off");
356 ic->ic_stats.is_rx_noprivacy++;
357 IEEE80211_NODE_STAT(ni, rx_noprivacy);
358 goto out;
359 }
360 key = ieee80211_crypto_decap(ic, ni, m, hdrspace);
361 if (key == NULL) {
362 /* NB: stats+msgs handled in crypto_decap */
363 IEEE80211_NODE_STAT(ni, rx_wepfail);
364 goto out;
365 }
366 wh = mtod(m, struct ieee80211_frame *);
367 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
368 } else {
369 key = NULL;
370 }
371
372 /*
373 * Next up, any fragmentation.
374 */
375 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
376 m = ieee80211_defrag(ic, ni, m, hdrspace);
377 if (m == NULL) {
378 /* Fragment dropped or frame not complete yet */
379 goto out;
380 }
381 }
382 wh = NULL; /* no longer valid, catch any uses */
383
384 /*
385 * Next strip any MSDU crypto bits.
386 */
387 if (key != NULL && !ieee80211_crypto_demic(ic, key, m, 0)) {
388 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
389 ni->ni_macaddr, "data", "%s", "demic error");
390 ic->ic_stats.is_rx_demicfail++;
391 IEEE80211_NODE_STAT(ni, rx_demicfail);
392 goto out;
393 }
394
395 /* copy to listener after decrypt */
396 if (bpf_peers_present(ic->ic_rawbpf))
397 bpf_mtap(ic->ic_rawbpf, m);
398
399 /*
400 * Finally, strip the 802.11 header.
401 */
402 m = ieee80211_decap(ic, m, hdrspace);
403 if (m == NULL) {
404 /* don't count Null data frames as errors */
405 if (subtype == IEEE80211_FC0_SUBTYPE_NODATA)
406 goto out;
407 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
408 ni->ni_macaddr, "data", "%s", "decap error");
409 ic->ic_stats.is_rx_decap++;
410 IEEE80211_NODE_STAT(ni, rx_decap);
411 goto err;
412 }
413 eh = mtod(m, struct ether_header *);
414 if (!ieee80211_node_is_authorized(ni)) {
415 /*
416 * Deny any non-PAE frames received prior to
417 * authorization. For open/shared-key
418 * authentication the port is mark authorized
419 * after authentication completes. For 802.1x
420 * the port is not marked authorized by the
421 * authenticator until the handshake has completed.
422 */
423 if (eh->ether_type != htons(ETHERTYPE_PAE)) {
424 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
425 eh->ether_shost, "data",
426 "unauthorized port: ether type 0x%x len %u",
427 eh->ether_type, m->m_pkthdr.len);
428 ic->ic_stats.is_rx_unauth++;
429 IEEE80211_NODE_STAT(ni, rx_unauth);
430 goto err;
431 }
432 } else {
433 /*
434 * When denying unencrypted frames, discard
435 * any non-PAE frames received without encryption.
436 */
437 if ((ic->ic_flags & IEEE80211_F_DROPUNENC) &&
438 key == NULL &&
439 eh->ether_type != htons(ETHERTYPE_PAE)) {
440 /*
441 * Drop unencrypted frames.
442 */
443 ic->ic_stats.is_rx_unencrypted++;
444 IEEE80211_NODE_STAT(ni, rx_unencrypted);
445 goto out;
446 }
447 }
448 ieee80211_deliver_data(ic, ni, m);
449 return IEEE80211_FC0_TYPE_DATA;
450
451 case IEEE80211_FC0_TYPE_MGT:
452 ic->ic_stats.is_rx_mgmt++;
453 IEEE80211_NODE_STAT(ni, rx_mgmt);
454 if (dir != IEEE80211_FC1_DIR_NODS) {
455 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
456 wh, "data", "%s", "unknown dir 0x%x", dir);
457 ic->ic_stats.is_rx_wrongdir++;
458 goto err;
459 }
460 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
461 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
462 ni->ni_macaddr, "mgt", "too short: len %u",
463 m->m_pkthdr.len);
464 ic->ic_stats.is_rx_tooshort++;
465 goto out;
466 }
467 #ifdef IEEE80211_DEBUG
468 if ((ieee80211_msg_debug(ic) && doprint(ic, subtype)) ||
469 ieee80211_msg_dumppkts(ic)) {
470 if_printf(ic->ic_ifp, "received %s from %s rssi %d\n",
471 ieee80211_mgt_subtype_name[subtype >>
472 IEEE80211_FC0_SUBTYPE_SHIFT],
473 ether_sprintf(wh->i_addr2), rssi);
474 }
475 #endif
476 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
477 if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) {
478 /*
479 * Only shared key auth frames with a challenge
480 * should be encrypted, discard all others.
481 */
482 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
483 wh, ieee80211_mgt_subtype_name[subtype >>
484 IEEE80211_FC0_SUBTYPE_SHIFT],
485 "%s", "WEP set but not permitted");
486 ic->ic_stats.is_rx_mgtdiscard++; /* XXX */
487 goto out;
488 }
489 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
490 /*
491 * Discard encrypted frames when privacy is off.
492 */
493 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
494 wh, "mgt", "%s", "WEP set but PRIVACY off");
495 ic->ic_stats.is_rx_noprivacy++;
496 goto out;
497 }
498 hdrspace = ieee80211_hdrspace(ic, wh);
499 key = ieee80211_crypto_decap(ic, ni, m, hdrspace);
500 if (key == NULL) {
501 /* NB: stats+msgs handled in crypto_decap */
502 goto out;
503 }
504 wh = mtod(m, struct ieee80211_frame *);
505 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
506 }
507 if (bpf_peers_present(ic->ic_rawbpf))
508 bpf_mtap(ic->ic_rawbpf, m);
509 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
510 m_freem(m);
511 return type;
512
513 case IEEE80211_FC0_TYPE_CTL:
514 ic->ic_stats.is_rx_ctl++;
515 IEEE80211_NODE_STAT(ni, rx_ctrl);
516 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
517 switch (subtype) {
518 case IEEE80211_FC0_SUBTYPE_PS_POLL:
519 ieee80211_recv_pspoll(ic, ni, m);
520 break;
521 }
522 }
523 goto out;
524 default:
525 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
526 wh, NULL, "bad frame type 0x%x", type);
527 /* should not come here */
528 break;
529 }
530 err:
531 ifp->if_ierrors++;
532 out:
533 if (m != NULL) {
534 if (bpf_peers_present(ic->ic_rawbpf))
535 bpf_mtap(ic->ic_rawbpf, m);
536 m_freem(m);
537 }
538 return type;
539 #undef SEQ_LEQ
540 }
541
542 /*
543 * This function reassemble fragments.
544 */
545 static struct mbuf *
546 ieee80211_defrag(struct ieee80211com *ic, struct ieee80211_node *ni,
547 struct mbuf *m, int hdrspace)
548 {
549 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
550 struct ieee80211_frame *lwh;
551 u_int16_t rxseq;
552 u_int8_t fragno;
553 u_int8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
554 struct mbuf *mfrag;
555
556 KASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?"));
557
558 rxseq = le16toh(*(u_int16_t *)wh->i_seq);
559 fragno = rxseq & IEEE80211_SEQ_FRAG_MASK;
560
561 /* Quick way out, if there's nothing to defragment */
562 if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL)
563 return m;
564
565 /*
566 * Remove frag to insure it doesn't get reaped by timer.
567 */
568 if (ni->ni_table == NULL) {
569 /*
570 * Should never happen. If the node is orphaned (not in
571 * the table) then input packets should not reach here.
572 * Otherwise, a concurrent request that yanks the table
573 * should be blocked by other interlocking and/or by first
574 * shutting the driver down. Regardless, be defensive
575 * here and just bail
576 */
577 /* XXX need msg+stat */
578 m_freem(m);
579 return NULL;
580 }
581 IEEE80211_NODE_LOCK(ni->ni_table);
582 mfrag = ni->ni_rxfrag[0];
583 ni->ni_rxfrag[0] = NULL;
584 IEEE80211_NODE_UNLOCK(ni->ni_table);
585
586 /*
587 * Validate new fragment is in order and
588 * related to the previous ones.
589 */
590 if (mfrag != NULL) {
591 u_int16_t last_rxseq;
592
593 lwh = mtod(mfrag, struct ieee80211_frame *);
594 last_rxseq = le16toh(*(u_int16_t *)lwh->i_seq);
595 /* NB: check seq # and frag together */
596 if (rxseq != last_rxseq+1 ||
597 !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) ||
598 !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) {
599 /*
600 * Unrelated fragment or no space for it,
601 * clear current fragments.
602 */
603 m_freem(mfrag);
604 mfrag = NULL;
605 }
606 }
607
608 if (mfrag == NULL) {
609 if (fragno != 0) { /* !first fragment, discard */
610 ic->ic_stats.is_rx_defrag++;
611 IEEE80211_NODE_STAT(ni, rx_defrag);
612 m_freem(m);
613 return NULL;
614 }
615 mfrag = m;
616 } else { /* concatenate */
617 m_adj(m, hdrspace); /* strip header */
618 m_cat(mfrag, m);
619 /* NB: m_cat doesn't update the packet header */
620 mfrag->m_pkthdr.len += m->m_pkthdr.len;
621 /* track last seqnum and fragno */
622 lwh = mtod(mfrag, struct ieee80211_frame *);
623 *(u_int16_t *) lwh->i_seq = *(u_int16_t *) wh->i_seq;
624 }
625 if (more_frag) { /* more to come, save */
626 ni->ni_rxfragstamp = ticks;
627 ni->ni_rxfrag[0] = mfrag;
628 mfrag = NULL;
629 }
630 return mfrag;
631 }
632
633 static void
634 ieee80211_deliver_data(struct ieee80211com *ic,
635 struct ieee80211_node *ni, struct mbuf *m)
636 {
637 struct ether_header *eh = mtod(m, struct ether_header *);
638 struct ifnet *ifp = ic->ic_ifp;
639
640 /*
641 * Do accounting.
642 */
643 ifp->if_ipackets++;
644 IEEE80211_NODE_STAT(ni, rx_data);
645 IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len);
646 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
647 m->m_flags |= M_MCAST; /* XXX M_BCAST? */
648 IEEE80211_NODE_STAT(ni, rx_mcast);
649 } else
650 IEEE80211_NODE_STAT(ni, rx_ucast);
651
652 /* perform as a bridge within the AP */
653 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
654 (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) {
655 struct mbuf *m1 = NULL;
656
657 if (m->m_flags & M_MCAST) {
658 m1 = m_dup(m, M_DONTWAIT);
659 if (m1 == NULL)
660 ifp->if_oerrors++;
661 else
662 m1->m_flags |= M_MCAST;
663 } else {
664 /*
665 * Check if the destination is known; if so
666 * and the port is authorized dispatch directly.
667 */
668 struct ieee80211_node *sta =
669 ieee80211_find_node(&ic->ic_sta, eh->ether_dhost);
670 if (sta != NULL) {
671 if (ieee80211_node_is_authorized(sta)) {
672 /*
673 * Beware of sending to ourself; this
674 * needs to happen via the normal
675 * input path.
676 */
677 if (sta != ic->ic_bss) {
678 m1 = m;
679 m = NULL;
680 }
681 } else {
682 ic->ic_stats.is_rx_unauth++;
683 IEEE80211_NODE_STAT(sta, rx_unauth);
684 }
685 ieee80211_free_node(sta);
686 }
687 }
688 if (m1 != NULL)
689 IF_HANDOFF(&ifp->if_snd, m1, ifp);
690 }
691 if (m != NULL) {
692 m->m_pkthdr.rcvif = ifp;
693 if (ni->ni_vlan != 0) {
694 /* attach vlan tag */
695 VLAN_INPUT_TAG_NEW(ifp, m, ni->ni_vlan);
696 if (m == NULL)
697 return;
698 }
699 (*ifp->if_input)(ifp, m);
700 }
701 }
702
703 static struct mbuf *
704 ieee80211_decap(struct ieee80211com *ic, struct mbuf *m, int hdrlen)
705 {
706 struct ieee80211_qosframe_addr4 wh; /* Max size address frames */
707 struct ether_header *eh;
708 struct llc *llc;
709
710 if (m->m_len < hdrlen + sizeof(*llc) &&
711 (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) {
712 /* XXX stat, msg */
713 return NULL;
714 }
715 memcpy(&wh, mtod(m, caddr_t), hdrlen);
716 llc = (struct llc *)(mtod(m, caddr_t) + hdrlen);
717 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
718 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
719 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
720 m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh));
721 llc = NULL;
722 } else {
723 m_adj(m, hdrlen - sizeof(*eh));
724 }
725 eh = mtod(m, struct ether_header *);
726 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
727 case IEEE80211_FC1_DIR_NODS:
728 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
729 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
730 break;
731 case IEEE80211_FC1_DIR_TODS:
732 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
733 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
734 break;
735 case IEEE80211_FC1_DIR_FROMDS:
736 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
737 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
738 break;
739 case IEEE80211_FC1_DIR_DSTODS:
740 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
741 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4);
742 break;
743 }
744 #ifdef ALIGNED_POINTER
745 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) {
746 struct mbuf *n, *n0, **np;
747 caddr_t newdata;
748 int off, pktlen;
749
750 n0 = NULL;
751 np = &n0;
752 off = 0;
753 pktlen = m->m_pkthdr.len;
754 while (pktlen > off) {
755 if (n0 == NULL) {
756 MGETHDR(n, M_DONTWAIT, MT_DATA);
757 if (n == NULL) {
758 m_freem(m);
759 return NULL;
760 }
761 M_MOVE_PKTHDR(n, m);
762 n->m_len = MHLEN;
763 } else {
764 MGET(n, M_DONTWAIT, MT_DATA);
765 if (n == NULL) {
766 m_freem(m);
767 m_freem(n0);
768 return NULL;
769 }
770 n->m_len = MLEN;
771 }
772 if (pktlen - off >= MINCLSIZE) {
773 MCLGET(n, M_DONTWAIT);
774 if (n->m_flags & M_EXT)
775 n->m_len = n->m_ext.ext_size;
776 }
777 if (n0 == NULL) {
778 newdata =
779 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) -
780 sizeof(*eh);
781 n->m_len -= newdata - n->m_data;
782 n->m_data = newdata;
783 }
784 if (n->m_len > pktlen - off)
785 n->m_len = pktlen - off;
786 m_copydata(m, off, n->m_len, mtod(n, caddr_t));
787 off += n->m_len;
788 *np = n;
789 np = &n->m_next;
790 }
791 m_freem(m);
792 m = n0;
793 }
794 #endif /* ALIGNED_POINTER */
795 if (llc != NULL) {
796 eh = mtod(m, struct ether_header *);
797 eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh));
798 }
799 return m;
800 }
801
802 /*
803 * Install received rate set information in the node's state block.
804 */
805 int
806 ieee80211_setup_rates(struct ieee80211_node *ni,
807 const u_int8_t *rates, const u_int8_t *xrates, int flags)
808 {
809 struct ieee80211com *ic = ni->ni_ic;
810 struct ieee80211_rateset *rs = &ni->ni_rates;
811
812 memset(rs, 0, sizeof(*rs));
813 rs->rs_nrates = rates[1];
814 memcpy(rs->rs_rates, rates + 2, rs->rs_nrates);
815 if (xrates != NULL) {
816 u_int8_t nxrates;
817 /*
818 * Tack on 11g extended supported rate element.
819 */
820 nxrates = xrates[1];
821 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
822 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
823 IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE,
824 "[%s] extended rate set too large;"
825 " only using %u of %u rates\n",
826 ether_sprintf(ni->ni_macaddr), nxrates, xrates[1]);
827 ic->ic_stats.is_rx_rstoobig++;
828 }
829 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
830 rs->rs_nrates += nxrates;
831 }
832 return ieee80211_fix_rate(ni, flags);
833 }
834
835 static void
836 ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh,
837 struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq,
838 u_int16_t status)
839 {
840
841 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
842 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
843 ni->ni_macaddr, "open auth",
844 "bad sta auth mode %u", ni->ni_authmode);
845 ic->ic_stats.is_rx_bad_auth++; /* XXX */
846 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
847 /*
848 * Clear any challenge text that may be there if
849 * a previous shared key auth failed and then an
850 * open auth is attempted.
851 */
852 if (ni->ni_challenge != NULL) {
853 FREE(ni->ni_challenge, M_DEVBUF);
854 ni->ni_challenge = NULL;
855 }
856 /* XXX hack to workaround calling convention */
857 ieee80211_send_error(ic, ni, wh->i_addr2,
858 IEEE80211_FC0_SUBTYPE_AUTH,
859 (seq + 1) | (IEEE80211_STATUS_ALG<<16));
860 }
861 return;
862 }
863 switch (ic->ic_opmode) {
864 case IEEE80211_M_IBSS:
865 case IEEE80211_M_AHDEMO:
866 case IEEE80211_M_MONITOR:
867 /* should not come here */
868 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
869 ni->ni_macaddr, "open auth",
870 "bad operating mode %u", ic->ic_opmode);
871 break;
872
873 case IEEE80211_M_HOSTAP:
874 if (ic->ic_state != IEEE80211_S_RUN ||
875 seq != IEEE80211_AUTH_OPEN_REQUEST) {
876 ic->ic_stats.is_rx_bad_auth++;
877 return;
878 }
879 /* always accept open authentication requests */
880 if (ni == ic->ic_bss) {
881 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
882 if (ni == NULL)
883 return;
884 } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)
885 (void) ieee80211_ref_node(ni);
886 /*
887 * Mark the node as referenced to reflect that it's
888 * reference count has been bumped to insure it remains
889 * after the transaction completes.
890 */
891 ni->ni_flags |= IEEE80211_NODE_AREF;
892
893 IEEE80211_SEND_MGMT(ic, ni,
894 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
895 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
896 "[%s] station authenticated (open)\n",
897 ether_sprintf(ni->ni_macaddr));
898 /*
899 * When 802.1x is not in use mark the port
900 * authorized at this point so traffic can flow.
901 */
902 if (ni->ni_authmode != IEEE80211_AUTH_8021X)
903 ieee80211_node_authorize(ni);
904 break;
905
906 case IEEE80211_M_STA:
907 if (ic->ic_state != IEEE80211_S_AUTH ||
908 seq != IEEE80211_AUTH_OPEN_RESPONSE) {
909 ic->ic_stats.is_rx_bad_auth++;
910 return;
911 }
912 if (status != 0) {
913 IEEE80211_DPRINTF(ic,
914 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
915 "[%s] open auth failed (reason %d)\n",
916 ether_sprintf(ni->ni_macaddr), status);
917 /* XXX can this happen? */
918 if (ni != ic->ic_bss)
919 ni->ni_fails++;
920 ic->ic_stats.is_rx_auth_fail++;
921 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
922 } else
923 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
924 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
925 break;
926 }
927 }
928
929 /*
930 * Send a management frame error response to the specified
931 * station. If ni is associated with the station then use
932 * it; otherwise allocate a temporary node suitable for
933 * transmitting the frame and then free the reference so
934 * it will go away as soon as the frame has been transmitted.
935 */
936 static void
937 ieee80211_send_error(struct ieee80211com *ic, struct ieee80211_node *ni,
938 const u_int8_t *mac, int subtype, int arg)
939 {
940 int istmp;
941
942 if (ni == ic->ic_bss) {
943 ni = ieee80211_tmp_node(ic, mac);
944 if (ni == NULL) {
945 /* XXX msg */
946 return;
947 }
948 istmp = 1;
949 } else
950 istmp = 0;
951 IEEE80211_SEND_MGMT(ic, ni, subtype, arg);
952 if (istmp)
953 ieee80211_free_node(ni);
954 }
955
956 static int
957 alloc_challenge(struct ieee80211com *ic, struct ieee80211_node *ni)
958 {
959 if (ni->ni_challenge == NULL)
960 MALLOC(ni->ni_challenge, u_int32_t*, IEEE80211_CHALLENGE_LEN,
961 M_DEVBUF, M_NOWAIT);
962 if (ni->ni_challenge == NULL) {
963 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
964 "[%s] shared key challenge alloc failed\n",
965 ether_sprintf(ni->ni_macaddr));
966 /* XXX statistic */
967 }
968 return (ni->ni_challenge != NULL);
969 }
970
971 /* XXX TODO: add statistics */
972 static void
973 ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh,
974 u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi,
975 u_int32_t rstamp, u_int16_t seq, u_int16_t status)
976 {
977 u_int8_t *challenge;
978 int allocbs, estatus;
979
980 /*
981 * NB: this can happen as we allow pre-shared key
982 * authentication to be enabled w/o wep being turned
983 * on so that configuration of these can be done
984 * in any order. It may be better to enforce the
985 * ordering in which case this check would just be
986 * for sanity/consistency.
987 */
988 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
989 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
990 ni->ni_macaddr, "shared key auth",
991 "%s", " PRIVACY is disabled");
992 estatus = IEEE80211_STATUS_ALG;
993 goto bad;
994 }
995 /*
996 * Pre-shared key authentication is evil; accept
997 * it only if explicitly configured (it is supported
998 * mainly for compatibility with clients like OS X).
999 */
1000 if (ni->ni_authmode != IEEE80211_AUTH_AUTO &&
1001 ni->ni_authmode != IEEE80211_AUTH_SHARED) {
1002 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1003 ni->ni_macaddr, "shared key auth",
1004 "bad sta auth mode %u", ni->ni_authmode);
1005 ic->ic_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */
1006 estatus = IEEE80211_STATUS_ALG;
1007 goto bad;
1008 }
1009
1010 challenge = NULL;
1011 if (frm + 1 < efrm) {
1012 if ((frm[1] + 2) > (efrm - frm)) {
1013 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1014 ni->ni_macaddr, "shared key auth",
1015 "ie %d/%d too long",
1016 frm[0], (frm[1] + 2) - (efrm - frm));
1017 ic->ic_stats.is_rx_bad_auth++;
1018 estatus = IEEE80211_STATUS_CHALLENGE;
1019 goto bad;
1020 }
1021 if (*frm == IEEE80211_ELEMID_CHALLENGE)
1022 challenge = frm;
1023 frm += frm[1] + 2;
1024 }
1025 switch (seq) {
1026 case IEEE80211_AUTH_SHARED_CHALLENGE:
1027 case IEEE80211_AUTH_SHARED_RESPONSE:
1028 if (challenge == NULL) {
1029 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1030 ni->ni_macaddr, "shared key auth",
1031 "%s", "no challenge");
1032 ic->ic_stats.is_rx_bad_auth++;
1033 estatus = IEEE80211_STATUS_CHALLENGE;
1034 goto bad;
1035 }
1036 if (challenge[1] != IEEE80211_CHALLENGE_LEN) {
1037 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1038 ni->ni_macaddr, "shared key auth",
1039 "bad challenge len %d", challenge[1]);
1040 ic->ic_stats.is_rx_bad_auth++;
1041 estatus = IEEE80211_STATUS_CHALLENGE;
1042 goto bad;
1043 }
1044 default:
1045 break;
1046 }
1047 switch (ic->ic_opmode) {
1048 case IEEE80211_M_MONITOR:
1049 case IEEE80211_M_AHDEMO:
1050 case IEEE80211_M_IBSS:
1051 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1052 ni->ni_macaddr, "shared key auth",
1053 "bad operating mode %u", ic->ic_opmode);
1054 return;
1055 case IEEE80211_M_HOSTAP:
1056 if (ic->ic_state != IEEE80211_S_RUN) {
1057 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1058 ni->ni_macaddr, "shared key auth",
1059 "bad state %u", ic->ic_state);
1060 estatus = IEEE80211_STATUS_ALG; /* XXX */
1061 goto bad;
1062 }
1063 switch (seq) {
1064 case IEEE80211_AUTH_SHARED_REQUEST:
1065 if (ni == ic->ic_bss) {
1066 ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
1067 if (ni == NULL) {
1068 /* NB: no way to return an error */
1069 return;
1070 }
1071 allocbs = 1;
1072 } else {
1073 if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)
1074 (void) ieee80211_ref_node(ni);
1075 allocbs = 0;
1076 }
1077 /*
1078 * Mark the node as referenced to reflect that it's
1079 * reference count has been bumped to insure it remains
1080 * after the transaction completes.
1081 */
1082 ni->ni_flags |= IEEE80211_NODE_AREF;
1083 ni->ni_rssi = rssi;
1084 ni->ni_rstamp = rstamp;
1085 if (!alloc_challenge(ic, ni)) {
1086 /* NB: don't return error so they rexmit */
1087 return;
1088 }
1089 get_random_bytes(ni->ni_challenge,
1090 IEEE80211_CHALLENGE_LEN);
1091 IEEE80211_DPRINTF(ic,
1092 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1093 "[%s] shared key %sauth request\n",
1094 ether_sprintf(ni->ni_macaddr),
1095 allocbs ? "" : "re");
1096 break;
1097 case IEEE80211_AUTH_SHARED_RESPONSE:
1098 if (ni == ic->ic_bss) {
1099 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1100 ni->ni_macaddr, "shared key response",
1101 "%s", "unknown station");
1102 /* NB: don't send a response */
1103 return;
1104 }
1105 if (ni->ni_challenge == NULL) {
1106 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1107 ni->ni_macaddr, "shared key response",
1108 "%s", "no challenge recorded");
1109 ic->ic_stats.is_rx_bad_auth++;
1110 estatus = IEEE80211_STATUS_CHALLENGE;
1111 goto bad;
1112 }
1113 if (memcmp(ni->ni_challenge, &challenge[2],
1114 challenge[1]) != 0) {
1115 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1116 ni->ni_macaddr, "shared key response",
1117 "%s", "challenge mismatch");
1118 ic->ic_stats.is_rx_auth_fail++;
1119 estatus = IEEE80211_STATUS_CHALLENGE;
1120 goto bad;
1121 }
1122 IEEE80211_DPRINTF(ic,
1123 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1124 "[%s] station authenticated (shared key)\n",
1125 ether_sprintf(ni->ni_macaddr));
1126 ieee80211_node_authorize(ni);
1127 break;
1128 default:
1129 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1130 ni->ni_macaddr, "shared key auth",
1131 "bad seq %d", seq);
1132 ic->ic_stats.is_rx_bad_auth++;
1133 estatus = IEEE80211_STATUS_SEQUENCE;
1134 goto bad;
1135 }
1136 IEEE80211_SEND_MGMT(ic, ni,
1137 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
1138 break;
1139
1140 case IEEE80211_M_STA:
1141 if (ic->ic_state != IEEE80211_S_AUTH)
1142 return;
1143 switch (seq) {
1144 case IEEE80211_AUTH_SHARED_PASS:
1145 if (ni->ni_challenge != NULL) {
1146 FREE(ni->ni_challenge, M_DEVBUF);
1147 ni->ni_challenge = NULL;
1148 }
1149 if (status != 0) {
1150 IEEE80211_DPRINTF(ic,
1151 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1152 "[%s] shared key auth failed (reason %d)\n",
1153 ether_sprintf(ieee80211_getbssid(ic, wh)),
1154 status);
1155 /* XXX can this happen? */
1156 if (ni != ic->ic_bss)
1157 ni->ni_fails++;
1158 ic->ic_stats.is_rx_auth_fail++;
1159 return;
1160 }
1161 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
1162 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1163 break;
1164 case IEEE80211_AUTH_SHARED_CHALLENGE:
1165 if (!alloc_challenge(ic, ni))
1166 return;
1167 /* XXX could optimize by passing recvd challenge */
1168 memcpy(ni->ni_challenge, &challenge[2], challenge[1]);
1169 IEEE80211_SEND_MGMT(ic, ni,
1170 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
1171 break;
1172 default:
1173 IEEE80211_DISCARD(ic, IEEE80211_MSG_AUTH,
1174 wh, "shared key auth", "bad seq %d", seq);
1175 ic->ic_stats.is_rx_bad_auth++;
1176 return;
1177 }
1178 break;
1179 }
1180 return;
1181 bad:
1182 /*
1183 * Send an error response; but only when operating as an AP.
1184 */
1185 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1186 /* XXX hack to workaround calling convention */
1187 ieee80211_send_error(ic, ni, wh->i_addr2,
1188 IEEE80211_FC0_SUBTYPE_AUTH,
1189 (seq + 1) | (estatus<<16));
1190 } else if (ic->ic_opmode == IEEE80211_M_STA) {
1191 /*
1192 * Kick the state machine. This short-circuits
1193 * using the mgt frame timeout to trigger the
1194 * state transition.
1195 */
1196 if (ic->ic_state == IEEE80211_S_AUTH)
1197 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
1198 }
1199 }
1200
1201 /* Verify the existence and length of __elem or get out. */
1202 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
1203 if ((__elem) == NULL) { \
1204 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1205 wh, ieee80211_mgt_subtype_name[subtype >> \
1206 IEEE80211_FC0_SUBTYPE_SHIFT], \
1207 "%s", "no " #__elem ); \
1208 ic->ic_stats.is_rx_elem_missing++; \
1209 return; \
1210 } \
1211 if ((__elem)[1] > (__maxlen)) { \
1212 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1213 wh, ieee80211_mgt_subtype_name[subtype >> \
1214 IEEE80211_FC0_SUBTYPE_SHIFT], \
1215 "bad " #__elem " len %d", (__elem)[1]); \
1216 ic->ic_stats.is_rx_elem_toobig++; \
1217 return; \
1218 } \
1219 } while (0)
1220
1221 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
1222 if ((_len) < (_minlen)) { \
1223 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1224 wh, ieee80211_mgt_subtype_name[subtype >> \
1225 IEEE80211_FC0_SUBTYPE_SHIFT], \
1226 "ie too short, got %d, expected %d", \
1227 (_len), (_minlen)); \
1228 ic->ic_stats.is_rx_elem_toosmall++; \
1229 return; \
1230 } \
1231 } while (0)
1232
1233 #ifdef IEEE80211_DEBUG
1234 static void
1235 ieee80211_ssid_mismatch(struct ieee80211com *ic, const char *tag,
1236 u_int8_t mac[IEEE80211_ADDR_LEN], u_int8_t *ssid)
1237 {
1238 printf("[%s] discard %s frame, ssid mismatch: ",
1239 ether_sprintf(mac), tag);
1240 ieee80211_print_essid(ssid + 2, ssid[1]);
1241 printf("\n");
1242 }
1243
1244 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1245 if ((_ssid)[1] != 0 && \
1246 ((_ssid)[1] != (_ni)->ni_esslen || \
1247 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1248 if (ieee80211_msg_input(ic)) \
1249 ieee80211_ssid_mismatch(ic, \
1250 ieee80211_mgt_subtype_name[subtype >> \
1251 IEEE80211_FC0_SUBTYPE_SHIFT], \
1252 wh->i_addr2, _ssid); \
1253 ic->ic_stats.is_rx_ssidmismatch++; \
1254 return; \
1255 } \
1256 } while (0)
1257 #else /* !IEEE80211_DEBUG */
1258 #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1259 if ((_ssid)[1] != 0 && \
1260 ((_ssid)[1] != (_ni)->ni_esslen || \
1261 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1262 ic->ic_stats.is_rx_ssidmismatch++; \
1263 return; \
1264 } \
1265 } while (0)
1266 #endif /* !IEEE80211_DEBUG */
1267
1268 /* unalligned little endian access */
1269 #define LE_READ_2(p) \
1270 ((u_int16_t) \
1271 ((((const u_int8_t *)(p))[0] ) | \
1272 (((const u_int8_t *)(p))[1] << 8)))
1273 #define LE_READ_4(p) \
1274 ((u_int32_t) \
1275 ((((const u_int8_t *)(p))[0] ) | \
1276 (((const u_int8_t *)(p))[1] << 8) | \
1277 (((const u_int8_t *)(p))[2] << 16) | \
1278 (((const u_int8_t *)(p))[3] << 24)))
1279
1280 static __inline int
1281 iswpaoui(const u_int8_t *frm)
1282 {
1283 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
1284 }
1285
1286 static __inline int
1287 iswmeoui(const u_int8_t *frm)
1288 {
1289 return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI);
1290 }
1291
1292 static __inline int
1293 iswmeparam(const u_int8_t *frm)
1294 {
1295 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1296 frm[6] == WME_PARAM_OUI_SUBTYPE;
1297 }
1298
1299 static __inline int
1300 iswmeinfo(const u_int8_t *frm)
1301 {
1302 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1303 frm[6] == WME_INFO_OUI_SUBTYPE;
1304 }
1305
1306 static __inline int
1307 isatherosoui(const u_int8_t *frm)
1308 {
1309 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
1310 }
1311
1312 /*
1313 * Convert a WPA cipher selector OUI to an internal
1314 * cipher algorithm. Where appropriate we also
1315 * record any key length.
1316 */
1317 static int
1318 wpa_cipher(u_int8_t *sel, u_int8_t *keylen)
1319 {
1320 #define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1321 u_int32_t w = LE_READ_4(sel);
1322
1323 switch (w) {
1324 case WPA_SEL(WPA_CSE_NULL):
1325 return IEEE80211_CIPHER_NONE;
1326 case WPA_SEL(WPA_CSE_WEP40):
1327 if (keylen)
1328 *keylen = 40 / NBBY;
1329 return IEEE80211_CIPHER_WEP;
1330 case WPA_SEL(WPA_CSE_WEP104):
1331 if (keylen)
1332 *keylen = 104 / NBBY;
1333 return IEEE80211_CIPHER_WEP;
1334 case WPA_SEL(WPA_CSE_TKIP):
1335 return IEEE80211_CIPHER_TKIP;
1336 case WPA_SEL(WPA_CSE_CCMP):
1337 return IEEE80211_CIPHER_AES_CCM;
1338 }
1339 return 32; /* NB: so 1<< is discarded */
1340 #undef WPA_SEL
1341 }
1342
1343 /*
1344 * Convert a WPA key management/authentication algorithm
1345 * to an internal code.
1346 */
1347 static int
1348 wpa_keymgmt(u_int8_t *sel)
1349 {
1350 #define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1351 u_int32_t w = LE_READ_4(sel);
1352
1353 switch (w) {
1354 case WPA_SEL(WPA_ASE_8021X_UNSPEC):
1355 return WPA_ASE_8021X_UNSPEC;
1356 case WPA_SEL(WPA_ASE_8021X_PSK):
1357 return WPA_ASE_8021X_PSK;
1358 case WPA_SEL(WPA_ASE_NONE):
1359 return WPA_ASE_NONE;
1360 }
1361 return 0; /* NB: so is discarded */
1362 #undef WPA_SEL
1363 }
1364
1365 /*
1366 * Parse a WPA information element to collect parameters
1367 * and validate the parameters against what has been
1368 * configured for the system.
1369 */
1370 static int
1371 ieee80211_parse_wpa(struct ieee80211com *ic, u_int8_t *frm,
1372 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh)
1373 {
1374 u_int8_t len = frm[1];
1375 u_int32_t w;
1376 int n;
1377
1378 /*
1379 * Check the length once for fixed parts: OUI, type,
1380 * version, mcast cipher, and 2 selector counts.
1381 * Other, variable-length data, must be checked separately.
1382 */
1383 if ((ic->ic_flags & IEEE80211_F_WPA1) == 0) {
1384 IEEE80211_DISCARD_IE(ic,
1385 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1386 wh, "WPA", "not WPA, flags 0x%x", ic->ic_flags);
1387 return IEEE80211_REASON_IE_INVALID;
1388 }
1389 if (len < 14) {
1390 IEEE80211_DISCARD_IE(ic,
1391 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1392 wh, "WPA", "too short, len %u", len);
1393 return IEEE80211_REASON_IE_INVALID;
1394 }
1395 frm += 6, len -= 4; /* NB: len is payload only */
1396 /* NB: iswapoui already validated the OUI and type */
1397 w = LE_READ_2(frm);
1398 if (w != WPA_VERSION) {
1399 IEEE80211_DISCARD_IE(ic,
1400 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1401 wh, "WPA", "bad version %u", w);
1402 return IEEE80211_REASON_IE_INVALID;
1403 }
1404 frm += 2, len -= 2;
1405
1406 /* multicast/group cipher */
1407 w = wpa_cipher(frm, &rsn->rsn_mcastkeylen);
1408 if (w != rsn->rsn_mcastcipher) {
1409 IEEE80211_DISCARD_IE(ic,
1410 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1411 wh, "WPA", "mcast cipher mismatch; got %u, expected %u",
1412 w, rsn->rsn_mcastcipher);
1413 return IEEE80211_REASON_IE_INVALID;
1414 }
1415 frm += 4, len -= 4;
1416
1417 /* unicast ciphers */
1418 n = LE_READ_2(frm);
1419 frm += 2, len -= 2;
1420 if (len < n*4+2) {
1421 IEEE80211_DISCARD_IE(ic,
1422 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1423 wh, "WPA", "ucast cipher data too short; len %u, n %u",
1424 len, n);
1425 return IEEE80211_REASON_IE_INVALID;
1426 }
1427 w = 0;
1428 for (; n > 0; n--) {
1429 w |= 1<<wpa_cipher(frm, &rsn->rsn_ucastkeylen);
1430 frm += 4, len -= 4;
1431 }
1432 w &= rsn->rsn_ucastcipherset;
1433 if (w == 0) {
1434 IEEE80211_DISCARD_IE(ic,
1435 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1436 wh, "WPA", "%s", "ucast cipher set empty");
1437 return IEEE80211_REASON_IE_INVALID;
1438 }
1439 if (w & (1<<IEEE80211_CIPHER_TKIP))
1440 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
1441 else
1442 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
1443
1444 /* key management algorithms */
1445 n = LE_READ_2(frm);
1446 frm += 2, len -= 2;
1447 if (len < n*4) {
1448 IEEE80211_DISCARD_IE(ic,
1449 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1450 wh, "WPA", "key mgmt alg data too short; len %u, n %u",
1451 len, n);
1452 return IEEE80211_REASON_IE_INVALID;
1453 }
1454 w = 0;
1455 for (; n > 0; n--) {
1456 w |= wpa_keymgmt(frm);
1457 frm += 4, len -= 4;
1458 }
1459 w &= rsn->rsn_keymgmtset;
1460 if (w == 0) {
1461 IEEE80211_DISCARD_IE(ic,
1462 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1463 wh, "WPA", "%s", "no acceptable key mgmt alg");
1464 return IEEE80211_REASON_IE_INVALID;
1465 }
1466 if (w & WPA_ASE_8021X_UNSPEC)
1467 rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC;
1468 else
1469 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK;
1470
1471 if (len > 2) /* optional capabilities */
1472 rsn->rsn_caps = LE_READ_2(frm);
1473
1474 return 0;
1475 }
1476
1477 /*
1478 * Convert an RSN cipher selector OUI to an internal
1479 * cipher algorithm. Where appropriate we also
1480 * record any key length.
1481 */
1482 static int
1483 rsn_cipher(u_int8_t *sel, u_int8_t *keylen)
1484 {
1485 #define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1486 u_int32_t w = LE_READ_4(sel);
1487
1488 switch (w) {
1489 case RSN_SEL(RSN_CSE_NULL):
1490 return IEEE80211_CIPHER_NONE;
1491 case RSN_SEL(RSN_CSE_WEP40):
1492 if (keylen)
1493 *keylen = 40 / NBBY;
1494 return IEEE80211_CIPHER_WEP;
1495 case RSN_SEL(RSN_CSE_WEP104):
1496 if (keylen)
1497 *keylen = 104 / NBBY;
1498 return IEEE80211_CIPHER_WEP;
1499 case RSN_SEL(RSN_CSE_TKIP):
1500 return IEEE80211_CIPHER_TKIP;
1501 case RSN_SEL(RSN_CSE_CCMP):
1502 return IEEE80211_CIPHER_AES_CCM;
1503 case RSN_SEL(RSN_CSE_WRAP):
1504 return IEEE80211_CIPHER_AES_OCB;
1505 }
1506 return 32; /* NB: so 1<< is discarded */
1507 #undef WPA_SEL
1508 }
1509
1510 /*
1511 * Convert an RSN key management/authentication algorithm
1512 * to an internal code.
1513 */
1514 static int
1515 rsn_keymgmt(u_int8_t *sel)
1516 {
1517 #define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1518 u_int32_t w = LE_READ_4(sel);
1519
1520 switch (w) {
1521 case RSN_SEL(RSN_ASE_8021X_UNSPEC):
1522 return RSN_ASE_8021X_UNSPEC;
1523 case RSN_SEL(RSN_ASE_8021X_PSK):
1524 return RSN_ASE_8021X_PSK;
1525 case RSN_SEL(RSN_ASE_NONE):
1526 return RSN_ASE_NONE;
1527 }
1528 return 0; /* NB: so is discarded */
1529 #undef RSN_SEL
1530 }
1531
1532 /*
1533 * Parse a WPA/RSN information element to collect parameters
1534 * and validate the parameters against what has been
1535 * configured for the system.
1536 */
1537 static int
1538 ieee80211_parse_rsn(struct ieee80211com *ic, u_int8_t *frm,
1539 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh)
1540 {
1541 u_int8_t len = frm[1];
1542 u_int32_t w;
1543 int n;
1544
1545 /*
1546 * Check the length once for fixed parts:
1547 * version, mcast cipher, and 2 selector counts.
1548 * Other, variable-length data, must be checked separately.
1549 */
1550 if ((ic->ic_flags & IEEE80211_F_WPA2) == 0) {
1551 IEEE80211_DISCARD_IE(ic,
1552 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1553 wh, "WPA", "not RSN, flags 0x%x", ic->ic_flags);
1554 return IEEE80211_REASON_IE_INVALID;
1555 }
1556 if (len < 10) {
1557 IEEE80211_DISCARD_IE(ic,
1558 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1559 wh, "RSN", "too short, len %u", len);
1560 return IEEE80211_REASON_IE_INVALID;
1561 }
1562 frm += 2;
1563 w = LE_READ_2(frm);
1564 if (w != RSN_VERSION) {
1565 IEEE80211_DISCARD_IE(ic,
1566 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1567 wh, "RSN", "bad version %u", w);
1568 return IEEE80211_REASON_IE_INVALID;
1569 }
1570 frm += 2, len -= 2;
1571
1572 /* multicast/group cipher */
1573 w = rsn_cipher(frm, &rsn->rsn_mcastkeylen);
1574 if (w != rsn->rsn_mcastcipher) {
1575 IEEE80211_DISCARD_IE(ic,
1576 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1577 wh, "RSN", "mcast cipher mismatch; got %u, expected %u",
1578 w, rsn->rsn_mcastcipher);
1579 return IEEE80211_REASON_IE_INVALID;
1580 }
1581 frm += 4, len -= 4;
1582
1583 /* unicast ciphers */
1584 n = LE_READ_2(frm);
1585 frm += 2, len -= 2;
1586 if (len < n*4+2) {
1587 IEEE80211_DISCARD_IE(ic,
1588 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1589 wh, "RSN", "ucast cipher data too short; len %u, n %u",
1590 len, n);
1591 return IEEE80211_REASON_IE_INVALID;
1592 }
1593 w = 0;
1594 for (; n > 0; n--) {
1595 w |= 1<<rsn_cipher(frm, &rsn->rsn_ucastkeylen);
1596 frm += 4, len -= 4;
1597 }
1598 w &= rsn->rsn_ucastcipherset;
1599 if (w == 0) {
1600 IEEE80211_DISCARD_IE(ic,
1601 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1602 wh, "RSN", "%s", "ucast cipher set empty");
1603 return IEEE80211_REASON_IE_INVALID;
1604 }
1605 if (w & (1<<IEEE80211_CIPHER_TKIP))
1606 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
1607 else
1608 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
1609
1610 /* key management algorithms */
1611 n = LE_READ_2(frm);
1612 frm += 2, len -= 2;
1613 if (len < n*4) {
1614 IEEE80211_DISCARD_IE(ic,
1615 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1616 wh, "RSN", "key mgmt alg data too short; len %u, n %u",
1617 len, n);
1618 return IEEE80211_REASON_IE_INVALID;
1619 }
1620 w = 0;
1621 for (; n > 0; n--) {
1622 w |= rsn_keymgmt(frm);
1623 frm += 4, len -= 4;
1624 }
1625 w &= rsn->rsn_keymgmtset;
1626 if (w == 0) {
1627 IEEE80211_DISCARD_IE(ic,
1628 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1629 wh, "RSN", "%s", "no acceptable key mgmt alg");
1630 return IEEE80211_REASON_IE_INVALID;
1631 }
1632 if (w & RSN_ASE_8021X_UNSPEC)
1633 rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC;
1634 else
1635 rsn->rsn_keymgmt = RSN_ASE_8021X_PSK;
1636
1637 /* optional RSN capabilities */
1638 if (len > 2)
1639 rsn->rsn_caps = LE_READ_2(frm);
1640 /* XXXPMKID */
1641
1642 return 0;
1643 }
1644
1645 static int
1646 ieee80211_parse_wmeparams(struct ieee80211com *ic, u_int8_t *frm,
1647 const struct ieee80211_frame *wh)
1648 {
1649 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
1650 struct ieee80211_wme_state *wme = &ic->ic_wme;
1651 u_int len = frm[1], qosinfo;
1652 int i;
1653
1654 if (len < sizeof(struct ieee80211_wme_param)-2) {
1655 IEEE80211_DISCARD_IE(ic,
1656 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME,
1657 wh, "WME", "too short, len %u", len);
1658 return -1;
1659 }
1660 qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)];
1661 qosinfo &= WME_QOSINFO_COUNT;
1662 /* XXX do proper check for wraparound */
1663 if (qosinfo == wme->wme_wmeChanParams.cap_info)
1664 return 0;
1665 frm += __offsetof(struct ieee80211_wme_param, params_acParams);
1666 for (i = 0; i < WME_NUM_AC; i++) {
1667 struct wmeParams *wmep =
1668 &wme->wme_wmeChanParams.cap_wmeParams[i];
1669 /* NB: ACI not used */
1670 wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM);
1671 wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN);
1672 wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN);
1673 wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX);
1674 wmep->wmep_txopLimit = LE_READ_2(frm+2);
1675 frm += 4;
1676 }
1677 wme->wme_wmeChanParams.cap_info = qosinfo;
1678 return 1;
1679 #undef MS
1680 }
1681
1682 void
1683 ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie)
1684 {
1685 u_int ielen = ie[1]+2;
1686 /*
1687 * Record information element for later use.
1688 */
1689 if (*iep == NULL || (*iep)[1] != ie[1]) {
1690 if (*iep != NULL)
1691 FREE(*iep, M_DEVBUF);
1692 MALLOC(*iep, void*, ielen, M_DEVBUF, M_NOWAIT);
1693 }
1694 if (*iep != NULL)
1695 memcpy(*iep, ie, ielen);
1696 /* XXX note failure */
1697 }
1698
1699 /* XXX find a better place for definition */
1700 struct l2_update_frame {
1701 struct ether_header eh;
1702 u_int8_t dsap;
1703 u_int8_t ssap;
1704 u_int8_t control;
1705 u_int8_t xid[3];
1706 } __packed;
1707
1708 /*
1709 * Deliver a TGf L2UF frame on behalf of a station.
1710 * This primes any bridge when the station is roaming
1711 * between ap's on the same wired network.
1712 */
1713 static void
1714 ieee80211_deliver_l2uf(struct ieee80211_node *ni)
1715 {
1716 struct ieee80211com *ic = ni->ni_ic;
1717 struct ifnet *ifp = ic->ic_ifp;
1718 struct mbuf *m;
1719 struct l2_update_frame *l2uf;
1720 struct ether_header *eh;
1721
1722 m = m_gethdr(M_NOWAIT, MT_DATA);
1723 if (m == NULL) {
1724 IEEE80211_NOTE(ic, IEEE80211_MSG_ASSOC, ni,
1725 "%s", "no mbuf for l2uf frame");
1726 ic->ic_stats.is_rx_nobuf++; /* XXX not right */
1727 return;
1728 }
1729 l2uf = mtod(m, struct l2_update_frame *);
1730 eh = &l2uf->eh;
1731 /* dst: Broadcast address */
1732 IEEE80211_ADDR_COPY(eh->ether_dhost, ifp->if_broadcastaddr);
1733 /* src: associated STA */
1734 IEEE80211_ADDR_COPY(eh->ether_shost, ni->ni_macaddr);
1735 eh->ether_type = htons(sizeof(*l2uf) - sizeof(*eh));
1736
1737 l2uf->dsap = 0;
1738 l2uf->ssap = 0;
1739 l2uf->control = 0xf5;
1740 l2uf->xid[0] = 0x81;
1741 l2uf->xid[1] = 0x80;
1742 l2uf->xid[2] = 0x00;
1743
1744 m->m_pkthdr.len = m->m_len = sizeof(*l2uf);
1745 ieee80211_deliver_data(ic, ni, m);
1746 }
1747
1748 static void
1749 ratesetmismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
1750 int reassoc, int resp, const char *tag, int rate)
1751 {
1752 struct ieee80211com *ic = ni->ni_ic;
1753
1754 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1755 "[%s] deny %s request, %srate set mismatch, rate 0x%x\n",
1756 ether_sprintf(wh->i_addr2),
1757 reassoc ? "reassoc" : "assoc", tag, rate);
1758 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_BASIC_RATE);
1759 ieee80211_node_leave(ic, ni);
1760 ic->ic_stats.is_rx_assoc_norate++;
1761 }
1762
1763 static void
1764 capinfomismatch(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
1765 int reassoc, int resp, const char *tag, int capinfo)
1766 {
1767 struct ieee80211com *ic = ni->ni_ic;
1768
1769 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
1770 "[%s] deny %s request, %s mismatch 0x%x\n",
1771 ether_sprintf(wh->i_addr2),
1772 reassoc ? "reassoc" : "assoc", tag, capinfo);
1773 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_CAPINFO);
1774 ieee80211_node_leave(ic, ni);
1775 ic->ic_stats.is_rx_assoc_capmismatch++;
1776 }
1777
1778 void
1779 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
1780 struct ieee80211_node *ni,
1781 int subtype, int rssi, u_int32_t rstamp)
1782 {
1783 #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1784 #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
1785 struct ieee80211_frame *wh;
1786 u_int8_t *frm, *efrm;
1787 u_int8_t *ssid, *rates, *xrates, *wpa, *wme;
1788 int reassoc, resp, allocbs;
1789 u_int8_t rate;
1790
1791 wh = mtod(m0, struct ieee80211_frame *);
1792 frm = (u_int8_t *)&wh[1];
1793 efrm = mtod(m0, u_int8_t *) + m0->m_len;
1794 switch (subtype) {
1795 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1796 case IEEE80211_FC0_SUBTYPE_BEACON: {
1797 struct ieee80211_scanparams scan;
1798
1799 /*
1800 * We process beacon/probe response frames:
1801 * o when scanning, or
1802 * o station mode when associated (to collect state
1803 * updates such as 802.11g slot time), or
1804 * o adhoc mode (to discover neighbors)
1805 * Frames otherwise received are discarded.
1806 */
1807 if (!((ic->ic_flags & IEEE80211_F_SCAN) ||
1808 (ic->ic_opmode == IEEE80211_M_STA && ni->ni_associd) ||
1809 ic->ic_opmode == IEEE80211_M_IBSS)) {
1810 ic->ic_stats.is_rx_mgtdiscard++;
1811 return;
1812 }
1813 /*
1814 * beacon/probe response frame format
1815 * [8] time stamp
1816 * [2] beacon interval
1817 * [2] capability information
1818 * [tlv] ssid
1819 * [tlv] supported rates
1820 * [tlv] country information
1821 * [tlv] parameter set (FH/DS)
1822 * [tlv] erp information
1823 * [tlv] extended supported rates
1824 * [tlv] WME
1825 * [tlv] WPA or RSN
1826 */
1827 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
1828 memset(&scan, 0, sizeof(scan));
1829 scan.tstamp = frm; frm += 8;
1830 scan.bintval = le16toh(*(u_int16_t *)frm); frm += 2;
1831 scan.capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
1832 scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
1833 scan.chan = scan.bchan;
1834
1835 while (efrm - frm > 1) {
1836 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2);
1837 switch (*frm) {
1838 case IEEE80211_ELEMID_SSID:
1839 scan.ssid = frm;
1840 break;
1841 case IEEE80211_ELEMID_RATES:
1842 scan.rates = frm;
1843 break;
1844 case IEEE80211_ELEMID_COUNTRY:
1845 scan.country = frm;
1846 break;
1847 case IEEE80211_ELEMID_FHPARMS:
1848 if (ic->ic_phytype == IEEE80211_T_FH) {
1849 scan.fhdwell = LE_READ_2(&frm[2]);
1850 scan.chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
1851 scan.fhindex = frm[6];
1852 }
1853 break;
1854 case IEEE80211_ELEMID_DSPARMS:
1855 /*
1856 * XXX hack this since depending on phytype
1857 * is problematic for multi-mode devices.
1858 */
1859 if (ic->ic_phytype != IEEE80211_T_FH)
1860 scan.chan = frm[2];
1861 break;
1862 case IEEE80211_ELEMID_TIM:
1863 /* XXX ATIM? */
1864 scan.tim = frm;
1865 scan.timoff = frm - mtod(m0, u_int8_t *);
1866 break;
1867 case IEEE80211_ELEMID_IBSSPARMS:
1868 break;
1869 case IEEE80211_ELEMID_XRATES:
1870 scan.xrates = frm;
1871 break;
1872 case IEEE80211_ELEMID_ERP:
1873 if (frm[1] != 1) {
1874 IEEE80211_DISCARD_IE(ic,
1875 IEEE80211_MSG_ELEMID, wh, "ERP",
1876 "bad len %u", frm[1]);
1877 ic->ic_stats.is_rx_elem_toobig++;
1878 break;
1879 }
1880 scan.erp = frm[2];
1881 break;
1882 case IEEE80211_ELEMID_RSN:
1883 scan.wpa = frm;
1884 break;
1885 case IEEE80211_ELEMID_VENDOR:
1886 if (iswpaoui(frm))
1887 scan.wpa = frm;
1888 else if (iswmeparam(frm) || iswmeinfo(frm))
1889 scan.wme = frm;
1890 /* XXX Atheros OUI support */
1891 break;
1892 default:
1893 IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID,
1894 wh, "unhandled",
1895 "id %u, len %u", *frm, frm[1]);
1896 ic->ic_stats.is_rx_elem_unknown++;
1897 break;
1898 }
1899 frm += frm[1] + 2;
1900 }
1901 IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE);
1902 IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN);
1903 if (
1904 #if IEEE80211_CHAN_MAX < 255
1905 scan.chan > IEEE80211_CHAN_MAX ||
1906 #endif
1907 isclr(ic->ic_chan_active, scan.chan)) {
1908 IEEE80211_DISCARD(ic,
1909 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
1910 wh, ieee80211_mgt_subtype_name[subtype >>
1911 IEEE80211_FC0_SUBTYPE_SHIFT],
1912 "invalid channel %u", scan.chan);
1913 ic->ic_stats.is_rx_badchan++;
1914 return;
1915 }
1916 if (scan.chan != scan.bchan &&
1917 ic->ic_phytype != IEEE80211_T_FH) {
1918 /*
1919 * Frame was received on a channel different from the
1920 * one indicated in the DS params element id;
1921 * silently discard it.
1922 *
1923 * NB: this can happen due to signal leakage.
1924 * But we should take it for FH phy because
1925 * the rssi value should be correct even for
1926 * different hop pattern in FH.
1927 */
1928 IEEE80211_DISCARD(ic,
1929 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
1930 wh, ieee80211_mgt_subtype_name[subtype >>
1931 IEEE80211_FC0_SUBTYPE_SHIFT],
1932 "for off-channel %u", scan.chan);
1933 ic->ic_stats.is_rx_chanmismatch++;
1934 return;
1935 }
1936 if (!(IEEE80211_BINTVAL_MIN <= scan.bintval &&
1937 scan.bintval <= IEEE80211_BINTVAL_MAX)) {
1938 IEEE80211_DISCARD(ic,
1939 IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
1940 wh, ieee80211_mgt_subtype_name[subtype >>
1941 IEEE80211_FC0_SUBTYPE_SHIFT],
1942 "bogus beacon interval", scan.bintval);
1943 ic->ic_stats.is_rx_badbintval++;
1944 return;
1945 }
1946
1947 /*
1948 * Count frame now that we know it's to be processed.
1949 */
1950 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
1951 ic->ic_stats.is_rx_beacon++; /* XXX remove */
1952 IEEE80211_NODE_STAT(ni, rx_beacons);
1953 } else
1954 IEEE80211_NODE_STAT(ni, rx_proberesp);
1955
1956 /*
1957 * When operating in station mode, check for state updates.
1958 * Be careful to ignore beacons received while doing a
1959 * background scan. We consider only 11g/WMM stuff right now.
1960 */
1961 if (ic->ic_opmode == IEEE80211_M_STA &&
1962 ni->ni_associd != 0 &&
1963 ((ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
1964 IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) {
1965 /* record tsf of last beacon */
1966 memcpy(ni->ni_tstamp.data, scan.tstamp,
1967 sizeof(ni->ni_tstamp));
1968 /* count beacon frame for s/w bmiss handling */
1969 ic->ic_swbmiss_count++;
1970 ic->ic_bmiss_count = 0;
1971 if (ni->ni_erp != scan.erp) {
1972 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1973 "[%s] erp change: was 0x%x, now 0x%x\n",
1974 ether_sprintf(wh->i_addr2),
1975 ni->ni_erp, scan.erp);
1976 if (ic->ic_curmode == IEEE80211_MODE_11G &&
1977 (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
1978 ic->ic_flags |= IEEE80211_F_USEPROT;
1979 else
1980 ic->ic_flags &= ~IEEE80211_F_USEPROT;
1981 ni->ni_erp = scan.erp;
1982 /* XXX statistic */
1983 }
1984 if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
1985 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1986 "[%s] capabilities change: before 0x%x,"
1987 " now 0x%x\n",
1988 ether_sprintf(wh->i_addr2),
1989 ni->ni_capinfo, scan.capinfo);
1990 /*
1991 * NB: we assume short preamble doesn't
1992 * change dynamically
1993 */
1994 ieee80211_set_shortslottime(ic,
1995 ic->ic_curmode == IEEE80211_MODE_11A ||
1996 (scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1997 ni->ni_capinfo = scan.capinfo;
1998 /* XXX statistic */
1999 }
2000 if (scan.wme != NULL &&
2001 (ni->ni_flags & IEEE80211_NODE_QOS) &&
2002 ieee80211_parse_wmeparams(ic, scan.wme, wh) > 0)
2003 ieee80211_wme_updateparams(ic);
2004 if (scan.tim != NULL) {
2005 struct ieee80211_tim_ie *ie =
2006 (struct ieee80211_tim_ie *) scan.tim;
2007
2008 ni->ni_dtim_count = ie->tim_count;
2009 ni->ni_dtim_period = ie->tim_period;
2010 }
2011 if (ic->ic_flags & IEEE80211_F_SCAN)
2012 ieee80211_add_scan(ic, &scan, wh,
2013 subtype, rssi, rstamp);
2014 return;
2015 }
2016 /*
2017 * If scanning, just pass information to the scan module.
2018 */
2019 if (ic->ic_flags & IEEE80211_F_SCAN) {
2020 if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) {
2021 /*
2022 * Actively scanning a channel marked passive;
2023 * send a probe request now that we know there
2024 * is 802.11 traffic present.
2025 *
2026 * XXX check if the beacon we recv'd gives
2027 * us what we need and suppress the probe req
2028 */
2029 ieee80211_probe_curchan(ic, 1);
2030 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
2031 }
2032 ieee80211_add_scan(ic, &scan, wh,
2033 subtype, rssi, rstamp);
2034 return;
2035 }
2036 if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
2037 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
2038 /*
2039 * Create a new entry in the neighbor table.
2040 */
2041 ni = ieee80211_add_neighbor(ic, wh, &scan);
2042 } else if (ni->ni_capinfo == 0) {
2043 /*
2044 * Update faked node created on transmit.
2045 * Note this also updates the tsf.
2046 */
2047 ieee80211_init_neighbor(ni, wh, &scan);
2048 } else {
2049 /*
2050 * Record tsf for potential resync.
2051 */
2052 memcpy(ni->ni_tstamp.data, scan.tstamp,
2053 sizeof(ni->ni_tstamp));
2054 }
2055 if (ni != NULL) {
2056 ni->ni_rssi = rssi;
2057 ni->ni_rstamp = rstamp;
2058 }
2059 }
2060 break;
2061 }
2062
2063 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
2064 if (ic->ic_opmode == IEEE80211_M_STA ||
2065 ic->ic_state != IEEE80211_S_RUN) {
2066 ic->ic_stats.is_rx_mgtdiscard++;
2067 return;
2068 }
2069 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
2070 /* frame must be directed */
2071 ic->ic_stats.is_rx_mgtdiscard++; /* XXX stat */
2072 return;
2073 }
2074
2075 /*
2076 * prreq frame format
2077 * [tlv] ssid
2078 * [tlv] supported rates
2079 * [tlv] extended supported rates
2080 */
2081 ssid = rates = xrates = NULL;
2082 while (efrm - frm > 1) {
2083 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2);
2084 switch (*frm) {
2085 case IEEE80211_ELEMID_SSID:
2086 ssid = frm;
2087 break;
2088 case IEEE80211_ELEMID_RATES:
2089 rates = frm;
2090 break;
2091 case IEEE80211_ELEMID_XRATES:
2092 xrates = frm;
2093 break;
2094 }
2095 frm += frm[1] + 2;
2096 }
2097 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2098 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
2099 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid);
2100 if ((ic->ic_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) {
2101 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
2102 wh, ieee80211_mgt_subtype_name[subtype >>
2103 IEEE80211_FC0_SUBTYPE_SHIFT],
2104 "%s", "no ssid with ssid suppression enabled");
2105 ic->ic_stats.is_rx_ssidmismatch++; /*XXX*/
2106 return;
2107 }
2108
2109 allocbs = 0;
2110 if (ni == ic->ic_bss) {
2111 if (ic->ic_opmode != IEEE80211_M_IBSS) {
2112 ni = ieee80211_tmp_node(ic, wh->i_addr2);
2113 allocbs = 1;
2114 } else if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
2115 /*
2116 * XXX Cannot tell if the sender is operating
2117 * in ibss mode. But we need a new node to
2118 * send the response so blindly add them to the
2119 * neighbor table.
2120 */
2121 ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
2122 wh->i_addr2);
2123 }
2124 if (ni == NULL)
2125 return;
2126 }
2127 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2128 "[%s] recv probe req\n", ether_sprintf(wh->i_addr2));
2129 ni->ni_rssi = rssi;
2130 ni->ni_rstamp = rstamp;
2131 rate = ieee80211_setup_rates(ni, rates, xrates,
2132 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
2133 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2134 if (rate & IEEE80211_RATE_BASIC) {
2135 IEEE80211_DISCARD(ic, IEEE80211_MSG_XRATE,
2136 wh, ieee80211_mgt_subtype_name[subtype >>
2137 IEEE80211_FC0_SUBTYPE_SHIFT],
2138 "%s", "recv'd rate set invalid");
2139 } else {
2140 IEEE80211_SEND_MGMT(ic, ni,
2141 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
2142 }
2143 if (allocbs) {
2144 /*
2145 * Temporary node created just to send a
2146 * response, reclaim immediately.
2147 */
2148 ieee80211_free_node(ni);
2149 }
2150 break;
2151
2152 case IEEE80211_FC0_SUBTYPE_AUTH: {
2153 u_int16_t algo, seq, status;
2154 /*
2155 * auth frame format
2156 * [2] algorithm
2157 * [2] sequence
2158 * [2] status
2159 * [tlv*] challenge
2160 */
2161 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
2162 algo = le16toh(*(u_int16_t *)frm);
2163 seq = le16toh(*(u_int16_t *)(frm + 2));
2164 status = le16toh(*(u_int16_t *)(frm + 4));
2165 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
2166 "[%s] recv auth frame with algorithm %d seq %d\n",
2167 ether_sprintf(wh->i_addr2), algo, seq);
2168 /*
2169 * Consult the ACL policy module if setup.
2170 */
2171 if (ic->ic_acl != NULL &&
2172 !ic->ic_acl->iac_check(ic, wh->i_addr2)) {
2173 IEEE80211_DISCARD(ic, IEEE80211_MSG_ACL,
2174 wh, "auth", "%s", "disallowed by ACL");
2175 ic->ic_stats.is_rx_acl++;
2176 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2177 IEEE80211_SEND_MGMT(ic, ni,
2178 IEEE80211_FC0_SUBTYPE_AUTH,
2179 (seq+1) | (IEEE80211_STATUS_UNSPECIFIED<<16));
2180 }
2181 return;
2182 }
2183 if (ic->ic_flags & IEEE80211_F_COUNTERM) {
2184 IEEE80211_DISCARD(ic,
2185 IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO,
2186 wh, "auth", "%s", "TKIP countermeasures enabled");
2187 ic->ic_stats.is_rx_auth_countermeasures++;
2188 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2189 IEEE80211_SEND_MGMT(ic, ni,
2190 IEEE80211_FC0_SUBTYPE_AUTH,
2191 IEEE80211_REASON_MIC_FAILURE);
2192 }
2193 return;
2194 }
2195 if (algo == IEEE80211_AUTH_ALG_SHARED)
2196 ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi,
2197 rstamp, seq, status);
2198 else if (algo == IEEE80211_AUTH_ALG_OPEN)
2199 ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq,
2200 status);
2201 else {
2202 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2203 wh, "auth", "unsupported alg %d", algo);
2204 ic->ic_stats.is_rx_auth_unsupported++;
2205 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2206 /* XXX not right */
2207 IEEE80211_SEND_MGMT(ic, ni,
2208 IEEE80211_FC0_SUBTYPE_AUTH,
2209 (seq+1) | (IEEE80211_STATUS_ALG<<16));
2210 }
2211 return;
2212 }
2213 break;
2214 }
2215
2216 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
2217 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
2218 u_int16_t capinfo, lintval;
2219 struct ieee80211_rsnparms rsn;
2220 u_int8_t reason;
2221
2222 if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
2223 ic->ic_state != IEEE80211_S_RUN) {
2224 ic->ic_stats.is_rx_mgtdiscard++;
2225 return;
2226 }
2227
2228 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
2229 reassoc = 1;
2230 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
2231 } else {
2232 reassoc = 0;
2233 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
2234 }
2235 /*
2236 * asreq frame format
2237 * [2] capability information
2238 * [2] listen interval
2239 * [6*] current AP address (reassoc only)
2240 * [tlv] ssid
2241 * [tlv] supported rates
2242 * [tlv] extended supported rates
2243 * [tlv] WPA or RSN
2244 */
2245 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4));
2246 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
2247 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2248 wh, ieee80211_mgt_subtype_name[subtype >>
2249 IEEE80211_FC0_SUBTYPE_SHIFT],
2250 "%s", "wrong bssid");
2251 ic->ic_stats.is_rx_assoc_bss++;
2252 return;
2253 }
2254 capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
2255 lintval = le16toh(*(u_int16_t *)frm); frm += 2;
2256 if (reassoc)
2257 frm += 6; /* ignore current AP info */
2258 ssid = rates = xrates = wpa = wme = NULL;
2259 while (efrm - frm > 1) {
2260 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2);
2261 switch (*frm) {
2262 case IEEE80211_ELEMID_SSID:
2263 ssid = frm;
2264 break;
2265 case IEEE80211_ELEMID_RATES:
2266 rates = frm;
2267 break;
2268 case IEEE80211_ELEMID_XRATES:
2269 xrates = frm;
2270 break;
2271 /* XXX verify only one of RSN and WPA ie's? */
2272 case IEEE80211_ELEMID_RSN:
2273 wpa = frm;
2274 break;
2275 case IEEE80211_ELEMID_VENDOR:
2276 if (iswpaoui(frm))
2277 wpa = frm;
2278 else if (iswmeinfo(frm))
2279 wme = frm;
2280 /* XXX Atheros OUI support */
2281 break;
2282 }
2283 frm += frm[1] + 2;
2284 }
2285 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2286 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
2287 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid);
2288
2289 if (ni == ic->ic_bss) {
2290 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
2291 "[%s] deny %s request, sta not authenticated\n",
2292 ether_sprintf(wh->i_addr2),
2293 reassoc ? "reassoc" : "assoc");
2294 ieee80211_send_error(ic, ni, wh->i_addr2,
2295 IEEE80211_FC0_SUBTYPE_DEAUTH,
2296 IEEE80211_REASON_ASSOC_NOT_AUTHED);
2297 ic->ic_stats.is_rx_assoc_notauth++;
2298 return;
2299 }
2300 /* assert right associstion security credentials */
2301 if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) {
2302 IEEE80211_DPRINTF(ic,
2303 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
2304 "[%s] no WPA/RSN IE in association request\n",
2305 ether_sprintf(wh->i_addr2));
2306 IEEE80211_SEND_MGMT(ic, ni,
2307 IEEE80211_FC0_SUBTYPE_DEAUTH,
2308 IEEE80211_REASON_IE_INVALID);
2309 ieee80211_node_leave(ic, ni);
2310 /* XXX distinguish WPA/RSN? */
2311 ic->ic_stats.is_rx_assoc_badwpaie++;
2312 return;
2313 }
2314 if (wpa != NULL) {
2315 /*
2316 * Parse WPA information element. Note that
2317 * we initialize the param block from the node
2318 * state so that information in the IE overrides
2319 * our defaults. The resulting parameters are
2320 * installed below after the association is assured.
2321 */
2322 rsn = ni->ni_rsn;
2323 if (wpa[0] != IEEE80211_ELEMID_RSN)
2324 reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh);
2325 else
2326 reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh);
2327 if (reason != 0) {
2328 IEEE80211_SEND_MGMT(ic, ni,
2329 IEEE80211_FC0_SUBTYPE_DEAUTH, reason);
2330 ieee80211_node_leave(ic, ni);
2331 /* XXX distinguish WPA/RSN? */
2332 ic->ic_stats.is_rx_assoc_badwpaie++;
2333 return;
2334 }
2335 IEEE80211_DPRINTF(ic,
2336 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
2337 "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n",
2338 ether_sprintf(wh->i_addr2),
2339 wpa[0] != IEEE80211_ELEMID_RSN ? "WPA" : "RSN",
2340 rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen,
2341 rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen,
2342 rsn.rsn_keymgmt, rsn.rsn_caps);
2343 }
2344 /* discard challenge after association */
2345 if (ni->ni_challenge != NULL) {
2346 FREE(ni->ni_challenge, M_DEVBUF);
2347 ni->ni_challenge = NULL;
2348 }
2349 /* NB: 802.11 spec says to ignore station's privacy bit */
2350 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0) {
2351 capinfomismatch(ni, wh, reassoc, resp,
2352 "capability", capinfo);
2353 return;
2354 }
2355 /*
2356 * Disallow re-associate w/ invalid slot time setting.
2357 */
2358 if (ni->ni_associd != 0 &&
2359 ic->ic_curmode == IEEE80211_MODE_11G &&
2360 ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME)) {
2361 capinfomismatch(ni, wh, reassoc, resp,
2362 "slot time", capinfo);
2363 return;
2364 }
2365 rate = ieee80211_setup_rates(ni, rates, xrates,
2366 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
2367 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2368 if (rate & IEEE80211_RATE_BASIC) {
2369 ratesetmismatch(ni, wh, reassoc, resp, "basic", rate);
2370 return;
2371 }
2372 /*
2373 * If constrained to 11g-only stations reject an
2374 * 11b-only station. We cheat a bit here by looking
2375 * at the max negotiated xmit rate and assuming anyone
2376 * with a best rate <24Mb/s is an 11b station.
2377 */
2378 if ((ic->ic_flags & IEEE80211_F_PUREG) && rate < 48) {
2379 ratesetmismatch(ni, wh, reassoc, resp, "11g", rate);
2380 return;
2381 }
2382 ni->ni_rssi = rssi;
2383 ni->ni_rstamp = rstamp;
2384 ni->ni_intval = lintval;
2385 ni->ni_capinfo = capinfo;
2386 ni->ni_chan = ic->ic_bss->ni_chan;
2387 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
2388 ni->ni_fhindex = ic->ic_bss->ni_fhindex;
2389 if (wpa != NULL) {
2390 /*
2391 * Record WPA/RSN parameters for station, mark
2392 * node as using WPA and record information element
2393 * for applications that require it.
2394 */
2395 ni->ni_rsn = rsn;
2396 ieee80211_saveie(&ni->ni_wpa_ie, wpa);
2397 } else if (ni->ni_wpa_ie != NULL) {
2398 /*
2399 * Flush any state from a previous association.
2400 */
2401 FREE(ni->ni_wpa_ie, M_DEVBUF);
2402 ni->ni_wpa_ie = NULL;
2403 }
2404 if (wme != NULL) {
2405 /*
2406 * Record WME parameters for station, mark node
2407 * as capable of QoS and record information
2408 * element for applications that require it.
2409 */
2410 ieee80211_saveie(&ni->ni_wme_ie, wme);
2411 ni->ni_flags |= IEEE80211_NODE_QOS;
2412 } else if (ni->ni_wme_ie != NULL) {
2413 /*
2414 * Flush any state from a previous association.
2415 */
2416 FREE(ni->ni_wme_ie, M_DEVBUF);
2417 ni->ni_wme_ie = NULL;
2418 ni->ni_flags &= ~IEEE80211_NODE_QOS;
2419 }
2420 ieee80211_deliver_l2uf(ni);
2421 ieee80211_node_join(ic, ni, resp);
2422 break;
2423 }
2424
2425 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
2426 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
2427 u_int16_t capinfo, associd;
2428 u_int16_t status;
2429
2430 if (ic->ic_opmode != IEEE80211_M_STA ||
2431 ic->ic_state != IEEE80211_S_ASSOC) {
2432 ic->ic_stats.is_rx_mgtdiscard++;
2433 return;
2434 }
2435
2436 /*
2437 * asresp frame format
2438 * [2] capability information
2439 * [2] status
2440 * [2] association ID
2441 * [tlv] supported rates
2442 * [tlv] extended supported rates
2443 * [tlv] WME
2444 */
2445 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
2446 ni = ic->ic_bss;
2447 capinfo = le16toh(*(u_int16_t *)frm);
2448 frm += 2;
2449 status = le16toh(*(u_int16_t *)frm);
2450 frm += 2;
2451 if (status != 0) {
2452 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2453 "[%s] %sassoc failed (reason %d)\n",
2454 ether_sprintf(wh->i_addr2),
2455 ISREASSOC(subtype) ? "re" : "", status);
2456 if (ni != ic->ic_bss) /* XXX never true? */
2457 ni->ni_fails++;
2458 ic->ic_stats.is_rx_auth_fail++; /* XXX */
2459 return;
2460 }
2461 associd = le16toh(*(u_int16_t *)frm);
2462 frm += 2;
2463
2464 rates = xrates = wpa = wme = NULL;
2465 while (efrm - frm > 1) {
2466 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2);
2467 switch (*frm) {
2468 case IEEE80211_ELEMID_RATES:
2469 rates = frm;
2470 break;
2471 case IEEE80211_ELEMID_XRATES:
2472 xrates = frm;
2473 break;
2474 case IEEE80211_ELEMID_VENDOR:
2475 if (iswmeoui(frm))
2476 wme = frm;
2477 /* XXX Atheros OUI support */
2478 break;
2479 }
2480 frm += frm[1] + 2;
2481 }
2482
2483 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2484 if (xrates != NULL)
2485 IEEE80211_VERIFY_ELEMENT(xrates,
2486 IEEE80211_RATE_MAXSIZE - rates[1]);
2487 rate = ieee80211_setup_rates(ni, rates, xrates,
2488 IEEE80211_F_JOIN |
2489 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
2490 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2491 if (rate & IEEE80211_RATE_BASIC) {
2492 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2493 "[%s] %sassoc failed (rate set mismatch)\n",
2494 ether_sprintf(wh->i_addr2),
2495 ISREASSOC(subtype) ? "re" : "");
2496 if (ni != ic->ic_bss) /* XXX never true? */
2497 ni->ni_fails++;
2498 ic->ic_stats.is_rx_assoc_norate++;
2499 ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
2500 return;
2501 }
2502
2503 ni->ni_capinfo = capinfo;
2504 ni->ni_associd = associd;
2505 if (wme != NULL &&
2506 ieee80211_parse_wmeparams(ic, wme, wh) >= 0) {
2507 ni->ni_flags |= IEEE80211_NODE_QOS;
2508 ieee80211_wme_updateparams(ic);
2509 } else
2510 ni->ni_flags &= ~IEEE80211_NODE_QOS;
2511 /*
2512 * Configure state now that we are associated.
2513 *
2514 * XXX may need different/additional driver callbacks?
2515 */
2516 if (ic->ic_curmode == IEEE80211_MODE_11A ||
2517 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
2518 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
2519 ic->ic_flags &= ~IEEE80211_F_USEBARKER;
2520 } else {
2521 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
2522 ic->ic_flags |= IEEE80211_F_USEBARKER;
2523 }
2524 ieee80211_set_shortslottime(ic,
2525 ic->ic_curmode == IEEE80211_MODE_11A ||
2526 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
2527 /*
2528 * Honor ERP protection.
2529 *
2530 * NB: ni_erp should zero for non-11g operation.
2531 * XXX check ic_curmode anyway?
2532 */
2533 if (ic->ic_curmode == IEEE80211_MODE_11G &&
2534 (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
2535 ic->ic_flags |= IEEE80211_F_USEPROT;
2536 else
2537 ic->ic_flags &= ~IEEE80211_F_USEPROT;
2538 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2539 "[%s] %sassoc success: %s preamble, %s slot time%s%s\n",
2540 ether_sprintf(wh->i_addr2),
2541 ISREASSOC(subtype) ? "re" : "",
2542 ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
2543 ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
2544 ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
2545 ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : ""
2546 );
2547 ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
2548 break;
2549 }
2550
2551 case IEEE80211_FC0_SUBTYPE_DEAUTH: {
2552 u_int16_t reason;
2553
2554 if (ic->ic_state == IEEE80211_S_SCAN) {
2555 ic->ic_stats.is_rx_mgtdiscard++;
2556 return;
2557 }
2558 /*
2559 * deauth frame format
2560 * [2] reason
2561 */
2562 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
2563 reason = le16toh(*(u_int16_t *)frm);
2564 ic->ic_stats.is_rx_deauth++;
2565 IEEE80211_NODE_STAT(ni, rx_deauth);
2566
2567 if (!IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_myaddr)) {
2568 /* NB: can happen when in promiscuous mode */
2569 ic->ic_stats.is_rx_mgtdiscard++;
2570 break;
2571 }
2572 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
2573 "[%s] recv deauthenticate (reason %d)\n",
2574 ether_sprintf(ni->ni_macaddr), reason);
2575 switch (ic->ic_opmode) {
2576 case IEEE80211_M_STA:
2577 ieee80211_new_state(ic, IEEE80211_S_AUTH,
2578 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
2579 break;
2580 case IEEE80211_M_HOSTAP:
2581 if (ni != ic->ic_bss)
2582 ieee80211_node_leave(ic, ni);
2583 break;
2584 default:
2585 ic->ic_stats.is_rx_mgtdiscard++;
2586 break;
2587 }
2588 break;
2589 }
2590
2591 case IEEE80211_FC0_SUBTYPE_DISASSOC: {
2592 u_int16_t reason;
2593
2594 if (ic->ic_state != IEEE80211_S_RUN &&
2595 ic->ic_state != IEEE80211_S_ASSOC &&
2596 ic->ic_state != IEEE80211_S_AUTH) {
2597 ic->ic_stats.is_rx_mgtdiscard++;
2598 return;
2599 }
2600 /*
2601 * disassoc frame format
2602 * [2] reason
2603 */
2604 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
2605 reason = le16toh(*(u_int16_t *)frm);
2606 ic->ic_stats.is_rx_disassoc++;
2607 IEEE80211_NODE_STAT(ni, rx_disassoc);
2608
2609 if (!IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_myaddr)) {
2610 /* NB: can happen when in promiscuous mode */
2611 ic->ic_stats.is_rx_mgtdiscard++;
2612 break;
2613 }
2614 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2615 "[%s] recv disassociate (reason %d)\n",
2616 ether_sprintf(ni->ni_macaddr), reason);
2617 switch (ic->ic_opmode) {
2618 case IEEE80211_M_STA:
2619 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
2620 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
2621 break;
2622 case IEEE80211_M_HOSTAP:
2623 if (ni != ic->ic_bss)
2624 ieee80211_node_leave(ic, ni);
2625 break;
2626 default:
2627 ic->ic_stats.is_rx_mgtdiscard++;
2628 break;
2629 }
2630 break;
2631 }
2632 default:
2633 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2634 wh, "mgt", "subtype 0x%x not handled", subtype);
2635 ic->ic_stats.is_rx_badsubtype++;
2636 break;
2637 }
2638 #undef ISREASSOC
2639 #undef ISPROBE
2640 }
2641 #undef IEEE80211_VERIFY_LENGTH
2642 #undef IEEE80211_VERIFY_ELEMENT
2643
2644 /*
2645 * Handle station power-save state change.
2646 */
2647 static void
2648 ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable)
2649 {
2650 struct ieee80211com *ic = ni->ni_ic;
2651 struct mbuf *m, *mhead, *mtail;
2652 int mcount;
2653
2654 if (enable) {
2655 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0)
2656 ic->ic_ps_sta++;
2657 ni->ni_flags |= IEEE80211_NODE_PWR_MGT;
2658 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2659 "[%s] power save mode on, %u sta's in ps mode\n",
2660 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta);
2661 return;
2662 }
2663
2664 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT)
2665 ic->ic_ps_sta--;
2666 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
2667 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2668 "[%s] power save mode off, %u sta's in ps mode\n",
2669 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta);
2670 /* XXX if no stations in ps mode, flush mc frames */
2671
2672 /*
2673 * Flush queued unicast frames.
2674 */
2675 if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) {
2676 if (ic->ic_set_tim != NULL)
2677 ic->ic_set_tim(ni, 0); /* just in case */
2678 return;
2679 }
2680 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2681 "[%s] flush ps queue, %u packets queued\n",
2682 ether_sprintf(ni->ni_macaddr), IEEE80211_NODE_SAVEQ_QLEN(ni));
2683 /*
2684 * Unload the frames from the ps q but don't send them
2685 * to the driver yet. We do this in two stages to minimize
2686 * locking but also because there's no easy way to preserve
2687 * ordering given the existing ifnet access mechanisms.
2688 * XXX could be optimized
2689 */
2690 IEEE80211_NODE_SAVEQ_LOCK(ni);
2691 mcount = IEEE80211_NODE_SAVEQ_QLEN(ni);
2692 mhead = mtail = NULL;
2693 for (;;) {
2694 _IEEE80211_NODE_SAVEQ_DEQUEUE_HEAD(ni, m);
2695 if (m == NULL)
2696 break;
2697 if (mhead == NULL) {
2698 mhead = m;
2699 m->m_nextpkt = NULL;
2700 } else
2701 mtail->m_nextpkt = m;
2702 mtail = m;
2703 }
2704 IEEE80211_NODE_SAVEQ_UNLOCK(ni);
2705 if (mhead != NULL) {
2706 /* XXX need different driver interface */
2707 /* XXX bypasses q max */
2708 IF_PREPEND_LIST(&ic->ic_ifp->if_snd, mhead, mtail, mcount);
2709 }
2710 if (ic->ic_set_tim != NULL)
2711 ic->ic_set_tim(ni, 0);
2712 }
2713
2714 /*
2715 * Process a received ps-poll frame.
2716 */
2717 static void
2718 ieee80211_recv_pspoll(struct ieee80211com *ic,
2719 struct ieee80211_node *ni, struct mbuf *m0)
2720 {
2721 struct ieee80211_frame_min *wh;
2722 struct mbuf *m;
2723 u_int16_t aid;
2724 int qlen;
2725
2726 wh = mtod(m0, struct ieee80211_frame_min *);
2727 if (ni->ni_associd == 0) {
2728 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG,
2729 (struct ieee80211_frame *) wh, "ps-poll",
2730 "%s", "unassociated station");
2731 ic->ic_stats.is_ps_unassoc++;
2732 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
2733 IEEE80211_REASON_NOT_ASSOCED);
2734 return;
2735 }
2736
2737 aid = le16toh(*(u_int16_t *)wh->i_dur);
2738 if (aid != ni->ni_associd) {
2739 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG,
2740 (struct ieee80211_frame *) wh, "ps-poll",
2741 "aid mismatch: sta aid 0x%x poll aid 0x%x",
2742 ni->ni_associd, aid);
2743 ic->ic_stats.is_ps_badaid++;
2744 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
2745 IEEE80211_REASON_NOT_ASSOCED);
2746 return;
2747 }
2748
2749 /* Okay, take the first queued packet and put it out... */
2750 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen);
2751 if (m == NULL) {
2752 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2753 "[%s] recv ps-poll, but queue empty\n",
2754 ether_sprintf(wh->i_addr2));
2755 ieee80211_send_nulldata(ieee80211_ref_node(ni));
2756 ic->ic_stats.is_ps_qempty++; /* XXX node stat */
2757 if (ic->ic_set_tim != NULL)
2758 ic->ic_set_tim(ni, 0); /* just in case */
2759 return;
2760 }
2761 /*
2762 * If there are more packets, set the more packets bit
2763 * in the packet dispatched to the station; otherwise
2764 * turn off the TIM bit.
2765 */
2766 if (qlen != 0) {
2767 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2768 "[%s] recv ps-poll, send packet, %u still queued\n",
2769 ether_sprintf(ni->ni_macaddr), qlen);
2770 m->m_flags |= M_MORE_DATA;
2771 } else {
2772 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2773 "[%s] recv ps-poll, send packet, queue empty\n",
2774 ether_sprintf(ni->ni_macaddr));
2775 if (ic->ic_set_tim != NULL)
2776 ic->ic_set_tim(ni, 0);
2777 }
2778 m->m_flags |= M_PWR_SAV; /* bypass PS handling */
2779 IF_ENQUEUE(&ic->ic_ifp->if_snd, m);
2780 }
2781
2782 #ifdef IEEE80211_DEBUG
2783 /*
2784 * Debugging support.
2785 */
2786
2787 /*
2788 * Return the bssid of a frame.
2789 */
2790 static const u_int8_t *
2791 ieee80211_getbssid(struct ieee80211com *ic, const struct ieee80211_frame *wh)
2792 {
2793 if (ic->ic_opmode == IEEE80211_M_STA)
2794 return wh->i_addr2;
2795 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS)
2796 return wh->i_addr1;
2797 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
2798 return wh->i_addr1;
2799 return wh->i_addr3;
2800 }
2801
2802 void
2803 ieee80211_note(struct ieee80211com *ic, const char *fmt, ...)
2804 {
2805 char buf[128]; /* XXX */
2806 va_list ap;
2807
2808 va_start(ap, fmt);
2809 vsnprintf(buf, sizeof(buf), fmt, ap);
2810 va_end(ap);
2811
2812 if_printf(ic->ic_ifp, "%s", buf); /* NB: no \n */
2813 }
2814
2815 void
2816 ieee80211_note_frame(struct ieee80211com *ic,
2817 const struct ieee80211_frame *wh,
2818 const char *fmt, ...)
2819 {
2820 char buf[128]; /* XXX */
2821 va_list ap;
2822
2823 va_start(ap, fmt);
2824 vsnprintf(buf, sizeof(buf), fmt, ap);
2825 va_end(ap);
2826 if_printf(ic->ic_ifp, "[%s] %s\n",
2827 ether_sprintf(ieee80211_getbssid(ic, wh)), buf);
2828 }
2829
2830 void
2831 ieee80211_note_mac(struct ieee80211com *ic,
2832 const u_int8_t mac[IEEE80211_ADDR_LEN],
2833 const char *fmt, ...)
2834 {
2835 char buf[128]; /* XXX */
2836 va_list ap;
2837
2838 va_start(ap, fmt);
2839 vsnprintf(buf, sizeof(buf), fmt, ap);
2840 va_end(ap);
2841 if_printf(ic->ic_ifp, "[%s] %s\n", ether_sprintf(mac), buf);
2842 }
2843
2844 void
2845 ieee80211_discard_frame(struct ieee80211com *ic,
2846 const struct ieee80211_frame *wh,
2847 const char *type, const char *fmt, ...)
2848 {
2849 va_list ap;
2850
2851 printf("[%s:%s] discard ", ic->ic_ifp->if_xname,
2852 ether_sprintf(ieee80211_getbssid(ic, wh)));
2853 if (type != NULL)
2854 printf("%s frame, ", type);
2855 else
2856 printf("frame, ");
2857 va_start(ap, fmt);
2858 vprintf(fmt, ap);
2859 va_end(ap);
2860 printf("\n");
2861 }
2862
2863 void
2864 ieee80211_discard_ie(struct ieee80211com *ic,
2865 const struct ieee80211_frame *wh,
2866 const char *type, const char *fmt, ...)
2867 {
2868 va_list ap;
2869
2870 printf("[%s:%s] discard ", ic->ic_ifp->if_xname,
2871 ether_sprintf(ieee80211_getbssid(ic, wh)));
2872 if (type != NULL)
2873 printf("%s information element, ", type);
2874 else
2875 printf("information element, ");
2876 va_start(ap, fmt);
2877 vprintf(fmt, ap);
2878 va_end(ap);
2879 printf("\n");
2880 }
2881
2882 void
2883 ieee80211_discard_mac(struct ieee80211com *ic,
2884 const u_int8_t mac[IEEE80211_ADDR_LEN],
2885 const char *type, const char *fmt, ...)
2886 {
2887 va_list ap;
2888
2889 printf("[%s:%s] discard ", ic->ic_ifp->if_xname, ether_sprintf(mac));
2890 if (type != NULL)
2891 printf("%s frame, ", type);
2892 else
2893 printf("frame, ");
2894 va_start(ap, fmt);
2895 vprintf(fmt, ap);
2896 va_end(ap);
2897 printf("\n");
2898 }
2899 #endif /* IEEE80211_DEBUG */
Cache object: 0df3b0c1dd9e94cd63e3deae17877024
|