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

Cache object: 4a719c19774adf50ec82215ae9a76cbf


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