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

Cache object: 1eb4c1bbe37fa89a4502111761b7e172


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