The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_input.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: fb3ea97072b23a4a051b0a38f4fce521


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.