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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 3da8bacaa167c71098cc92f6d5485732


[ 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.