]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net80211/ieee80211_sta.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.git] / sys / net80211 / ieee80211_sta.c
1 /*-
2  * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 #ifdef __FreeBSD__
28 __FBSDID("$FreeBSD$");
29 #endif
30
31 /*
32  * IEEE 802.11 Station mode support.
33  */
34 #include "opt_inet.h"
35 #include "opt_wlan.h"
36
37 #include <sys/param.h>
38 #include <sys/systm.h> 
39 #include <sys/mbuf.h>   
40 #include <sys/malloc.h>
41 #include <sys/kernel.h>
42
43 #include <sys/socket.h>
44 #include <sys/sockio.h>
45 #include <sys/endian.h>
46 #include <sys/errno.h>
47 #include <sys/proc.h>
48 #include <sys/sysctl.h>
49
50 #include <net/if.h>
51 #include <net/if_media.h>
52 #include <net/if_llc.h>
53 #include <net/ethernet.h>
54
55 #include <net/bpf.h>
56
57 #include <net80211/ieee80211_var.h>
58 #include <net80211/ieee80211_sta.h>
59 #include <net80211/ieee80211_input.h>
60
61 #define IEEE80211_RATE2MBS(r)   (((r) & IEEE80211_RATE_VAL) / 2)
62
63 static  void sta_vattach(struct ieee80211vap *);
64 static  void sta_beacon_miss(struct ieee80211vap *);
65 static  int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int);
66 static  int sta_input(struct ieee80211_node *, struct mbuf *,
67             int rssi, int noise, uint32_t rstamp);
68 static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *,
69             int subtype, int rssi, int noise, uint32_t rstamp);
70
71 void
72 ieee80211_sta_attach(struct ieee80211com *ic)
73 {
74         ic->ic_vattach[IEEE80211_M_STA] = sta_vattach;
75 }
76
77 void
78 ieee80211_sta_detach(struct ieee80211com *ic)
79 {
80 }
81
82 static void
83 sta_vdetach(struct ieee80211vap *vap)
84 {
85 }
86
87 static void
88 sta_vattach(struct ieee80211vap *vap)
89 {
90         vap->iv_newstate = sta_newstate;
91         vap->iv_input = sta_input;
92         vap->iv_recv_mgmt = sta_recv_mgmt;
93         vap->iv_opdetach = sta_vdetach;
94         vap->iv_bmiss = sta_beacon_miss;
95 }
96
97 /*
98  * Handle a beacon miss event.  The common code filters out
99  * spurious events that can happen when scanning and/or before
100  * reaching RUN state.
101  */
102 static void
103 sta_beacon_miss(struct ieee80211vap *vap)
104 {
105         struct ieee80211com *ic = vap->iv_ic;
106
107         KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scanning"));
108         KASSERT(vap->iv_state == IEEE80211_S_RUN,
109             ("wrong state %d", vap->iv_state));
110
111         IEEE80211_DPRINTF(vap,
112                 IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
113                 "beacon miss, mode %u state %s\n",
114                 vap->iv_opmode, ieee80211_state_name[vap->iv_state]);
115
116         if (++vap->iv_bmiss_count < vap->iv_bmiss_max) {
117                 /*
118                  * Send a directed probe req before falling back to a
119                  * scan; if we receive a response ic_bmiss_count will
120                  * be reset.  Some cards mistakenly report beacon miss
121                  * so this avoids the expensive scan if the ap is
122                  * still there.
123                  */
124                 ieee80211_send_probereq(vap->iv_bss, vap->iv_myaddr,
125                         vap->iv_bss->ni_bssid, vap->iv_bss->ni_bssid,
126                         vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen);
127                 return;
128         }
129         vap->iv_bmiss_count = 0;
130         vap->iv_stats.is_beacon_miss++;
131         if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) {
132                 /*
133                  * If we receive a beacon miss interrupt when using
134                  * dynamic turbo, attempt to switch modes before
135                  * reassociating.
136                  */
137                 if (IEEE80211_ATH_CAP(vap, vap->iv_bss, IEEE80211_NODE_TURBOP))
138                         ieee80211_dturbo_switch(vap,
139                             ic->ic_bsschan->ic_flags ^ IEEE80211_CHAN_TURBO);
140                 /*
141                  * Try to reassociate before scanning for a new ap.
142                  */
143                 ieee80211_new_state(vap, IEEE80211_S_ASSOC, 1);
144         } else {
145                 /*
146                  * Somebody else is controlling state changes (e.g.
147                  * a user-mode app) don't do anything that would
148                  * confuse them; just drop into scan mode so they'll
149                  * notified of the state change and given control.
150                  */
151                 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
152         }
153 }
154
155 /*
156  * Handle deauth with reason.  We retry only for
157  * the cases where we might succeed.  Otherwise
158  * we downgrade the ap and scan.
159  */
160 static void
161 sta_authretry(struct ieee80211vap *vap, struct ieee80211_node *ni, int reason)
162 {
163         switch (reason) {
164         case IEEE80211_STATUS_SUCCESS:          /* NB: MLME assoc */
165         case IEEE80211_STATUS_TIMEOUT:
166         case IEEE80211_REASON_ASSOC_EXPIRE:
167         case IEEE80211_REASON_NOT_AUTHED:
168         case IEEE80211_REASON_NOT_ASSOCED:
169         case IEEE80211_REASON_ASSOC_LEAVE:
170         case IEEE80211_REASON_ASSOC_NOT_AUTHED:
171                 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_AUTH, 1);
172                 break;
173         default:
174                 ieee80211_scan_assoc_fail(vap, vap->iv_bss->ni_macaddr, reason);
175                 if (vap->iv_roaming == IEEE80211_ROAMING_AUTO)
176                         ieee80211_check_scan_current(vap);
177                 break;
178         }
179 }
180
181 /*
182  * IEEE80211_M_STA vap state machine handler.
183  * This routine handles the main states in the 802.11 protocol.
184  */
185 static int
186 sta_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
187 {
188         struct ieee80211com *ic = vap->iv_ic;
189         struct ieee80211_node *ni;
190         enum ieee80211_state ostate;
191
192         IEEE80211_LOCK_ASSERT(ic);
193
194         ostate = vap->iv_state;
195         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
196             __func__, ieee80211_state_name[ostate],
197             ieee80211_state_name[nstate], arg);
198         vap->iv_state = nstate;                 /* state transition */
199         callout_stop(&vap->iv_mgtsend);         /* XXX callout_drain */
200         if (ostate != IEEE80211_S_SCAN)
201                 ieee80211_cancel_scan(vap);     /* background scan */
202         ni = vap->iv_bss;                       /* NB: no reference held */
203         if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
204                 callout_stop(&vap->iv_swbmiss);
205         switch (nstate) {
206         case IEEE80211_S_INIT:
207                 switch (ostate) {
208                 case IEEE80211_S_SLEEP:
209                         /* XXX wakeup */
210                 case IEEE80211_S_RUN:
211                         IEEE80211_SEND_MGMT(ni,
212                             IEEE80211_FC0_SUBTYPE_DISASSOC,
213                             IEEE80211_REASON_ASSOC_LEAVE);
214                         ieee80211_sta_leave(ni);
215                         break;
216                 case IEEE80211_S_ASSOC:
217                         IEEE80211_SEND_MGMT(ni,
218                             IEEE80211_FC0_SUBTYPE_DEAUTH,
219                             IEEE80211_REASON_AUTH_LEAVE);
220                         break;
221                 case IEEE80211_S_SCAN:
222                         ieee80211_cancel_scan(vap);
223                         break;
224                 default:
225                         goto invalid;
226                 }
227                 if (ostate != IEEE80211_S_INIT) {
228                         /* NB: optimize INIT -> INIT case */
229                         ieee80211_reset_bss(vap);
230                 }
231                 if (vap->iv_auth->ia_detach != NULL)
232                         vap->iv_auth->ia_detach(vap);
233                 break;
234         case IEEE80211_S_SCAN:
235                 switch (ostate) {
236                 case IEEE80211_S_INIT:
237                         /*
238                          * Initiate a scan.  We can come here as a result
239                          * of an IEEE80211_IOC_SCAN_REQ too in which case
240                          * the vap will be marked with IEEE80211_FEXT_SCANREQ
241                          * and the scan request parameters will be present
242                          * in iv_scanreq.  Otherwise we do the default.
243                          */
244                         if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) {
245                                 ieee80211_check_scan(vap,
246                                     vap->iv_scanreq_flags,
247                                     vap->iv_scanreq_duration,
248                                     vap->iv_scanreq_mindwell,
249                                     vap->iv_scanreq_maxdwell,
250                                     vap->iv_scanreq_nssid, vap->iv_scanreq_ssid);
251                                 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
252                         } else
253                                 ieee80211_check_scan_current(vap);
254                         break;
255                 case IEEE80211_S_SCAN:
256                 case IEEE80211_S_AUTH:
257                 case IEEE80211_S_ASSOC:
258                         /*
259                          * These can happen either because of a timeout
260                          * on an assoc/auth response or because of a
261                          * change in state that requires a reset.  For
262                          * the former we're called with a non-zero arg
263                          * that is the cause for the failure; pass this
264                          * to the scan code so it can update state.
265                          * Otherwise trigger a new scan unless we're in
266                          * manual roaming mode in which case an application
267                          * must issue an explicit scan request.
268                          */
269                         if (arg != 0)
270                                 ieee80211_scan_assoc_fail(vap,
271                                         vap->iv_bss->ni_macaddr, arg);
272                         if (vap->iv_roaming == IEEE80211_ROAMING_AUTO)
273                                 ieee80211_check_scan_current(vap);
274                         break;
275                 case IEEE80211_S_RUN:           /* beacon miss */
276                         /*
277                          * Beacon miss.  Notify user space and if not
278                          * under control of a user application (roaming
279                          * manual) kick off a scan to re-connect.
280                          */
281                         ieee80211_sta_leave(ni);
282                         if (vap->iv_roaming == IEEE80211_ROAMING_AUTO)
283                                 ieee80211_check_scan_current(vap);
284                         break;
285                 default:
286                         goto invalid;
287                 }
288                 break;
289         case IEEE80211_S_AUTH:
290                 switch (ostate) {
291                 case IEEE80211_S_INIT:
292                 case IEEE80211_S_SCAN:
293                         IEEE80211_SEND_MGMT(ni,
294                             IEEE80211_FC0_SUBTYPE_AUTH, 1);
295                         break;
296                 case IEEE80211_S_AUTH:
297                 case IEEE80211_S_ASSOC:
298                         switch (arg & 0xff) {
299                         case IEEE80211_FC0_SUBTYPE_AUTH:
300                                 /* ??? */
301                                 IEEE80211_SEND_MGMT(ni,
302                                     IEEE80211_FC0_SUBTYPE_AUTH, 2);
303                                 break;
304                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
305                                 sta_authretry(vap, ni, arg>>8);
306                                 break;
307                         }
308                         break;
309                 case IEEE80211_S_RUN:
310                         switch (arg & 0xff) {
311                         case IEEE80211_FC0_SUBTYPE_AUTH:
312                                 IEEE80211_SEND_MGMT(ni,
313                                     IEEE80211_FC0_SUBTYPE_AUTH, 2);
314                                 vap->iv_state = ostate; /* stay RUN */
315                                 break;
316                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
317                                 ieee80211_sta_leave(ni);
318                                 if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) {
319                                         /* try to reauth */
320                                         IEEE80211_SEND_MGMT(ni,
321                                             IEEE80211_FC0_SUBTYPE_AUTH, 1);
322                                 }
323                                 break;
324                         }
325                         break;
326                 default:
327                         goto invalid;
328                 }
329                 break;
330         case IEEE80211_S_ASSOC:
331                 switch (ostate) {
332                 case IEEE80211_S_AUTH:
333                 case IEEE80211_S_ASSOC:
334                         IEEE80211_SEND_MGMT(ni,
335                             IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
336                         break;
337                 case IEEE80211_S_SLEEP:         /* cannot happen */
338                 case IEEE80211_S_RUN:
339                         ieee80211_sta_leave(ni);
340                         if (vap->iv_roaming == IEEE80211_ROAMING_AUTO) {
341                                 IEEE80211_SEND_MGMT(ni, arg ?
342                                     IEEE80211_FC0_SUBTYPE_REASSOC_REQ :
343                                     IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
344                         }
345                         break;
346                 default:
347                         goto invalid;
348                 }
349                 break;
350         case IEEE80211_S_RUN:
351                 if (vap->iv_flags & IEEE80211_F_WPA) {
352                         /* XXX validate prerequisites */
353                 }
354                 switch (ostate) {
355                 case IEEE80211_S_RUN:
356                         break;
357                 case IEEE80211_S_AUTH:          /* when join is done in fw */
358                 case IEEE80211_S_ASSOC:
359 #ifdef IEEE80211_DEBUG
360                         if (ieee80211_msg_debug(vap)) {
361                                 ieee80211_note(vap, "%s with %s ssid ",
362                                     (vap->iv_opmode == IEEE80211_M_STA ?
363                                     "associated" : "synchronized"),
364                                     ether_sprintf(ni->ni_bssid));
365                                 ieee80211_print_essid(vap->iv_bss->ni_essid,
366                                     ni->ni_esslen);
367                                 /* XXX MCS/HT */
368                                 printf(" channel %d start %uMb\n",
369                                     ieee80211_chan2ieee(ic, ic->ic_curchan),
370                                     IEEE80211_RATE2MBS(ni->ni_txrate));
371                         }
372 #endif
373                         ieee80211_scan_assoc_success(vap, ni->ni_macaddr);
374                         ieee80211_notify_node_join(ni, 
375                             arg == IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
376                         break;
377                 case IEEE80211_S_SLEEP:
378                         ieee80211_sta_pwrsave(vap, 0);
379                         break;
380                 default:
381                         goto invalid;
382                 }
383                 ieee80211_sync_curchan(ic);
384                 if (ostate != IEEE80211_S_RUN &&
385                     (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
386                         /*
387                          * Start s/w beacon miss timer for devices w/o
388                          * hardware support.  We fudge a bit here since
389                          * we're doing this in software.
390                          */
391                         vap->iv_swbmiss_period = IEEE80211_TU_TO_TICKS(
392                                 2 * vap->iv_bmissthreshold * ni->ni_intval);
393                         vap->iv_swbmiss_count = 0;
394                         callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period,
395                                 ieee80211_swbmiss, vap);
396                 }
397                 /*
398                  * When 802.1x is not in use mark the port authorized
399                  * at this point so traffic can flow.
400                  */
401                 if (ni->ni_authmode != IEEE80211_AUTH_8021X)
402                         ieee80211_node_authorize(ni);
403                 break;
404         case IEEE80211_S_SLEEP:
405                 ieee80211_sta_pwrsave(vap, 0);
406                 break;
407         default:
408         invalid:
409                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY,
410                     "%s: invalid state transition %s -> %s\n", __func__,
411                     ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
412                 break;
413         }
414         return 0;
415 }
416
417 /*
418  * Return non-zero if the frame is an echo of a multicast
419  * frame sent by ourself.  The dir is known to be DSTODS.
420  */
421 static __inline int
422 isdstods_mcastecho(struct ieee80211vap *vap, const struct ieee80211_frame *wh)
423 {
424 #define QWH4(wh)        ((const struct ieee80211_qosframe_addr4 *)wh)
425 #define WH4(wh)         ((const struct ieee80211_frame_addr4 *)wh)
426         const uint8_t *sa;
427
428         KASSERT(vap->iv_opmode == IEEE80211_M_STA, ("wrong mode"));
429
430         if (!IEEE80211_IS_MULTICAST(wh->i_addr3))
431                 return 0;
432         sa = IEEE80211_QOS_HAS_SEQ(wh) ? QWH4(wh)->i_addr4 : WH4(wh)->i_addr4;
433         return IEEE80211_ADDR_EQ(sa, vap->iv_myaddr);
434 #undef WH4
435 #undef QWH4
436 }
437
438 /*
439  * Return non-zero if the frame is an echo of a multicast
440  * frame sent by ourself.  The dir is known to be FROMDS.
441  */
442 static __inline int
443 isfromds_mcastecho(struct ieee80211vap *vap, const struct ieee80211_frame *wh)
444 {
445         KASSERT(vap->iv_opmode == IEEE80211_M_STA, ("wrong mode"));
446
447         if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
448                 return 0;
449         return IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr);
450 }
451
452 /*
453  * Decide if a received management frame should be
454  * printed when debugging is enabled.  This filters some
455  * of the less interesting frames that come frequently
456  * (e.g. beacons).
457  */
458 static __inline int
459 doprint(struct ieee80211vap *vap, int subtype)
460 {
461         switch (subtype) {
462         case IEEE80211_FC0_SUBTYPE_BEACON:
463                 return (vap->iv_ic->ic_flags & IEEE80211_F_SCAN);
464         case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
465                 return 0;
466         }
467         return 1;
468 }
469
470 /*
471  * Process a received frame.  The node associated with the sender
472  * should be supplied.  If nothing was found in the node table then
473  * the caller is assumed to supply a reference to iv_bss instead.
474  * The RSSI and a timestamp are also supplied.  The RSSI data is used
475  * during AP scanning to select a AP to associate with; it can have
476  * any units so long as values have consistent units and higher values
477  * mean ``better signal''.  The receive timestamp is currently not used
478  * by the 802.11 layer.
479  */
480 static int
481 sta_input(struct ieee80211_node *ni, struct mbuf *m,
482         int rssi, int noise, uint32_t rstamp)
483 {
484 #define SEQ_LEQ(a,b)    ((int)((a)-(b)) <= 0)
485 #define HAS_SEQ(type)   ((type & 0x4) == 0)
486         struct ieee80211vap *vap = ni->ni_vap;
487         struct ieee80211com *ic = ni->ni_ic;
488         struct ifnet *ifp = vap->iv_ifp;
489         struct ieee80211_frame *wh;
490         struct ieee80211_key *key;
491         struct ether_header *eh;
492         int hdrspace, need_tap;
493         uint8_t dir, type, subtype, qos;
494         uint8_t *bssid;
495         uint16_t rxseq;
496
497         if (m->m_flags & M_AMPDU_MPDU) {
498                 /*
499                  * Fastpath for A-MPDU reorder q resubmission.  Frames
500                  * w/ M_AMPDU_MPDU marked have already passed through
501                  * here but were received out of order and been held on
502                  * the reorder queue.  When resubmitted they are marked
503                  * with the M_AMPDU_MPDU flag and we can bypass most of
504                  * the normal processing.
505                  */
506                 wh = mtod(m, struct ieee80211_frame *);
507                 type = IEEE80211_FC0_TYPE_DATA;
508                 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
509                 subtype = IEEE80211_FC0_SUBTYPE_QOS;
510                 hdrspace = ieee80211_hdrspace(ic, wh);  /* XXX optimize? */
511                 goto resubmit_ampdu;
512         }
513
514         KASSERT(ni != NULL, ("null node"));
515         ni->ni_inact = ni->ni_inact_reload;
516
517         need_tap = 1;                   /* mbuf need to be tapped. */
518         type = -1;                      /* undefined */
519
520         if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
521                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
522                     ni->ni_macaddr, NULL,
523                     "too short (1): len %u", m->m_pkthdr.len);
524                 vap->iv_stats.is_rx_tooshort++;
525                 goto out;
526         }
527         /*
528          * Bit of a cheat here, we use a pointer for a 3-address
529          * frame format but don't reference fields past outside
530          * ieee80211_frame_min w/o first validating the data is
531          * present.
532          */
533         wh = mtod(m, struct ieee80211_frame *);
534
535         if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
536             IEEE80211_FC0_VERSION_0) {
537                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
538                     ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]);
539                 vap->iv_stats.is_rx_badversion++;
540                 goto err;
541         }
542
543         dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
544         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
545         subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
546         if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
547                 bssid = wh->i_addr2;
548                 if (!IEEE80211_ADDR_EQ(bssid, ni->ni_bssid)) {
549                         /* not interested in */
550                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
551                             bssid, NULL, "%s", "not to bss");
552                         vap->iv_stats.is_rx_wrongbss++;
553                         goto out;
554                 }
555                 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
556                 ni->ni_noise = noise;
557                 ni->ni_rstamp = rstamp;
558                 if (HAS_SEQ(type)) {
559                         uint8_t tid = ieee80211_gettid(wh);
560                         if (IEEE80211_QOS_HAS_SEQ(wh) &&
561                             TID_TO_WME_AC(tid) >= WME_AC_VI)
562                                 ic->ic_wme.wme_hipri_traffic++;
563                         rxseq = le16toh(*(uint16_t *)wh->i_seq);
564                         if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 &&
565                             (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
566                             SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
567                                 /* duplicate, discard */
568                                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
569                                     bssid, "duplicate",
570                                     "seqno <%u,%u> fragno <%u,%u> tid %u",
571                                     rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
572                                     ni->ni_rxseqs[tid] >>
573                                         IEEE80211_SEQ_SEQ_SHIFT,
574                                     rxseq & IEEE80211_SEQ_FRAG_MASK,
575                                     ni->ni_rxseqs[tid] &
576                                         IEEE80211_SEQ_FRAG_MASK,
577                                     tid);
578                                 vap->iv_stats.is_rx_dup++;
579                                 IEEE80211_NODE_STAT(ni, rx_dup);
580                                 goto out;
581                         }
582                         ni->ni_rxseqs[tid] = rxseq;
583                 }
584         }
585
586         switch (type) {
587         case IEEE80211_FC0_TYPE_DATA:
588                 hdrspace = ieee80211_hdrspace(ic, wh);
589                 if (m->m_len < hdrspace &&
590                     (m = m_pullup(m, hdrspace)) == NULL) {
591                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
592                             ni->ni_macaddr, NULL,
593                             "data too short: expecting %u", hdrspace);
594                         vap->iv_stats.is_rx_tooshort++;
595                         goto out;               /* XXX */
596                 }
597                 /*
598                  * Handle A-MPDU re-ordering.  If the frame is to be
599                  * processed directly then ieee80211_ampdu_reorder
600                  * will return 0; otherwise it has consumed the mbuf
601                  * and we should do nothing more with it.
602                  */
603                 if ((m->m_flags & M_AMPDU) &&
604                     (dir == IEEE80211_FC1_DIR_FROMDS ||
605                      dir == IEEE80211_FC1_DIR_DSTODS) &&
606                     ieee80211_ampdu_reorder(ni, m) != 0) {
607                         m = NULL;
608                         goto out;
609                 }
610         resubmit_ampdu:
611                 if (dir == IEEE80211_FC1_DIR_FROMDS) {
612                         if ((ifp->if_flags & IFF_SIMPLEX) &&
613                             isfromds_mcastecho(vap, wh)) {
614                                 /*
615                                  * In IEEE802.11 network, multicast
616                                  * packets sent from "me" are broadcast
617                                  * from the AP; silently discard for
618                                  * SIMPLEX interface.
619                                  */
620                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
621                                     wh, "data", "%s", "multicast echo");
622                                 vap->iv_stats.is_rx_mcastecho++;
623                                 goto out;
624                         }
625                         if ((vap->iv_flags & IEEE80211_F_DWDS) &&
626                             IEEE80211_IS_MULTICAST(wh->i_addr1)) {
627                                 /*
628                                  * DWDS sta's must drop 3-address mcast frames
629                                  * as they will be sent separately as a 4-addr
630                                  * frame.  Accepting the 3-addr frame will
631                                  * confuse the bridge into thinking the sending
632                                  * sta is located at the end of WDS link.
633                                  */
634                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh,
635                                     "3-address data", "%s", "DWDS enabled");
636                                 vap->iv_stats.is_rx_mcastecho++;
637                                 goto out;
638                         }
639                 } else if (dir == IEEE80211_FC1_DIR_DSTODS) {
640                         if ((vap->iv_flags & IEEE80211_F_DWDS) == 0) {
641                                 IEEE80211_DISCARD(vap,
642                                     IEEE80211_MSG_INPUT, wh, "4-address data",
643                                     "%s", "DWDS not enabled");
644                                 vap->iv_stats.is_rx_wrongdir++;
645                                 goto out;
646                         }
647                         if ((ifp->if_flags & IFF_SIMPLEX) &&
648                             isdstods_mcastecho(vap, wh)) {
649                                 /*
650                                  * In IEEE802.11 network, multicast
651                                  * packets sent from "me" are broadcast
652                                  * from the AP; silently discard for
653                                  * SIMPLEX interface.
654                                  */
655                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh,
656                                     "4-address data", "%s", "multicast echo");
657                                 vap->iv_stats.is_rx_mcastecho++;
658                                 goto out;
659                         }
660                 } else {
661                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh,
662                             "data", "incorrect dir 0x%x", dir);
663                         vap->iv_stats.is_rx_wrongdir++;
664                         goto out;
665                 }
666
667                 /*
668                  * Handle privacy requirements.  Note that we
669                  * must not be preempted from here until after
670                  * we (potentially) call ieee80211_crypto_demic;
671                  * otherwise we may violate assumptions in the
672                  * crypto cipher modules used to do delayed update
673                  * of replay sequence numbers.
674                  */
675                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
676                         if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
677                                 /*
678                                  * Discard encrypted frames when privacy is off.
679                                  */
680                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
681                                     wh, "WEP", "%s", "PRIVACY off");
682                                 vap->iv_stats.is_rx_noprivacy++;
683                                 IEEE80211_NODE_STAT(ni, rx_noprivacy);
684                                 goto out;
685                         }
686                         key = ieee80211_crypto_decap(ni, m, hdrspace);
687                         if (key == NULL) {
688                                 /* NB: stats+msgs handled in crypto_decap */
689                                 IEEE80211_NODE_STAT(ni, rx_wepfail);
690                                 goto out;
691                         }
692                         wh = mtod(m, struct ieee80211_frame *);
693                         wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
694                 } else {
695                         /* XXX M_WEP and IEEE80211_F_PRIVACY */
696                         key = NULL;
697                 }
698
699                 /*
700                  * Save QoS bits for use below--before we strip the header.
701                  */
702                 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
703                         qos = (dir == IEEE80211_FC1_DIR_DSTODS) ?
704                             ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] :
705                             ((struct ieee80211_qosframe *)wh)->i_qos[0];
706                 } else
707                         qos = 0;
708
709                 /*
710                  * Next up, any fragmentation.
711                  */
712                 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
713                         m = ieee80211_defrag(ni, m, hdrspace);
714                         if (m == NULL) {
715                                 /* Fragment dropped or frame not complete yet */
716                                 goto out;
717                         }
718                 }
719                 wh = NULL;              /* no longer valid, catch any uses */
720
721                 /*
722                  * Next strip any MSDU crypto bits.
723                  */
724                 if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) {
725                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
726                             ni->ni_macaddr, "data", "%s", "demic error");
727                         vap->iv_stats.is_rx_demicfail++;
728                         IEEE80211_NODE_STAT(ni, rx_demicfail);
729                         goto out;
730                 }
731
732                 /* copy to listener after decrypt */
733                 if (bpf_peers_present(vap->iv_rawbpf))
734                         bpf_mtap(vap->iv_rawbpf, m);
735                 need_tap = 0;
736
737                 /*
738                  * Finally, strip the 802.11 header.
739                  */
740                 m = ieee80211_decap(vap, m, hdrspace);
741                 if (m == NULL) {
742                         /* XXX mask bit to check for both */
743                         /* don't count Null data frames as errors */
744                         if (subtype == IEEE80211_FC0_SUBTYPE_NODATA ||
745                             subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL)
746                                 goto out;
747                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
748                             ni->ni_macaddr, "data", "%s", "decap error");
749                         vap->iv_stats.is_rx_decap++;
750                         IEEE80211_NODE_STAT(ni, rx_decap);
751                         goto err;
752                 }
753                 eh = mtod(m, struct ether_header *);
754                 if (!ieee80211_node_is_authorized(ni)) {
755                         /*
756                          * Deny any non-PAE frames received prior to
757                          * authorization.  For open/shared-key
758                          * authentication the port is mark authorized
759                          * after authentication completes.  For 802.1x
760                          * the port is not marked authorized by the
761                          * authenticator until the handshake has completed.
762                          */
763                         if (eh->ether_type != htons(ETHERTYPE_PAE)) {
764                                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
765                                     eh->ether_shost, "data",
766                                     "unauthorized port: ether type 0x%x len %u",
767                                     eh->ether_type, m->m_pkthdr.len);
768                                 vap->iv_stats.is_rx_unauth++;
769                                 IEEE80211_NODE_STAT(ni, rx_unauth);
770                                 goto err;
771                         }
772                 } else {
773                         /*
774                          * When denying unencrypted frames, discard
775                          * any non-PAE frames received without encryption.
776                          */
777                         if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
778                             (key == NULL && (m->m_flags & M_WEP) == 0) &&
779                             eh->ether_type != htons(ETHERTYPE_PAE)) {
780                                 /*
781                                  * Drop unencrypted frames.
782                                  */
783                                 vap->iv_stats.is_rx_unencrypted++;
784                                 IEEE80211_NODE_STAT(ni, rx_unencrypted);
785                                 goto out;
786                         }
787                 }
788                 /* XXX require HT? */
789                 if (qos & IEEE80211_QOS_AMSDU) {
790                         m = ieee80211_decap_amsdu(ni, m);
791                         if (m == NULL)
792                                 return IEEE80211_FC0_TYPE_DATA;
793                 } else if ((ni->ni_ath_flags & IEEE80211_NODE_FF) &&
794 #define FF_LLC_SIZE     (sizeof(struct ether_header) + sizeof(struct llc))
795                     m->m_pkthdr.len >= 3*FF_LLC_SIZE) {
796                         struct llc *llc;
797
798                         /*
799                          * Check for fast-frame tunnel encapsulation.
800                          */
801                         if (m->m_len < FF_LLC_SIZE &&
802                             (m = m_pullup(m, FF_LLC_SIZE)) == NULL) {
803                                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
804                                     ni->ni_macaddr, "fast-frame",
805                                     "%s", "m_pullup(llc) failed");
806                                 vap->iv_stats.is_rx_tooshort++;
807                                 return IEEE80211_FC0_TYPE_DATA;
808                         }
809                         llc = (struct llc *)(mtod(m, uint8_t *) + 
810                                 sizeof(struct ether_header));
811                         if (llc->llc_snap.ether_type == htons(ATH_FF_ETH_TYPE)) {
812                                 m_adj(m, FF_LLC_SIZE);
813                                 m = ieee80211_decap_fastframe(ni, m);
814                                 if (m == NULL)
815                                         return IEEE80211_FC0_TYPE_DATA;
816                         }
817                 }
818 #undef FF_LLC_SIZE
819                 ieee80211_deliver_data(vap, ni, m);
820                 return IEEE80211_FC0_TYPE_DATA;
821
822         case IEEE80211_FC0_TYPE_MGT:
823                 vap->iv_stats.is_rx_mgmt++;
824                 IEEE80211_NODE_STAT(ni, rx_mgmt);
825                 if (dir != IEEE80211_FC1_DIR_NODS) {
826                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
827                             wh, "data", "incorrect dir 0x%x", dir);
828                         vap->iv_stats.is_rx_wrongdir++;
829                         goto err;
830                 }
831                 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
832                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
833                             ni->ni_macaddr, "mgt", "too short: len %u",
834                             m->m_pkthdr.len);
835                         vap->iv_stats.is_rx_tooshort++;
836                         goto out;
837                 }
838 #ifdef IEEE80211_DEBUG
839                 if ((ieee80211_msg_debug(vap) && doprint(vap, subtype)) ||
840                     ieee80211_msg_dumppkts(vap)) {
841                         if_printf(ifp, "received %s from %s rssi %d\n",
842                             ieee80211_mgt_subtype_name[subtype >>
843                                 IEEE80211_FC0_SUBTYPE_SHIFT],
844                             ether_sprintf(wh->i_addr2), rssi);
845                 }
846 #endif
847                 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
848                         if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) {
849                                 /*
850                                  * Only shared key auth frames with a challenge
851                                  * should be encrypted, discard all others.
852                                  */
853                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
854                                     wh, ieee80211_mgt_subtype_name[subtype >>
855                                         IEEE80211_FC0_SUBTYPE_SHIFT],
856                                     "%s", "WEP set but not permitted");
857                                 vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
858                                 goto out;
859                         }
860                         if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
861                                 /*
862                                  * Discard encrypted frames when privacy is off.
863                                  */
864                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
865                                     wh, "mgt", "%s", "WEP set but PRIVACY off");
866                                 vap->iv_stats.is_rx_noprivacy++;
867                                 goto out;
868                         }
869                         hdrspace = ieee80211_hdrspace(ic, wh);
870                         key = ieee80211_crypto_decap(ni, m, hdrspace);
871                         if (key == NULL) {
872                                 /* NB: stats+msgs handled in crypto_decap */
873                                 goto out;
874                         }
875                         wh = mtod(m, struct ieee80211_frame *);
876                         wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
877                 }
878                 if (bpf_peers_present(vap->iv_rawbpf))
879                         bpf_mtap(vap->iv_rawbpf, m);
880                 vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
881                 m_freem(m);
882                 return IEEE80211_FC0_TYPE_MGT;
883
884         case IEEE80211_FC0_TYPE_CTL:
885                 vap->iv_stats.is_rx_ctl++;
886                 IEEE80211_NODE_STAT(ni, rx_ctrl);
887                 goto out;
888         default:
889                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
890                     wh, NULL, "bad frame type 0x%x", type);
891                 /* should not come here */
892                 break;
893         }
894 err:
895         ifp->if_ierrors++;
896 out:
897         if (m != NULL) {
898                 if (bpf_peers_present(vap->iv_rawbpf) && need_tap)
899                         bpf_mtap(vap->iv_rawbpf, m);
900                 m_freem(m);
901         }
902         return type;
903 #undef SEQ_LEQ
904 }
905
906 static void
907 sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
908     int rssi, int noise, uint32_t rstamp, uint16_t seq, uint16_t status)
909 {
910         struct ieee80211vap *vap = ni->ni_vap;
911
912         if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
913                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH,
914                     ni->ni_macaddr, "open auth",
915                     "bad sta auth mode %u", ni->ni_authmode);
916                 vap->iv_stats.is_rx_bad_auth++; /* XXX */
917                 return;
918         }
919         if (vap->iv_state != IEEE80211_S_AUTH ||
920             seq != IEEE80211_AUTH_OPEN_RESPONSE) {
921                 vap->iv_stats.is_rx_bad_auth++;
922                 return;
923         }
924         if (status != 0) {
925                 IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
926                     ni, "open auth failed (reason %d)", status);
927                 vap->iv_stats.is_rx_auth_fail++;
928                 vap->iv_stats.is_rx_authfail_code = status;
929                 ieee80211_new_state(vap, IEEE80211_S_SCAN,
930                     IEEE80211_SCAN_FAIL_STATUS);
931         } else
932                 ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
933 }
934
935 static void
936 sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
937     uint8_t *frm, uint8_t *efrm, int rssi, int noise, uint32_t rstamp,
938     uint16_t seq, uint16_t status)
939 {
940         struct ieee80211vap *vap = ni->ni_vap;
941         uint8_t *challenge;
942         int estatus;
943
944         /*
945          * NB: this can happen as we allow pre-shared key
946          * authentication to be enabled w/o wep being turned
947          * on so that configuration of these can be done
948          * in any order.  It may be better to enforce the
949          * ordering in which case this check would just be
950          * for sanity/consistency.
951          */
952         if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
953                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH,
954                     ni->ni_macaddr, "shared key auth",
955                     "%s", " PRIVACY is disabled");
956                 estatus = IEEE80211_STATUS_ALG;
957                 goto bad;
958         }
959         /*
960          * Pre-shared key authentication is evil; accept
961          * it only if explicitly configured (it is supported
962          * mainly for compatibility with clients like OS X).
963          */
964         if (ni->ni_authmode != IEEE80211_AUTH_AUTO &&
965             ni->ni_authmode != IEEE80211_AUTH_SHARED) {
966                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH,
967                     ni->ni_macaddr, "shared key auth",
968                     "bad sta auth mode %u", ni->ni_authmode);
969                 vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */
970                 estatus = IEEE80211_STATUS_ALG;
971                 goto bad;
972         }
973
974         challenge = NULL;
975         if (frm + 1 < efrm) {
976                 if ((frm[1] + 2) > (efrm - frm)) {
977                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH,
978                             ni->ni_macaddr, "shared key auth",
979                             "ie %d/%d too long",
980                             frm[0], (frm[1] + 2) - (efrm - frm));
981                         vap->iv_stats.is_rx_bad_auth++;
982                         estatus = IEEE80211_STATUS_CHALLENGE;
983                         goto bad;
984                 }
985                 if (*frm == IEEE80211_ELEMID_CHALLENGE)
986                         challenge = frm;
987                 frm += frm[1] + 2;
988         }
989         switch (seq) {
990         case IEEE80211_AUTH_SHARED_CHALLENGE:
991         case IEEE80211_AUTH_SHARED_RESPONSE:
992                 if (challenge == NULL) {
993                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH,
994                             ni->ni_macaddr, "shared key auth",
995                             "%s", "no challenge");
996                         vap->iv_stats.is_rx_bad_auth++;
997                         estatus = IEEE80211_STATUS_CHALLENGE;
998                         goto bad;
999                 }
1000                 if (challenge[1] != IEEE80211_CHALLENGE_LEN) {
1001                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_AUTH,
1002                             ni->ni_macaddr, "shared key auth",
1003                             "bad challenge len %d", challenge[1]);
1004                         vap->iv_stats.is_rx_bad_auth++;
1005                         estatus = IEEE80211_STATUS_CHALLENGE;
1006                         goto bad;
1007                 }
1008         default:
1009                 break;
1010         }
1011         if (vap->iv_state != IEEE80211_S_AUTH)
1012                 return;
1013         switch (seq) {
1014         case IEEE80211_AUTH_SHARED_PASS:
1015                 if (ni->ni_challenge != NULL) {
1016                         FREE(ni->ni_challenge, M_80211_NODE);
1017                         ni->ni_challenge = NULL;
1018                 }
1019                 if (status != 0) {
1020                         IEEE80211_NOTE_FRAME(vap,
1021                             IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, wh,
1022                             "shared key auth failed (reason %d)", status);
1023                         vap->iv_stats.is_rx_auth_fail++;
1024                         vap->iv_stats.is_rx_authfail_code = status;
1025                         return;
1026                 }
1027                 ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
1028                 break;
1029         case IEEE80211_AUTH_SHARED_CHALLENGE:
1030                 if (!ieee80211_alloc_challenge(ni))
1031                         return;
1032                 /* XXX could optimize by passing recvd challenge */
1033                 memcpy(ni->ni_challenge, &challenge[2], challenge[1]);
1034                 IEEE80211_SEND_MGMT(ni,
1035                         IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
1036                 break;
1037         default:
1038                 IEEE80211_DISCARD(vap, IEEE80211_MSG_AUTH,
1039                     wh, "shared key auth", "bad seq %d", seq);
1040                 vap->iv_stats.is_rx_bad_auth++;
1041                 return;
1042         }
1043         return;
1044 bad:
1045         /*
1046          * Kick the state machine.  This short-circuits
1047          * using the mgt frame timeout to trigger the
1048          * state transition.
1049          */
1050         if (vap->iv_state == IEEE80211_S_AUTH)
1051                 ieee80211_new_state(vap, IEEE80211_S_SCAN,
1052                     IEEE80211_SCAN_FAIL_STATUS);
1053 }
1054
1055 static int
1056 ieee80211_parse_wmeparams(struct ieee80211vap *vap, uint8_t *frm,
1057         const struct ieee80211_frame *wh)
1058 {
1059 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
1060         struct ieee80211_wme_state *wme = &vap->iv_ic->ic_wme;
1061         u_int len = frm[1], qosinfo;
1062         int i;
1063
1064         if (len < sizeof(struct ieee80211_wme_param)-2) {
1065                 IEEE80211_DISCARD_IE(vap,
1066                     IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME,
1067                     wh, "WME", "too short, len %u", len);
1068                 return -1;
1069         }
1070         qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)];
1071         qosinfo &= WME_QOSINFO_COUNT;
1072         /* XXX do proper check for wraparound */
1073         if (qosinfo == wme->wme_wmeChanParams.cap_info)
1074                 return 0;
1075         frm += __offsetof(struct ieee80211_wme_param, params_acParams);
1076         for (i = 0; i < WME_NUM_AC; i++) {
1077                 struct wmeParams *wmep =
1078                         &wme->wme_wmeChanParams.cap_wmeParams[i];
1079                 /* NB: ACI not used */
1080                 wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM);
1081                 wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN);
1082                 wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN);
1083                 wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX);
1084                 wmep->wmep_txopLimit = LE_READ_2(frm+2);
1085                 frm += 4;
1086         }
1087         wme->wme_wmeChanParams.cap_info = qosinfo;
1088         return 1;
1089 #undef MS
1090 }
1091
1092 static int
1093 ieee80211_parse_athparams(struct ieee80211_node *ni, uint8_t *frm,
1094         const struct ieee80211_frame *wh)
1095 {
1096         struct ieee80211vap *vap = ni->ni_vap;
1097         const struct ieee80211_ath_ie *ath;
1098         u_int len = frm[1];
1099         int capschanged;
1100         uint16_t defkeyix;
1101
1102         if (len < sizeof(struct ieee80211_ath_ie)-2) {
1103                 IEEE80211_DISCARD_IE(vap,
1104                     IEEE80211_MSG_ELEMID | IEEE80211_MSG_SUPERG,
1105                     wh, "Atheros", "too short, len %u", len);
1106                 return -1;
1107         }
1108         ath = (const struct ieee80211_ath_ie *)frm;
1109         capschanged = (ni->ni_ath_flags != ath->ath_capability);
1110         defkeyix = LE_READ_2(ath->ath_defkeyix);
1111         if (capschanged || defkeyix != ni->ni_ath_defkeyix) {
1112                 ni->ni_ath_flags = ath->ath_capability;
1113                 ni->ni_ath_defkeyix = defkeyix;
1114                 IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni,
1115                     "ath ie change: new caps 0x%x defkeyix 0x%x",
1116                     ni->ni_ath_flags, ni->ni_ath_defkeyix);
1117         }
1118         if (IEEE80211_ATH_CAP(vap, ni, ATHEROS_CAP_TURBO_PRIME)) {
1119                 uint16_t curflags, newflags;
1120
1121                 /*
1122                  * Check for turbo mode switch.  Calculate flags
1123                  * for the new mode and effect the switch.
1124                  */
1125                 newflags = curflags = vap->iv_ic->ic_bsschan->ic_flags;
1126                 /* NB: BOOST is not in ic_flags, so get it from the ie */
1127                 if (ath->ath_capability & ATHEROS_CAP_BOOST) 
1128                         newflags |= IEEE80211_CHAN_TURBO;
1129                 else
1130                         newflags &= ~IEEE80211_CHAN_TURBO;
1131                 if (newflags != curflags)
1132                         ieee80211_dturbo_switch(vap, newflags);
1133         }
1134         return capschanged;
1135 }
1136
1137 /*
1138  * Return non-zero if a background scan may be continued:
1139  * o bg scan is active
1140  * o no channel switch is pending
1141  * o there has not been any traffic recently
1142  *
1143  * Note we do not check if there is an administrative enable;
1144  * this is only done to start the scan.  We assume that any
1145  * change in state will be accompanied by a request to cancel
1146  * active scans which will otherwise cause this test to fail.
1147  */
1148 static __inline int
1149 contbgscan(struct ieee80211vap *vap)
1150 {
1151         struct ieee80211com *ic = vap->iv_ic;
1152
1153         return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) &&
1154             (ic->ic_flags & IEEE80211_F_CSAPENDING) == 0 &&
1155             vap->iv_state == IEEE80211_S_RUN &&         /* XXX? */
1156             time_after(ticks, ic->ic_lastdata + vap->iv_bgscanidle));
1157 }
1158
1159 /*
1160  * Return non-zero if a backgrond scan may be started:
1161  * o bg scanning is administratively enabled
1162  * o no channel switch is pending
1163  * o we are not boosted on a dynamic turbo channel
1164  * o there has not been a scan recently
1165  * o there has not been any traffic recently
1166  */
1167 static __inline int
1168 startbgscan(struct ieee80211vap *vap)
1169 {
1170         struct ieee80211com *ic = vap->iv_ic;
1171
1172         return ((vap->iv_flags & IEEE80211_F_BGSCAN) &&
1173             (ic->ic_flags & IEEE80211_F_CSAPENDING) == 0 &&
1174             !IEEE80211_IS_CHAN_DTURBO(ic->ic_curchan) &&
1175             time_after(ticks, ic->ic_lastscan + vap->iv_bgscanintvl) &&
1176             time_after(ticks, ic->ic_lastdata + vap->iv_bgscanidle));
1177 }
1178
1179 static void
1180 sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
1181         int subtype, int rssi, int noise, uint32_t rstamp)
1182 {
1183 #define ISPROBE(_st)    ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1184 #define ISREASSOC(_st)  ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
1185         struct ieee80211vap *vap = ni->ni_vap;
1186         struct ieee80211com *ic = ni->ni_ic;
1187         struct ieee80211_frame *wh;
1188         uint8_t *frm, *efrm;
1189         uint8_t *rates, *xrates, *wme, *htcap, *htinfo;
1190         uint8_t rate;
1191
1192         wh = mtod(m0, struct ieee80211_frame *);
1193         frm = (uint8_t *)&wh[1];
1194         efrm = mtod(m0, uint8_t *) + m0->m_len;
1195         switch (subtype) {
1196         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1197         case IEEE80211_FC0_SUBTYPE_BEACON: {
1198                 struct ieee80211_scanparams scan;
1199                 /*
1200                  * We process beacon/probe response frames:
1201                  *    o when scanning, or
1202                  *    o station mode when associated (to collect state
1203                  *      updates such as 802.11g slot time), or
1204                  * Frames otherwise received are discarded.
1205                  */ 
1206                 if (!((ic->ic_flags & IEEE80211_F_SCAN) || ni->ni_associd)) {
1207                         vap->iv_stats.is_rx_mgtdiscard++;
1208                         return;
1209                 }
1210                 /* XXX probe response in sta mode when !scanning? */
1211                 if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
1212                         return;
1213                 /*
1214                  * Count frame now that we know it's to be processed.
1215                  */
1216                 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
1217                         vap->iv_stats.is_rx_beacon++;           /* XXX remove */
1218                         IEEE80211_NODE_STAT(ni, rx_beacons);
1219                 } else
1220                         IEEE80211_NODE_STAT(ni, rx_proberesp);
1221                 /*
1222                  * When operating in station mode, check for state updates.
1223                  * Be careful to ignore beacons received while doing a
1224                  * background scan.  We consider only 11g/WMM stuff right now.
1225                  */
1226                 if (ni->ni_associd != 0 &&
1227                     ((ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
1228                      IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) {
1229                         /* record tsf of last beacon */
1230                         memcpy(ni->ni_tstamp.data, scan.tstamp,
1231                                 sizeof(ni->ni_tstamp));
1232                         /* count beacon frame for s/w bmiss handling */
1233                         vap->iv_swbmiss_count++;
1234                         vap->iv_bmiss_count = 0;
1235                         if (ni->ni_erp != scan.erp) {
1236                                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC,
1237                                     wh->i_addr2,
1238                                     "erp change: was 0x%x, now 0x%x",
1239                                     ni->ni_erp, scan.erp);
1240                                 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&
1241                                     (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
1242                                         ic->ic_flags |= IEEE80211_F_USEPROT;
1243                                 else
1244                                         ic->ic_flags &= ~IEEE80211_F_USEPROT;
1245                                 ni->ni_erp = scan.erp;
1246                                 /* XXX statistic */
1247                                 /* XXX driver notification */
1248                         }
1249                         if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
1250                                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC,
1251                                     wh->i_addr2,
1252                                     "capabilities change: was 0x%x, now 0x%x",
1253                                     ni->ni_capinfo, scan.capinfo);
1254                                 /*
1255                                  * NB: we assume short preamble doesn't
1256                                  *     change dynamically
1257                                  */
1258                                 ieee80211_set_shortslottime(ic,
1259                                         IEEE80211_IS_CHAN_A(ic->ic_bsschan) ||
1260                                         (scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1261                                 ni->ni_capinfo = (ni->ni_capinfo &~ IEEE80211_CAPINFO_SHORT_SLOTTIME)
1262                                                | (scan.capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME);
1263                                 /* XXX statistic */
1264                         }
1265                         if (scan.wme != NULL &&
1266                             (ni->ni_flags & IEEE80211_NODE_QOS) &&
1267                             ieee80211_parse_wmeparams(vap, scan.wme, wh) > 0)
1268                                 ieee80211_wme_updateparams(vap);
1269                         if (scan.ath != NULL)
1270                                 ieee80211_parse_athparams(ni, scan.ath, wh);
1271                         if (scan.htcap != NULL && scan.htinfo != NULL &&
1272                             (vap->iv_flags_ext & IEEE80211_FEXT_HT)) {
1273                                 ieee80211_ht_updateparams(ni,
1274                                     scan.htcap, scan.htinfo);
1275                                 /* XXX state changes? */
1276                         }
1277                         if (scan.tim != NULL) {
1278                                 struct ieee80211_tim_ie *tim =
1279                                     (struct ieee80211_tim_ie *) scan.tim;
1280 #if 0
1281                                 int aid = IEEE80211_AID(ni->ni_associd);
1282                                 int ix = aid / NBBY;
1283                                 int min = tim->tim_bitctl &~ 1;
1284                                 int max = tim->tim_len + min - 4;
1285                                 if ((tim->tim_bitctl&1) ||
1286                                     (min <= ix && ix <= max &&
1287                                      isset(tim->tim_bitmap - min, aid))) {
1288                                         /* 
1289                                          * XXX Do not let bg scan kick off
1290                                          * we are expecting data.
1291                                          */
1292                                         ic->ic_lastdata = ticks;
1293                                         ieee80211_sta_pwrsave(vap, 0);
1294                                 }
1295 #endif
1296                                 ni->ni_dtim_count = tim->tim_count;
1297                                 ni->ni_dtim_period = tim->tim_period;
1298                         }
1299                         /*
1300                          * If scanning, pass the info to the scan module.
1301                          * Otherwise, check if it's the right time to do
1302                          * a background scan.  Background scanning must
1303                          * be enabled and we must not be operating in the
1304                          * turbo phase of dynamic turbo mode.  Then,
1305                          * it's been a while since the last background
1306                          * scan and if no data frames have come through
1307                          * recently, kick off a scan.  Note that this
1308                          * is the mechanism by which a background scan
1309                          * is started _and_ continued each time we
1310                          * return on-channel to receive a beacon from
1311                          * our ap.
1312                          */
1313                         if (ic->ic_flags & IEEE80211_F_SCAN) {
1314                                 ieee80211_add_scan(vap, &scan, wh,
1315                                         subtype, rssi, noise, rstamp);
1316                         } else if (contbgscan(vap)) {
1317                                 ieee80211_bg_scan(vap, 0);
1318                         } else if (startbgscan(vap)) {
1319                                 vap->iv_stats.is_scan_bg++;
1320 #if 0
1321                                 /* wakeup if we are sleeing */
1322                                 ieee80211_set_pwrsave(vap, 0);
1323 #endif
1324                                 ieee80211_bg_scan(vap, 0);
1325                         }
1326                         return;
1327                 }
1328                 /*
1329                  * If scanning, just pass information to the scan module.
1330                  */
1331                 if (ic->ic_flags & IEEE80211_F_SCAN) {
1332                         if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) {
1333                                 /*
1334                                  * Actively scanning a channel marked passive;
1335                                  * send a probe request now that we know there
1336                                  * is 802.11 traffic present.
1337                                  *
1338                                  * XXX check if the beacon we recv'd gives
1339                                  * us what we need and suppress the probe req
1340                                  */
1341                                 ieee80211_probe_curchan(vap, 1);
1342                                 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
1343                         }
1344                         ieee80211_add_scan(vap, &scan, wh,
1345                                 subtype, rssi, noise, rstamp);
1346                         return;
1347                 }
1348                 break;
1349         }
1350
1351         case IEEE80211_FC0_SUBTYPE_AUTH: {
1352                 uint16_t algo, seq, status;
1353                 /*
1354                  * auth frame format
1355                  *      [2] algorithm
1356                  *      [2] sequence
1357                  *      [2] status
1358                  *      [tlv*] challenge
1359                  */
1360                 IEEE80211_VERIFY_LENGTH(efrm - frm, 6, return);
1361                 algo   = le16toh(*(uint16_t *)frm);
1362                 seq    = le16toh(*(uint16_t *)(frm + 2));
1363                 status = le16toh(*(uint16_t *)(frm + 4));
1364                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2,
1365                     "recv auth frame with algorithm %d seq %d", algo, seq);
1366
1367                 if (vap->iv_flags & IEEE80211_F_COUNTERM) {
1368                         IEEE80211_DISCARD(vap,
1369                             IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO,
1370                             wh, "auth", "%s", "TKIP countermeasures enabled");
1371                         vap->iv_stats.is_rx_auth_countermeasures++;
1372                         if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
1373                                 ieee80211_send_error(ni, wh->i_addr2,
1374                                         IEEE80211_FC0_SUBTYPE_AUTH,
1375                                         IEEE80211_REASON_MIC_FAILURE);
1376                         }
1377                         return;
1378                 }
1379                 if (algo == IEEE80211_AUTH_ALG_SHARED)
1380                         sta_auth_shared(ni, wh, frm + 6, efrm, rssi,
1381                             noise, rstamp, seq, status);
1382                 else if (algo == IEEE80211_AUTH_ALG_OPEN)
1383                         sta_auth_open(ni, wh, rssi, noise, rstamp,
1384                             seq, status);
1385                 else {
1386                         IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1387                             wh, "auth", "unsupported alg %d", algo);
1388                         vap->iv_stats.is_rx_auth_unsupported++;
1389                         return;
1390                 } 
1391                 break;
1392         }
1393
1394         case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
1395         case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
1396                 uint16_t capinfo, associd;
1397                 uint16_t status;
1398
1399                 if (vap->iv_state != IEEE80211_S_ASSOC) {
1400                         vap->iv_stats.is_rx_mgtdiscard++;
1401                         return;
1402                 }
1403
1404                 /*
1405                  * asresp frame format
1406                  *      [2] capability information
1407                  *      [2] status
1408                  *      [2] association ID
1409                  *      [tlv] supported rates
1410                  *      [tlv] extended supported rates
1411                  *      [tlv] WME
1412                  *      [tlv] HT capabilities
1413                  *      [tlv] HT info
1414                  */
1415                 IEEE80211_VERIFY_LENGTH(efrm - frm, 6, return);
1416                 ni = vap->iv_bss;
1417                 capinfo = le16toh(*(uint16_t *)frm);
1418                 frm += 2;
1419                 status = le16toh(*(uint16_t *)frm);
1420                 frm += 2;
1421                 if (status != 0) {
1422                         IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC,
1423                             wh->i_addr2, "%sassoc failed (reason %d)",
1424                             ISREASSOC(subtype) ?  "re" : "", status);
1425                         vap->iv_stats.is_rx_auth_fail++;        /* XXX */
1426                         return;
1427                 }
1428                 associd = le16toh(*(uint16_t *)frm);
1429                 frm += 2;
1430
1431                 rates = xrates = wme = htcap = htinfo = NULL;
1432                 while (efrm - frm > 1) {
1433                         IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
1434                         switch (*frm) {
1435                         case IEEE80211_ELEMID_RATES:
1436                                 rates = frm;
1437                                 break;
1438                         case IEEE80211_ELEMID_XRATES:
1439                                 xrates = frm;
1440                                 break;
1441                         case IEEE80211_ELEMID_HTCAP:
1442                                 htcap = frm;
1443                                 break;
1444                         case IEEE80211_ELEMID_HTINFO:
1445                                 htinfo = frm;
1446                                 break;
1447                         case IEEE80211_ELEMID_VENDOR:
1448                                 if (iswmeoui(frm))
1449                                         wme = frm;
1450                                 else if (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) {
1451                                         /*
1452                                          * Accept pre-draft HT ie's if the
1453                                          * standard ones have not been seen.
1454                                          */
1455                                         if (ishtcapoui(frm)) {
1456                                                 if (htcap == NULL)
1457                                                         htcap = frm;
1458                                         } else if (ishtinfooui(frm)) {
1459                                                 if (htinfo == NULL)
1460                                                         htcap = frm;
1461                                         }
1462                                 }
1463                                 /* XXX Atheros OUI support */
1464                                 break;
1465                         }
1466                         frm += frm[1] + 2;
1467                 }
1468
1469                 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return);
1470                 if (xrates != NULL)
1471                         IEEE80211_VERIFY_ELEMENT(xrates,
1472                                 IEEE80211_RATE_MAXSIZE - rates[1], return);
1473                 rate = ieee80211_setup_rates(ni, rates, xrates,
1474                                 IEEE80211_F_JOIN |
1475                                 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
1476                                 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1477                 if (rate & IEEE80211_RATE_BASIC) {
1478                         IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC,
1479                             wh->i_addr2,
1480                             "%sassoc failed (rate set mismatch)",
1481                             ISREASSOC(subtype) ?  "re" : "");
1482                         vap->iv_stats.is_rx_assoc_norate++;
1483                         ieee80211_new_state(vap, IEEE80211_S_SCAN,
1484                             IEEE80211_SCAN_FAIL_STATUS);
1485                         return;
1486                 }
1487
1488                 ni->ni_capinfo = capinfo;
1489                 ni->ni_associd = associd;
1490                 if (ni->ni_jointime == 0)
1491                         ni->ni_jointime = time_uptime;
1492                 if (wme != NULL &&
1493                     ieee80211_parse_wmeparams(vap, wme, wh) >= 0) {
1494                         ni->ni_flags |= IEEE80211_NODE_QOS;
1495                         ieee80211_wme_updateparams(vap);
1496                 } else
1497                         ni->ni_flags &= ~IEEE80211_NODE_QOS;
1498                 /*
1499                  * Setup HT state according to the negotiation.
1500                  *
1501                  * NB: shouldn't need to check if HT use is enabled but some
1502                  *     ap's send back HT ie's even when we don't indicate we
1503                  *     are HT capable in our AssocReq.
1504                  */
1505                 if (htcap != NULL && htinfo != NULL &&
1506                     (vap->iv_flags_ext & IEEE80211_FEXT_HT)) {
1507                         ieee80211_ht_node_init(ni);
1508                         ieee80211_ht_updateparams(ni, htcap, htinfo);
1509                         ieee80211_setup_htrates(ni, htcap,
1510                              IEEE80211_F_JOIN | IEEE80211_F_DOBRS);
1511                         ieee80211_setup_basic_htrates(ni, htinfo);
1512                 }
1513                 /*
1514                  * Configure state now that we are associated.
1515                  *
1516                  * XXX may need different/additional driver callbacks?
1517                  */
1518                 if (IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
1519                     (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
1520                         ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
1521                         ic->ic_flags &= ~IEEE80211_F_USEBARKER;
1522                 } else {
1523                         ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
1524                         ic->ic_flags |= IEEE80211_F_USEBARKER;
1525                 }
1526                 ieee80211_set_shortslottime(ic,
1527                         IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
1528                         (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1529                 /*
1530                  * Honor ERP protection.
1531                  *
1532                  * NB: ni_erp should zero for non-11g operation.
1533                  */
1534                 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&
1535                     (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
1536                         ic->ic_flags |= IEEE80211_F_USEPROT;
1537                 else
1538                         ic->ic_flags &= ~IEEE80211_F_USEPROT;
1539                 IEEE80211_NOTE_MAC(vap,
1540                     IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, wh->i_addr2,
1541                     "%sassoc success at aid %d: %s preamble, %s slot time%s%s%s%s%s%s%s%s",
1542                     ISREASSOC(subtype) ? "re" : "",
1543                     IEEE80211_NODE_AID(ni),
1544                     ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
1545                     ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
1546                     ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
1547                     ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",
1548                     ni->ni_flags & IEEE80211_NODE_HT ?
1549                         (ni->ni_chw == 40 ? ", HT40" : ", HT20") : "",
1550                     ni->ni_flags & IEEE80211_NODE_AMPDU ? " (+AMPDU)" : "",
1551                     ni->ni_flags & IEEE80211_NODE_MIMO_RTS ? " (+SMPS-DYN)" :
1552                         ni->ni_flags & IEEE80211_NODE_MIMO_PS ? " (+SMPS)" : "",
1553                     ni->ni_flags & IEEE80211_NODE_RIFS ? " (+RIFS)" : "",
1554                     IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ?
1555                         ", fast-frames" : "",
1556                     IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_TURBOP) ?
1557                         ", turbo" : ""
1558                 );
1559                 ieee80211_new_state(vap, IEEE80211_S_RUN, subtype);
1560                 break;
1561         }
1562
1563         case IEEE80211_FC0_SUBTYPE_DEAUTH: {
1564                 uint16_t reason;
1565
1566                 if (vap->iv_state == IEEE80211_S_SCAN) {
1567                         vap->iv_stats.is_rx_mgtdiscard++;
1568                         return;
1569                 }
1570                 if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) {
1571                         /* NB: can happen when in promiscuous mode */
1572                         vap->iv_stats.is_rx_mgtdiscard++;
1573                         break;
1574                 }
1575
1576                 /*
1577                  * deauth frame format
1578                  *      [2] reason
1579                  */
1580                 IEEE80211_VERIFY_LENGTH(efrm - frm, 2, return);
1581                 reason = le16toh(*(uint16_t *)frm);
1582
1583                 vap->iv_stats.is_rx_deauth++;
1584                 vap->iv_stats.is_rx_deauth_code = reason;
1585                 IEEE80211_NODE_STAT(ni, rx_deauth);
1586
1587                 IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni,
1588                     "recv deauthenticate (reason %d)", reason);
1589                 ieee80211_new_state(vap, IEEE80211_S_AUTH,
1590                     (reason << 8) | IEEE80211_FC0_SUBTYPE_DEAUTH);
1591                 break;
1592         }
1593
1594         case IEEE80211_FC0_SUBTYPE_DISASSOC: {
1595                 uint16_t reason;
1596
1597                 if (vap->iv_state != IEEE80211_S_RUN &&
1598                     vap->iv_state != IEEE80211_S_ASSOC &&
1599                     vap->iv_state != IEEE80211_S_AUTH) {
1600                         vap->iv_stats.is_rx_mgtdiscard++;
1601                         return;
1602                 }
1603                 if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) {
1604                         /* NB: can happen when in promiscuous mode */
1605                         vap->iv_stats.is_rx_mgtdiscard++;
1606                         break;
1607                 }
1608
1609                 /*
1610                  * disassoc frame format
1611                  *      [2] reason
1612                  */
1613                 IEEE80211_VERIFY_LENGTH(efrm - frm, 2, return);
1614                 reason = le16toh(*(uint16_t *)frm);
1615
1616                 vap->iv_stats.is_rx_disassoc++;
1617                 vap->iv_stats.is_rx_disassoc_code = reason;
1618                 IEEE80211_NODE_STAT(ni, rx_disassoc);
1619
1620                 IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
1621                     "recv disassociate (reason %d)", reason);
1622                 ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
1623                 break;
1624         }
1625
1626         case IEEE80211_FC0_SUBTYPE_ACTION:
1627                 if (vap->iv_state == IEEE80211_S_RUN) {
1628                         if (ieee80211_parse_action(ni, m0) == 0)
1629                                 ic->ic_recv_action(ni, frm, efrm);
1630                 } else
1631                         vap->iv_stats.is_rx_mgtdiscard++;
1632                 break;
1633
1634         case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
1635         case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1636         case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
1637                 vap->iv_stats.is_rx_mgtdiscard++;
1638                 return;
1639         default:
1640                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1641                      wh, "mgt", "subtype 0x%x not handled", subtype);
1642                 vap->iv_stats.is_rx_badsubtype++;
1643                 break;
1644         }
1645 #undef ISREASSOC
1646 #undef ISPROBE
1647 }