The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_input.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: c1bb0f5ec405cdd00da78e5a3f689238


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