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