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

Cache object: 0df3b0c1dd9e94cd63e3deae17877024


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