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

Cache object: 8329608512dada31f76f9d009a709a90


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