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