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