LCOV - code coverage report
Current view: top level - net80211 - ieee80211_input.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1425 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 40 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ieee80211_input.c,v 1.202 2018/08/07 18:13:14 stsp Exp $      */
       2             : 
       3             : /*-
       4             :  * Copyright (c) 2001 Atsushi Onoe
       5             :  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
       6             :  * Copyright (c) 2007-2009 Damien Bergamini
       7             :  * All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  * 1. Redistributions of source code must retain the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer.
      14             :  * 2. Redistributions in binary form must reproduce the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer in the
      16             :  *    documentation and/or other materials provided with the distribution.
      17             :  * 3. The name of the author may not be used to endorse or promote products
      18             :  *    derived from this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      21             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      22             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      23             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      24             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      25             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      29             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             :  */
      31             : 
      32             : #include "bpfilter.h"
      33             : 
      34             : #include <sys/param.h>
      35             : #include <sys/systm.h>
      36             : #include <sys/mbuf.h>
      37             : #include <sys/malloc.h>
      38             : #include <sys/kernel.h>
      39             : #include <sys/socket.h>
      40             : #include <sys/sockio.h>
      41             : #include <sys/endian.h>
      42             : #include <sys/errno.h>
      43             : #include <sys/sysctl.h>
      44             : #include <sys/task.h>
      45             : 
      46             : #include <net/if.h>
      47             : #include <net/if_dl.h>
      48             : #include <net/if_media.h>
      49             : #include <net/if_llc.h>
      50             : 
      51             : #if NBPFILTER > 0
      52             : #include <net/bpf.h>
      53             : #endif
      54             : 
      55             : #include <netinet/in.h>
      56             : #include <netinet/if_ether.h>
      57             : 
      58             : #include <net80211/ieee80211_var.h>
      59             : #include <net80211/ieee80211_priv.h>
      60             : 
      61             : struct  mbuf *ieee80211_defrag(struct ieee80211com *, struct mbuf *, int);
      62             : void    ieee80211_defrag_timeout(void *);
      63             : void    ieee80211_input_ba(struct ieee80211com *, struct mbuf *,
      64             :             struct ieee80211_node *, int, struct ieee80211_rxinfo *);
      65             : void    ieee80211_input_ba_flush(struct ieee80211com *, struct ieee80211_node *,
      66             :             struct ieee80211_rx_ba *);
      67             : void    ieee80211_input_ba_gap_timeout(void *arg);
      68             : void    ieee80211_ba_move_window(struct ieee80211com *,
      69             :             struct ieee80211_node *, u_int8_t, u_int16_t);
      70             : void    ieee80211_input_ba_seq(struct ieee80211com *,
      71             :             struct ieee80211_node *, uint8_t, uint16_t);
      72             : struct  mbuf *ieee80211_align_mbuf(struct mbuf *);
      73             : void    ieee80211_decap(struct ieee80211com *, struct mbuf *,
      74             :             struct ieee80211_node *, int);
      75             : void    ieee80211_amsdu_decap(struct ieee80211com *, struct mbuf *,
      76             :             struct ieee80211_node *, int);
      77             : void    ieee80211_deliver_data(struct ieee80211com *, struct mbuf *,
      78             :             struct ieee80211_node *, int);
      79             : int     ieee80211_parse_edca_params_body(struct ieee80211com *,
      80             :             const u_int8_t *);
      81             : int     ieee80211_parse_edca_params(struct ieee80211com *, const u_int8_t *);
      82             : int     ieee80211_parse_wmm_params(struct ieee80211com *, const u_int8_t *);
      83             : enum    ieee80211_cipher ieee80211_parse_rsn_cipher(const u_int8_t[]);
      84             : enum    ieee80211_akm ieee80211_parse_rsn_akm(const u_int8_t[]);
      85             : int     ieee80211_parse_rsn_body(struct ieee80211com *, const u_int8_t *,
      86             :             u_int, struct ieee80211_rsnparams *);
      87             : int     ieee80211_save_ie(const u_int8_t *, u_int8_t **);
      88             : void    ieee80211_recv_probe_resp(struct ieee80211com *, struct mbuf *,
      89             :             struct ieee80211_node *, struct ieee80211_rxinfo *, int);
      90             : #ifndef IEEE80211_STA_ONLY
      91             : void    ieee80211_recv_probe_req(struct ieee80211com *, struct mbuf *,
      92             :             struct ieee80211_node *, struct ieee80211_rxinfo *);
      93             : #endif
      94             : void    ieee80211_recv_auth(struct ieee80211com *, struct mbuf *,
      95             :             struct ieee80211_node *, struct ieee80211_rxinfo *);
      96             : #ifndef IEEE80211_STA_ONLY
      97             : void    ieee80211_recv_assoc_req(struct ieee80211com *, struct mbuf *,
      98             :             struct ieee80211_node *, struct ieee80211_rxinfo *, int);
      99             : #endif
     100             : void    ieee80211_recv_assoc_resp(struct ieee80211com *, struct mbuf *,
     101             :             struct ieee80211_node *, int);
     102             : void    ieee80211_recv_deauth(struct ieee80211com *, struct mbuf *,
     103             :             struct ieee80211_node *);
     104             : void    ieee80211_recv_disassoc(struct ieee80211com *, struct mbuf *,
     105             :             struct ieee80211_node *);
     106             : void    ieee80211_recv_addba_req(struct ieee80211com *, struct mbuf *,
     107             :             struct ieee80211_node *);
     108             : void    ieee80211_recv_addba_resp(struct ieee80211com *, struct mbuf *,
     109             :             struct ieee80211_node *);
     110             : void    ieee80211_recv_delba(struct ieee80211com *, struct mbuf *,
     111             :             struct ieee80211_node *);
     112             : void    ieee80211_recv_sa_query_req(struct ieee80211com *, struct mbuf *,
     113             :             struct ieee80211_node *);
     114             : #ifndef IEEE80211_STA_ONLY
     115             : void    ieee80211_recv_sa_query_resp(struct ieee80211com *, struct mbuf *,
     116             :             struct ieee80211_node *);
     117             : #endif
     118             : void    ieee80211_recv_action(struct ieee80211com *, struct mbuf *,
     119             :             struct ieee80211_node *);
     120             : #ifndef IEEE80211_STA_ONLY
     121             : void    ieee80211_recv_pspoll(struct ieee80211com *, struct mbuf *,
     122             :             struct ieee80211_node *);
     123             : #endif
     124             : void    ieee80211_recv_bar(struct ieee80211com *, struct mbuf *,
     125             :             struct ieee80211_node *);
     126             : void    ieee80211_bar_tid(struct ieee80211com *, struct ieee80211_node *,
     127             :             u_int8_t, u_int16_t);
     128             : 
     129             : /*
     130             :  * Retrieve the length in bytes of an 802.11 header.
     131             :  */
     132             : u_int
     133           0 : ieee80211_get_hdrlen(const struct ieee80211_frame *wh)
     134             : {
     135             :         u_int size = sizeof(*wh);
     136             : 
     137             :         /* NB: does not work with control frames */
     138           0 :         KASSERT(ieee80211_has_seq(wh));
     139             : 
     140           0 :         if (ieee80211_has_addr4(wh))
     141           0 :                 size += IEEE80211_ADDR_LEN;     /* i_addr4 */
     142           0 :         if (ieee80211_has_qos(wh))
     143           0 :                 size += sizeof(u_int16_t);      /* i_qos */
     144           0 :         if (ieee80211_has_htc(wh))
     145           0 :                 size += sizeof(u_int32_t);      /* i_ht */
     146           0 :         return size;
     147             : }
     148             : 
     149             : /*
     150             :  * Process a received frame.  The node associated with the sender
     151             :  * should be supplied.  If nothing was found in the node table then
     152             :  * the caller is assumed to supply a reference to ic_bss instead.
     153             :  * The RSSI and a timestamp are also supplied.  The RSSI data is used
     154             :  * during AP scanning to select a AP to associate with; it can have
     155             :  * any units so long as values have consistent units and higher values
     156             :  * mean ``better signal''.  The receive timestamp is currently not used
     157             :  * by the 802.11 layer.
     158             :  */
     159             : void
     160           0 : ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
     161             :     struct ieee80211_rxinfo *rxi)
     162             : {
     163           0 :         struct ieee80211com *ic = (void *)ifp;
     164             :         struct ieee80211_frame *wh;
     165             :         u_int16_t *orxseq, nrxseq, qos;
     166             :         u_int8_t dir, type, subtype, tid;
     167             :         int hdrlen, hasqos;
     168             : 
     169           0 :         KASSERT(ni != NULL);
     170             : 
     171             :         /* in monitor mode, send everything directly to bpf */
     172           0 :         if (ic->ic_opmode == IEEE80211_M_MONITOR)
     173             :                 goto out;
     174             : 
     175             :         /*
     176             :          * Do not process frames without an Address 2 field any further.
     177             :          * Only CTS and ACK control frames do not have this field.
     178             :          */
     179           0 :         if (m->m_len < sizeof(struct ieee80211_frame_min)) {
     180             :                 DPRINTF(("frame too short, len %u\n", m->m_len));
     181           0 :                 ic->ic_stats.is_rx_tooshort++;
     182           0 :                 goto out;
     183             :         }
     184             : 
     185           0 :         wh = mtod(m, struct ieee80211_frame *);
     186           0 :         if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
     187             :             IEEE80211_FC0_VERSION_0) {
     188             :                 DPRINTF(("frame with wrong version: %x\n", wh->i_fc[0]));
     189           0 :                 ic->ic_stats.is_rx_badversion++;
     190           0 :                 goto err;
     191             :         }
     192             : 
     193           0 :         dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
     194           0 :         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
     195           0 :         subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
     196             : 
     197           0 :         if (type != IEEE80211_FC0_TYPE_CTL) {
     198           0 :                 hdrlen = ieee80211_get_hdrlen(wh);
     199           0 :                 if (m->m_len < hdrlen) {
     200             :                         DPRINTF(("frame too short, len %u\n", m->m_len));
     201           0 :                         ic->ic_stats.is_rx_tooshort++;
     202           0 :                         goto err;
     203             :                 }
     204             :         }
     205           0 :         if ((hasqos = ieee80211_has_qos(wh))) {
     206           0 :                 qos = ieee80211_get_qos(wh);
     207           0 :                 tid = qos & IEEE80211_QOS_TID;
     208           0 :         } else {
     209             :                 qos = 0;
     210             :                 tid = 0;
     211             :         }
     212             : 
     213           0 :         if (type == IEEE80211_FC0_TYPE_DATA && hasqos &&
     214           0 :             (subtype & IEEE80211_FC0_SUBTYPE_NODATA) == 0 &&
     215           0 :             !(rxi->rxi_flags & IEEE80211_RXI_AMPDU_DONE)) {
     216           0 :                 int ba_state = ni->ni_rx_ba[tid].ba_state;
     217             : 
     218             :                 /* 
     219             :                  * If Block Ack was explicitly requested, check
     220             :                  * if we have a BA agreement for this RA/TID.
     221             :                  */
     222           0 :                 if ((qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
     223           0 :                     IEEE80211_QOS_ACK_POLICY_BA &&
     224           0 :                     ba_state != IEEE80211_BA_AGREED) {
     225             :                         DPRINTF(("no BA agreement for %s, TID %d\n",
     226             :                             ether_sprintf(ni->ni_macaddr), tid));
     227             :                         /* send a DELBA with reason code UNKNOWN-BA */
     228           0 :                         IEEE80211_SEND_ACTION(ic, ni,
     229             :                             IEEE80211_CATEG_BA, IEEE80211_ACTION_DELBA,
     230             :                             IEEE80211_REASON_SETUP_REQUIRED << 16 | tid);
     231           0 :                         goto err;
     232             :                 }
     233             : 
     234             :                 /* 
     235             :                  * Check if we have an explicit or implicit
     236             :                  * Block Ack Request for a valid BA agreement.
     237             :                  */
     238           0 :                 if (ba_state == IEEE80211_BA_AGREED &&
     239             :                     ((qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
     240           0 :                     IEEE80211_QOS_ACK_POLICY_BA ||
     241           0 :                     (qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
     242             :                     IEEE80211_QOS_ACK_POLICY_NORMAL)) {
     243             :                         /* go through A-MPDU reordering */
     244           0 :                         ieee80211_input_ba(ic, m, ni, tid, rxi);
     245           0 :                         return; /* don't free m! */
     246             :                 }
     247           0 :         }
     248             : 
     249             :         /* duplicate detection (see 9.2.9) */
     250           0 :         if (ieee80211_has_seq(wh) &&
     251           0 :             ic->ic_state != IEEE80211_S_SCAN) {
     252           0 :                 nrxseq = letoh16(*(u_int16_t *)wh->i_seq) >>
     253             :                     IEEE80211_SEQ_SEQ_SHIFT;
     254           0 :                 if (hasqos)
     255           0 :                         orxseq = &ni->ni_qos_rxseqs[tid];
     256             :                 else
     257           0 :                         orxseq = &ni->ni_rxseq;
     258           0 :                 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
     259           0 :                     nrxseq == *orxseq) {
     260             :                         /* duplicate, silently discarded */
     261           0 :                         ic->ic_stats.is_rx_dup++;
     262           0 :                         goto out;
     263             :                 }
     264           0 :                 *orxseq = nrxseq;
     265           0 :         }
     266           0 :         if (ic->ic_state > IEEE80211_S_SCAN) {
     267           0 :                 ni->ni_rssi = rxi->rxi_rssi;
     268           0 :                 ni->ni_rstamp = rxi->rxi_tstamp;
     269           0 :                 ni->ni_inact = 0;
     270             : 
     271           0 :                 if (ic->ic_state == IEEE80211_S_RUN && ic->ic_bgscan_start) {
     272             :                         /* Cancel or start background scan based on RSSI. */
     273           0 :                         if ((*ic->ic_node_checkrssi)(ic, ni))
     274           0 :                                 timeout_del(&ic->ic_bgscan_timeout);
     275           0 :                         else if (!timeout_pending(&ic->ic_bgscan_timeout) &&
     276           0 :                             (ic->ic_flags & IEEE80211_F_BGSCAN) == 0 &&
     277           0 :                             (ic->ic_flags & IEEE80211_F_DESBSSID) == 0)
     278           0 :                                 timeout_add_msec(&ic->ic_bgscan_timeout,
     279           0 :                                     500 * (ic->ic_bgscan_fail + 1));
     280             :                 }
     281             :         }
     282             : 
     283             : #ifndef IEEE80211_STA_ONLY
     284           0 :         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
     285           0 :             (ic->ic_caps & IEEE80211_C_APPMGT) &&
     286           0 :             ni->ni_state == IEEE80211_STA_ASSOC) {
     287           0 :                 if (wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) {
     288           0 :                         if (ni->ni_pwrsave == IEEE80211_PS_AWAKE) {
     289             :                                 /* turn on PS mode */
     290           0 :                                 ni->ni_pwrsave = IEEE80211_PS_DOZE;
     291             :                                 DPRINTF(("PS mode on for %s\n",
     292             :                                     ether_sprintf(wh->i_addr2)));
     293           0 :                         }
     294           0 :                 } else if (ni->ni_pwrsave == IEEE80211_PS_DOZE) {
     295             :                         struct mbuf *m;
     296             : 
     297             :                         /* turn off PS mode */
     298           0 :                         ni->ni_pwrsave = IEEE80211_PS_AWAKE;
     299             :                         DPRINTF(("PS mode off for %s\n",
     300             :                             ether_sprintf(wh->i_addr2)));
     301             : 
     302           0 :                         (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
     303             : 
     304             :                         /* dequeue buffered unicast frames */
     305           0 :                         while ((m = mq_dequeue(&ni->ni_savedq)) != NULL) {
     306           0 :                                 mq_enqueue(&ic->ic_pwrsaveq, m);
     307           0 :                                 if_start(ifp);
     308             :                         }
     309           0 :                 }
     310             :         }
     311             : #endif
     312           0 :         switch (type) {
     313             :         case IEEE80211_FC0_TYPE_DATA:
     314           0 :                 switch (ic->ic_opmode) {
     315             :                 case IEEE80211_M_STA:
     316           0 :                         if (dir != IEEE80211_FC1_DIR_FROMDS) {
     317           0 :                                 ic->ic_stats.is_rx_wrongdir++;
     318           0 :                                 goto out;
     319             :                         }
     320           0 :                         if (ic->ic_state != IEEE80211_S_SCAN &&
     321           0 :                             !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
     322             :                                 /* Source address is not our BSS. */
     323             :                                 DPRINTF(("discard frame from SA %s\n",
     324             :                                     ether_sprintf(wh->i_addr2)));
     325           0 :                                 ic->ic_stats.is_rx_wrongbss++;
     326           0 :                                 goto out;
     327             :                         }
     328           0 :                         if ((ifp->if_flags & IFF_SIMPLEX) &&
     329           0 :                             IEEE80211_IS_MULTICAST(wh->i_addr1) &&
     330           0 :                             IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
     331             :                                 /*
     332             :                                  * In IEEE802.11 network, multicast frame
     333             :                                  * sent from me is broadcasted from AP.
     334             :                                  * It should be silently discarded for
     335             :                                  * SIMPLEX interface.
     336             :                                  */
     337           0 :                                 ic->ic_stats.is_rx_mcastecho++;
     338           0 :                                 goto out;
     339             :                         }
     340             :                         break;
     341             : #ifndef IEEE80211_STA_ONLY
     342             :                 case IEEE80211_M_IBSS:
     343             :                 case IEEE80211_M_AHDEMO:
     344           0 :                         if (dir != IEEE80211_FC1_DIR_NODS) {
     345           0 :                                 ic->ic_stats.is_rx_wrongdir++;
     346           0 :                                 goto out;
     347             :                         }
     348           0 :                         if (ic->ic_state != IEEE80211_S_SCAN &&
     349           0 :                             !IEEE80211_ADDR_EQ(wh->i_addr3,
     350           0 :                                 ic->ic_bss->ni_bssid) &&
     351           0 :                             !IEEE80211_ADDR_EQ(wh->i_addr3,
     352             :                                 etherbroadcastaddr)) {
     353             :                                 /* Destination is not our BSS or broadcast. */
     354             :                                 DPRINTF(("discard data frame to DA %s\n",
     355             :                                     ether_sprintf(wh->i_addr3)));
     356           0 :                                 ic->ic_stats.is_rx_wrongbss++;
     357           0 :                                 goto out;
     358             :                         }
     359             :                         break;
     360             :                 case IEEE80211_M_HOSTAP:
     361           0 :                         if (dir != IEEE80211_FC1_DIR_TODS) {
     362           0 :                                 ic->ic_stats.is_rx_wrongdir++;
     363           0 :                                 goto out;
     364             :                         }
     365           0 :                         if (ic->ic_state != IEEE80211_S_SCAN &&
     366           0 :                             !IEEE80211_ADDR_EQ(wh->i_addr1,
     367           0 :                                 ic->ic_bss->ni_bssid) &&
     368           0 :                             !IEEE80211_ADDR_EQ(wh->i_addr1,
     369             :                                 etherbroadcastaddr)) {
     370             :                                 /* BSS is not us or broadcast. */
     371             :                                 DPRINTF(("discard data frame to BSS %s\n",
     372             :                                     ether_sprintf(wh->i_addr1)));
     373           0 :                                 ic->ic_stats.is_rx_wrongbss++;
     374           0 :                                 goto out;
     375             :                         }
     376             :                         /* check if source STA is associated */
     377           0 :                         if (ni == ic->ic_bss) {
     378             :                                 DPRINTF(("data from unknown src %s\n",
     379             :                                     ether_sprintf(wh->i_addr2)));
     380             :                                 /* NB: caller deals with reference */
     381           0 :                                 ni = ieee80211_find_node(ic, wh->i_addr2);
     382           0 :                                 if (ni == NULL)
     383           0 :                                         ni = ieee80211_dup_bss(ic, wh->i_addr2);
     384           0 :                                 if (ni != NULL) {
     385           0 :                                         IEEE80211_SEND_MGMT(ic, ni,
     386             :                                             IEEE80211_FC0_SUBTYPE_DEAUTH,
     387             :                                             IEEE80211_REASON_NOT_AUTHED);
     388           0 :                                 }
     389           0 :                                 ic->ic_stats.is_rx_notassoc++;
     390           0 :                                 goto err;
     391             :                         }
     392           0 :                         if (ni->ni_state != IEEE80211_STA_ASSOC) {
     393             :                                 DPRINTF(("data from unassoc src %s\n",
     394             :                                     ether_sprintf(wh->i_addr2)));
     395           0 :                                 IEEE80211_SEND_MGMT(ic, ni,
     396             :                                     IEEE80211_FC0_SUBTYPE_DISASSOC,
     397             :                                     IEEE80211_REASON_NOT_ASSOCED);
     398           0 :                                 ic->ic_stats.is_rx_notassoc++;
     399           0 :                                 goto err;
     400             :                         }
     401             :                         break;
     402             : #endif  /* IEEE80211_STA_ONLY */
     403             :                 default:
     404             :                         /* can't get there */
     405             :                         goto out;
     406             :                 }
     407             : 
     408           0 :                 if ((ic->ic_flags & IEEE80211_F_WEPON) ||
     409           0 :                     ((ic->ic_flags & IEEE80211_F_RSNON) &&
     410           0 :                      (ni->ni_flags & IEEE80211_NODE_RXPROT))) {
     411             :                         /* protection is on for Rx */
     412           0 :                         if (!(rxi->rxi_flags & IEEE80211_RXI_HWDEC)) {
     413           0 :                                 if (!(wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
     414             :                                         /* drop unencrypted */
     415           0 :                                         ic->ic_stats.is_rx_unencrypted++;
     416           0 :                                         goto err;
     417             :                                 }
     418             :                                 /* do software decryption */
     419           0 :                                 m = ieee80211_decrypt(ic, m, ni);
     420           0 :                                 if (m == NULL) {
     421           0 :                                         ic->ic_stats.is_rx_wepfail++;
     422           0 :                                         goto err;
     423             :                                 }
     424           0 :                                 wh = mtod(m, struct ieee80211_frame *);
     425           0 :                         }
     426           0 :                 } else if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) ||
     427           0 :                     (rxi->rxi_flags & IEEE80211_RXI_HWDEC)) {
     428             :                         /* frame encrypted but protection off for Rx */
     429           0 :                         ic->ic_stats.is_rx_nowep++;
     430           0 :                         goto out;
     431             :                 }
     432             : 
     433             : #if NBPFILTER > 0
     434             :                 /* copy to listener after decrypt */
     435           0 :                 if (ic->ic_rawbpf)
     436           0 :                         bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);
     437             : #endif
     438             : 
     439           0 :                 if ((ni->ni_flags & IEEE80211_NODE_HT) &&
     440           0 :                     hasqos && (qos & IEEE80211_QOS_AMSDU))
     441           0 :                         ieee80211_amsdu_decap(ic, m, ni, hdrlen);
     442             :                 else
     443           0 :                         ieee80211_decap(ic, m, ni, hdrlen);
     444           0 :                 return;
     445             : 
     446             :         case IEEE80211_FC0_TYPE_MGT:
     447           0 :                 if (dir != IEEE80211_FC1_DIR_NODS) {
     448           0 :                         ic->ic_stats.is_rx_wrongdir++;
     449           0 :                         goto err;
     450             :                 }
     451             : #ifndef IEEE80211_STA_ONLY
     452           0 :                 if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
     453           0 :                         ic->ic_stats.is_rx_ahdemo_mgt++;
     454           0 :                         goto out;
     455             :                 }
     456             : #endif
     457             :                 /* drop frames without interest */
     458           0 :                 if (ic->ic_state == IEEE80211_S_SCAN) {
     459           0 :                         if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
     460           0 :                             subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
     461           0 :                                 ic->ic_stats.is_rx_mgtdiscard++;
     462           0 :                                 goto out;
     463             :                         }
     464             :                 }
     465             : 
     466           0 :                 if (ni->ni_flags & IEEE80211_NODE_RXMGMTPROT) {
     467             :                         /* MMPDU protection is on for Rx */
     468           0 :                         if (subtype == IEEE80211_FC0_SUBTYPE_DISASSOC ||
     469           0 :                             subtype == IEEE80211_FC0_SUBTYPE_DEAUTH ||
     470           0 :                             subtype == IEEE80211_FC0_SUBTYPE_ACTION) {
     471           0 :                                 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
     472           0 :                                     !(wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
     473             :                                         /* unicast mgmt not encrypted */
     474             :                                         goto out;
     475             :                                 }
     476             :                                 /* do software decryption */
     477           0 :                                 m = ieee80211_decrypt(ic, m, ni);
     478           0 :                                 if (m == NULL) {
     479             :                                         /* XXX stats */
     480             :                                         goto out;
     481             :                                 }
     482           0 :                                 wh = mtod(m, struct ieee80211_frame *);
     483           0 :                         }
     484           0 :                 } else if ((ic->ic_flags & IEEE80211_F_RSNON) &&
     485           0 :                     (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
     486             :                         /* encrypted but MMPDU Rx protection off for TA */
     487             :                         goto out;
     488             :                 }
     489             : 
     490             : #if NBPFILTER > 0
     491           0 :                 if (bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN) != 0) {
     492             :                         /*
     493             :                          * Drop mbuf if it was filtered by bpf. Normally,
     494             :                          * this is done in ether_input() but IEEE 802.11
     495             :                          * management frames are a special case.
     496             :                          */
     497           0 :                         m_freem(m);
     498           0 :                         return;
     499             :                 }
     500             : #endif
     501           0 :                 (*ic->ic_recv_mgmt)(ic, m, ni, rxi, subtype);
     502           0 :                 m_freem(m);
     503           0 :                 return;
     504             : 
     505             :         case IEEE80211_FC0_TYPE_CTL:
     506           0 :                 ic->ic_stats.is_rx_ctl++;
     507           0 :                 switch (subtype) {
     508             : #ifndef IEEE80211_STA_ONLY
     509             :                 case IEEE80211_FC0_SUBTYPE_PS_POLL:
     510           0 :                         ieee80211_recv_pspoll(ic, m, ni);
     511           0 :                         break;
     512             : #endif
     513             :                 case IEEE80211_FC0_SUBTYPE_BAR:
     514           0 :                         ieee80211_recv_bar(ic, m, ni);
     515           0 :                         break;
     516             :                 default:
     517             :                         break;
     518             :                 }
     519             :                 goto out;
     520             : 
     521             :         default:
     522             :                 DPRINTF(("bad frame type %x\n", type));
     523             :                 /* should not come here */
     524             :                 break;
     525             :         }
     526             :  err:
     527           0 :         ifp->if_ierrors++;
     528             :  out:
     529           0 :         if (m != NULL) {
     530             : #if NBPFILTER > 0
     531           0 :                 if (ic->ic_rawbpf)
     532           0 :                         bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_IN);
     533             : #endif
     534           0 :                 m_freem(m);
     535           0 :         }
     536           0 : }
     537             : 
     538             : /*
     539             :  * Handle defragmentation (see 9.5 and Annex C).  We support the concurrent
     540             :  * reception of fragments of three fragmented MSDUs or MMPDUs.
     541             :  */
     542             : struct mbuf *
     543           0 : ieee80211_defrag(struct ieee80211com *ic, struct mbuf *m, int hdrlen)
     544             : {
     545             :         const struct ieee80211_frame *owh, *wh;
     546             :         struct ieee80211_defrag *df;
     547             :         u_int16_t rxseq, seq;
     548             :         u_int8_t frag;
     549             :         int i;
     550             : 
     551           0 :         wh = mtod(m, struct ieee80211_frame *);
     552           0 :         rxseq = letoh16(*(const u_int16_t *)wh->i_seq);
     553           0 :         seq = rxseq >> IEEE80211_SEQ_SEQ_SHIFT;
     554           0 :         frag = rxseq & IEEE80211_SEQ_FRAG_MASK;
     555             : 
     556           0 :         if (frag == 0 && !(wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG))
     557           0 :                 return m;       /* not fragmented */
     558             : 
     559           0 :         if (frag == 0) {
     560             :                 /* first fragment, setup entry in the fragment cache */
     561           0 :                 if (++ic->ic_defrag_cur == IEEE80211_DEFRAG_SIZE)
     562           0 :                         ic->ic_defrag_cur = 0;
     563           0 :                 df = &ic->ic_defrag[ic->ic_defrag_cur];
     564           0 :                 m_freem(df->df_m);   /* discard old entry */
     565           0 :                 df->df_seq = seq;
     566           0 :                 df->df_frag = 0;
     567           0 :                 df->df_m = m;
     568             :                 /* start receive MSDU timer of aMaxReceiveLifetime */
     569           0 :                 timeout_add_sec(&df->df_to, 1);
     570           0 :                 return NULL;    /* MSDU or MMPDU not yet complete */
     571             :         }
     572             : 
     573             :         /* find matching entry in the fragment cache */
     574           0 :         for (i = 0; i < IEEE80211_DEFRAG_SIZE; i++) {
     575           0 :                 df = &ic->ic_defrag[i];
     576           0 :                 if (df->df_m == NULL)
     577             :                         continue;
     578           0 :                 if (df->df_seq != seq || df->df_frag + 1 != frag)
     579             :                         continue;
     580           0 :                 owh = mtod(df->df_m, struct ieee80211_frame *);
     581             :                 /* frame type, source and destination must match */
     582           0 :                 if (((wh->i_fc[0] ^ owh->i_fc[0]) & IEEE80211_FC0_TYPE_MASK) ||
     583           0 :                     !IEEE80211_ADDR_EQ(wh->i_addr1, owh->i_addr1) ||
     584           0 :                     !IEEE80211_ADDR_EQ(wh->i_addr2, owh->i_addr2))
     585             :                         continue;
     586             :                 /* matching entry found */
     587             :                 break;
     588             :         }
     589           0 :         if (i == IEEE80211_DEFRAG_SIZE) {
     590             :                 /* no matching entry found, discard fragment */
     591           0 :                 ic->ic_if.if_ierrors++;
     592           0 :                 m_freem(m);
     593           0 :                 return NULL;
     594             :         }
     595             : 
     596           0 :         df->df_frag = frag;
     597             :         /* strip 802.11 header and concatenate fragment */
     598           0 :         m_adj(m, hdrlen);
     599           0 :         m_cat(df->df_m, m);
     600           0 :         df->df_m->m_pkthdr.len += m->m_pkthdr.len;
     601             : 
     602           0 :         if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
     603           0 :                 return NULL;    /* MSDU or MMPDU not yet complete */
     604             : 
     605             :         /* MSDU or MMPDU complete */
     606           0 :         timeout_del(&df->df_to);
     607           0 :         m = df->df_m;
     608           0 :         df->df_m = NULL;
     609           0 :         return m;
     610           0 : }
     611             : 
     612             : /*
     613             :  * Receive MSDU defragmentation timer exceeds aMaxReceiveLifetime.
     614             :  */
     615             : void
     616           0 : ieee80211_defrag_timeout(void *arg)
     617             : {
     618           0 :         struct ieee80211_defrag *df = arg;
     619           0 :         int s = splnet();
     620             : 
     621             :         /* discard all received fragments */
     622           0 :         m_freem(df->df_m);
     623           0 :         df->df_m = NULL;
     624             : 
     625           0 :         splx(s);
     626           0 : }
     627             : 
     628             : /*
     629             :  * Process a received data MPDU related to a specific HT-immediate Block Ack
     630             :  * agreement (see 9.10.7.6).
     631             :  */
     632             : void
     633           0 : ieee80211_input_ba(struct ieee80211com *ic, struct mbuf *m,
     634             :     struct ieee80211_node *ni, int tid, struct ieee80211_rxinfo *rxi)
     635             : {
     636           0 :         struct ifnet *ifp = &ic->ic_if;
     637           0 :         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
     638             :         struct ieee80211_frame *wh;
     639             :         int idx, count;
     640             :         u_int16_t sn;
     641             : 
     642           0 :         wh = mtod(m, struct ieee80211_frame *);
     643           0 :         sn = letoh16(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
     644             : 
     645             :         /* reset Block Ack inactivity timer */
     646           0 :         if (ba->ba_timeout_val != 0)
     647           0 :                 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
     648             : 
     649           0 :         if (SEQ_LT(sn, ba->ba_winstart)) {   /* SN < WinStartB */
     650           0 :                 ic->ic_stats.is_ht_rx_frame_below_ba_winstart++;
     651           0 :                 m_freem(m);     /* discard the MPDU */
     652           0 :                 return;
     653             :         }
     654           0 :         if (SEQ_LT(ba->ba_winend, sn)) {     /* WinEndB < SN */
     655           0 :                 ic->ic_stats.is_ht_rx_frame_above_ba_winend++;
     656           0 :                 count = (sn - ba->ba_winend) & 0xfff;
     657           0 :                 if (count > ba->ba_winsize) {
     658             :                         /* 
     659             :                          * Check whether we're consistently behind the window,
     660             :                          * and let the window move forward if neccessary.
     661             :                          */
     662           0 :                         if (ba->ba_winmiss < IEEE80211_BA_MAX_WINMISS) { 
     663           0 :                                 if (ba->ba_missedsn == ((sn - 1) & 0xfff))
     664           0 :                                         ba->ba_winmiss++;
     665             :                                 else
     666           0 :                                         ba->ba_winmiss = 0;
     667           0 :                                 ba->ba_missedsn = sn;
     668           0 :                                 ifp->if_ierrors++;
     669           0 :                                 m_freem(m);     /* discard the MPDU */
     670           0 :                                 return;
     671             :                         }
     672             : 
     673             :                         /* It appears the window has moved for real. */
     674           0 :                         ic->ic_stats.is_ht_rx_ba_window_jump++;
     675           0 :                         ba->ba_winmiss = 0;
     676           0 :                         ba->ba_missedsn = 0;
     677           0 :                         ieee80211_ba_move_window(ic, ni, tid, sn);
     678           0 :                 } else {
     679           0 :                         ic->ic_stats.is_ht_rx_ba_window_slide++;
     680           0 :                         ieee80211_input_ba_seq(ic, ni, tid,
     681           0 :                             (ba->ba_winstart + count) & 0xfff);
     682           0 :                         ieee80211_input_ba_flush(ic, ni, ba);
     683             :                 }
     684             :         }
     685             :         /* WinStartB <= SN <= WinEndB */
     686             : 
     687           0 :         ba->ba_winmiss = 0;
     688           0 :         ba->ba_missedsn = 0;
     689           0 :         idx = (sn - ba->ba_winstart) & 0xfff;
     690           0 :         idx = (ba->ba_head + idx) % IEEE80211_BA_MAX_WINSZ;
     691             :         /* store the received MPDU in the buffer */
     692           0 :         if (ba->ba_buf[idx].m != NULL) {
     693           0 :                 ifp->if_ierrors++;
     694           0 :                 ic->ic_stats.is_ht_rx_ba_no_buf++;
     695           0 :                 m_freem(m);
     696           0 :                 return;
     697             :         }
     698           0 :         ba->ba_buf[idx].m = m;
     699             :         /* store Rx meta-data too */
     700           0 :         rxi->rxi_flags |= IEEE80211_RXI_AMPDU_DONE;
     701           0 :         ba->ba_buf[idx].rxi = *rxi;
     702             : 
     703           0 :         if (ba->ba_buf[ba->ba_head].m == NULL)
     704           0 :                 timeout_add_msec(&ba->ba_gap_to, IEEE80211_BA_GAP_TIMEOUT);
     705           0 :         else if (timeout_pending(&ba->ba_gap_to))
     706           0 :                 timeout_del(&ba->ba_gap_to);
     707             : 
     708           0 :         ieee80211_input_ba_flush(ic, ni, ba);
     709           0 : }
     710             : 
     711             : /* 
     712             :  * Forward buffered frames with sequence number lower than max_seq.
     713             :  * See 802.11-2012 9.21.7.6.2 b.
     714             :  */
     715             : void
     716           0 : ieee80211_input_ba_seq(struct ieee80211com *ic, struct ieee80211_node *ni,
     717             :     uint8_t tid, uint16_t max_seq)
     718             : {
     719           0 :         struct ifnet *ifp = &ic->ic_if;
     720           0 :         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
     721             :         struct ieee80211_frame *wh;
     722             :         uint16_t seq;
     723             :         int i = 0;
     724             : 
     725           0 :         while (i++ < ba->ba_winsize) {
     726             :                 /* gaps may exist */
     727           0 :                 if (ba->ba_buf[ba->ba_head].m != NULL) {
     728           0 :                         wh = mtod(ba->ba_buf[ba->ba_head].m,
     729             :                             struct ieee80211_frame *);
     730           0 :                         KASSERT(ieee80211_has_seq(wh));
     731           0 :                         seq = letoh16(*(u_int16_t *)wh->i_seq) >>
     732             :                             IEEE80211_SEQ_SEQ_SHIFT;
     733           0 :                         if (!SEQ_LT(seq, max_seq))
     734           0 :                                 return;
     735           0 :                         ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m,
     736           0 :                             ni, &ba->ba_buf[ba->ba_head].rxi);
     737           0 :                         ba->ba_buf[ba->ba_head].m = NULL;
     738           0 :                 } else
     739           0 :                         ic->ic_stats.is_ht_rx_ba_frame_lost++;
     740           0 :                 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
     741             :         }
     742           0 : }
     743             : 
     744             : /* Flush a consecutive sequence of frames from the reorder buffer. */
     745             : void
     746           0 : ieee80211_input_ba_flush(struct ieee80211com *ic, struct ieee80211_node *ni,
     747             :     struct ieee80211_rx_ba *ba)
     748             : 
     749             : {
     750           0 :         struct ifnet *ifp = &ic->ic_if;
     751             : 
     752             :         /* pass reordered MPDUs up to the next MAC process */
     753           0 :         while (ba->ba_buf[ba->ba_head].m != NULL) {
     754           0 :                 ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m, ni,
     755           0 :                     &ba->ba_buf[ba->ba_head].rxi);
     756           0 :                 ba->ba_buf[ba->ba_head].m = NULL;
     757             : 
     758           0 :                 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
     759             :                 /* move window forward */
     760           0 :                 ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
     761             :         }
     762           0 :         ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
     763           0 : }
     764             : 
     765             : /* 
     766             :  * Forcibly move the BA window forward to remove a leading gap which has
     767             :  * been causing frames to linger in the reordering buffer for too long.
     768             :  * A leading gap will occur if a particular A-MPDU subframe never arrives
     769             :  * or if a bug in the sender causes sequence numbers to jump forward by > 1.
     770             :  */
     771             : void
     772           0 : ieee80211_input_ba_gap_timeout(void *arg)
     773             : {
     774           0 :         struct ieee80211_rx_ba *ba = arg;
     775           0 :         struct ieee80211_node *ni = ba->ba_ni;
     776           0 :         struct ieee80211com *ic = ni->ni_ic;
     777             :         int s, skipped;
     778             : 
     779           0 :         ic->ic_stats.is_ht_rx_ba_window_gap_timeout++;
     780             : 
     781           0 :         s = splnet();
     782             : 
     783             :         skipped = 0;
     784           0 :         while (skipped < ba->ba_winsize && ba->ba_buf[ba->ba_head].m == NULL) {
     785             :                 /* move window forward */
     786           0 :                 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
     787           0 :                 ba->ba_winstart = (ba->ba_winstart + 1) & 0xfff;
     788           0 :                 skipped++;
     789           0 :                 ic->ic_stats.is_ht_rx_ba_frame_lost++;
     790             :         }
     791           0 :         if (skipped > 0)
     792           0 :                 ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
     793             : 
     794           0 :         ieee80211_input_ba_flush(ic, ni, ba);
     795             : 
     796           0 :         splx(s);        
     797           0 : }
     798             : 
     799             : 
     800             : /*
     801             :  * Change the value of WinStartB (move window forward) upon reception of a
     802             :  * BlockAckReq frame or an ADDBA Request (PBAC).
     803             :  */
     804             : void
     805           0 : ieee80211_ba_move_window(struct ieee80211com *ic, struct ieee80211_node *ni,
     806             :     u_int8_t tid, u_int16_t ssn)
     807             : {
     808           0 :         struct ifnet *ifp = &ic->ic_if;
     809           0 :         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
     810             :         int count;
     811             : 
     812             :         /* assert(WinStartB <= SSN) */
     813             : 
     814           0 :         count = (ssn - ba->ba_winstart) & 0xfff;
     815           0 :         if (count > ba->ba_winsize)       /* no overlap */
     816           0 :                 count = ba->ba_winsize;
     817           0 :         while (count-- > 0) {
     818             :                 /* gaps may exist */
     819           0 :                 if (ba->ba_buf[ba->ba_head].m != NULL) {
     820           0 :                         ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m, ni,
     821           0 :                             &ba->ba_buf[ba->ba_head].rxi);
     822           0 :                         ba->ba_buf[ba->ba_head].m = NULL;
     823           0 :                 } else
     824           0 :                         ic->ic_stats.is_ht_rx_ba_frame_lost++;
     825           0 :                 ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
     826             :         }
     827             :         /* move window forward */
     828           0 :         ba->ba_winstart = ssn;
     829             : 
     830           0 :         ieee80211_input_ba_flush(ic, ni, ba);
     831           0 : }
     832             : 
     833             : void
     834           0 : ieee80211_deliver_data(struct ieee80211com *ic, struct mbuf *m,
     835             :     struct ieee80211_node *ni, int mcast)
     836             : {
     837           0 :         struct ifnet *ifp = &ic->ic_if;
     838             :         struct ether_header *eh;
     839             :         struct mbuf *m1;
     840             : 
     841           0 :         eh = mtod(m, struct ether_header *);
     842             : 
     843           0 :         if ((ic->ic_flags & IEEE80211_F_RSNON) && !ni->ni_port_valid &&
     844           0 :             eh->ether_type != htons(ETHERTYPE_PAE)) {
     845             :                 DPRINTF(("port not valid: %s\n",
     846             :                     ether_sprintf(eh->ether_dhost)));
     847           0 :                 ic->ic_stats.is_rx_unauth++;
     848           0 :                 m_freem(m);
     849           0 :                 return;
     850             :         }
     851             : 
     852             :         /*
     853             :          * Perform as a bridge within the AP.  Notice that we do not
     854             :          * bridge EAPOL frames as suggested in C.1.1 of IEEE Std 802.1X.
     855             :          * And we do not forward unicast frames received on a multicast address.
     856             :          */
     857             :         m1 = NULL;
     858             : #ifndef IEEE80211_STA_ONLY
     859           0 :         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
     860           0 :             !(ic->ic_flags & IEEE80211_F_NOBRIDGE) &&
     861           0 :             eh->ether_type != htons(ETHERTYPE_PAE)) {
     862             :                 struct ieee80211_node *ni1;
     863             : 
     864           0 :                 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
     865           0 :                         m1 = m_dup_pkt(m, ETHER_ALIGN, M_DONTWAIT);
     866           0 :                         if (m1 == NULL)
     867           0 :                                 ifp->if_oerrors++;
     868             :                         else
     869           0 :                                 m1->m_flags |= M_MCAST;
     870           0 :                 } else if (!mcast) {
     871           0 :                         ni1 = ieee80211_find_node(ic, eh->ether_dhost);
     872           0 :                         if (ni1 != NULL &&
     873           0 :                             ni1->ni_state == IEEE80211_STA_ASSOC) {
     874             :                                 m1 = m;
     875             :                                 m = NULL;
     876           0 :                         }
     877             :                 }
     878           0 :                 if (m1 != NULL) {
     879           0 :                         if (if_enqueue(ifp, m1))
     880           0 :                                  ifp->if_oerrors++;
     881             :                 }
     882           0 :         }
     883             : #endif
     884           0 :         if (m != NULL) {
     885           0 :                 if ((ic->ic_flags & IEEE80211_F_RSNON) &&
     886           0 :                     eh->ether_type == htons(ETHERTYPE_PAE)) {
     887           0 :                         ifp->if_ipackets++;
     888             : #if NBPFILTER > 0
     889             :                         /*
     890             :                          * If we forward frame into transmitter of the AP,
     891             :                          * we don't need to duplicate for DLT_EN10MB.
     892             :                          */
     893           0 :                         if (ifp->if_bpf && m1 == NULL)
     894           0 :                                 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
     895             : #endif
     896           0 :                         ieee80211_eapol_key_input(ic, m, ni);
     897           0 :                 } else {
     898           0 :                         struct mbuf_list ml = MBUF_LIST_INITIALIZER();
     899           0 :                         ml_enqueue(&ml, m);
     900           0 :                         if_input(ifp, &ml);
     901           0 :                 }
     902             :         }
     903           0 : }
     904             : 
     905             : void
     906           0 : ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
     907             :     struct ieee80211_node *ni, int hdrlen)
     908             : {
     909           0 :         struct ether_header eh;
     910             :         struct ieee80211_frame *wh;
     911             :         struct llc *llc;
     912             :         int mcast;
     913             : 
     914           0 :         if (m->m_len < hdrlen + LLC_SNAPFRAMELEN &&
     915           0 :             (m = m_pullup(m, hdrlen + LLC_SNAPFRAMELEN)) == NULL) {
     916           0 :                 ic->ic_stats.is_rx_decap++;
     917           0 :                 return;
     918             :         }
     919           0 :         wh = mtod(m, struct ieee80211_frame *);
     920           0 :         mcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
     921           0 :         switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
     922             :         case IEEE80211_FC1_DIR_NODS:
     923           0 :                 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1);
     924           0 :                 IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2);
     925           0 :                 break;
     926             :         case IEEE80211_FC1_DIR_TODS:
     927           0 :                 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3);
     928           0 :                 IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2);
     929           0 :                 break;
     930             :         case IEEE80211_FC1_DIR_FROMDS:
     931           0 :                 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1);
     932           0 :                 IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr3);
     933           0 :                 break;
     934             :         case IEEE80211_FC1_DIR_DSTODS:
     935           0 :                 IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3);
     936           0 :                 IEEE80211_ADDR_COPY(eh.ether_shost,
     937             :                     ((struct ieee80211_frame_addr4 *)wh)->i_addr4);
     938           0 :                 break;
     939             :         }
     940           0 :         llc = (struct llc *)((caddr_t)wh + hdrlen);
     941           0 :         if (llc->llc_dsap == LLC_SNAP_LSAP &&
     942           0 :             llc->llc_ssap == LLC_SNAP_LSAP &&
     943           0 :             llc->llc_control == LLC_UI &&
     944           0 :             llc->llc_snap.org_code[0] == 0 &&
     945           0 :             llc->llc_snap.org_code[1] == 0 &&
     946           0 :             llc->llc_snap.org_code[2] == 0) {
     947           0 :                 eh.ether_type = llc->llc_snap.ether_type;
     948           0 :                 m_adj(m, hdrlen + LLC_SNAPFRAMELEN - ETHER_HDR_LEN);
     949           0 :         } else {
     950           0 :                 eh.ether_type = htons(m->m_pkthdr.len - hdrlen);
     951           0 :                 m_adj(m, hdrlen - ETHER_HDR_LEN);
     952             :         }
     953           0 :         memcpy(mtod(m, caddr_t), &eh, ETHER_HDR_LEN);
     954             :         if (!ALIGNED_POINTER(mtod(m, caddr_t) + ETHER_HDR_LEN, u_int32_t)) {
     955             :                 struct mbuf *m0 = m;
     956             :                 m = m_dup_pkt(m0, ETHER_ALIGN, M_NOWAIT);
     957             :                 m_freem(m0);
     958             :                 if (m == NULL) {
     959             :                         ic->ic_stats.is_rx_decap++;
     960             :                         return;
     961             :                 }
     962             :         }
     963           0 :         ieee80211_deliver_data(ic, m, ni, mcast);
     964           0 : }
     965             : 
     966             : /*
     967             :  * Decapsulate an Aggregate MSDU (see 7.2.2.2).
     968             :  */
     969             : void
     970           0 : ieee80211_amsdu_decap(struct ieee80211com *ic, struct mbuf *m,
     971             :     struct ieee80211_node *ni, int hdrlen)
     972             : {
     973             :         struct mbuf *n;
     974             :         struct ether_header *eh;
     975             :         struct llc *llc;
     976             :         int len, pad, mcast;
     977             :         struct ieee80211_frame *wh;
     978             : 
     979           0 :         wh = mtod(m, struct ieee80211_frame *);
     980           0 :         mcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
     981             : 
     982             :         /* strip 802.11 header */
     983           0 :         m_adj(m, hdrlen);
     984             : 
     985           0 :         for (;;) {
     986             :                 /* process an A-MSDU subframe */
     987           0 :                 if (m->m_len < ETHER_HDR_LEN + LLC_SNAPFRAMELEN) {
     988           0 :                         m = m_pullup(m, ETHER_HDR_LEN + LLC_SNAPFRAMELEN);
     989           0 :                         if (m == NULL) {
     990           0 :                                 ic->ic_stats.is_rx_decap++;
     991           0 :                                 break;
     992             :                         }
     993             :                 }
     994           0 :                 eh = mtod(m, struct ether_header *);
     995             :                 /* examine 802.3 header */
     996           0 :                 len = ntohs(eh->ether_type);
     997           0 :                 if (len < LLC_SNAPFRAMELEN) {
     998             :                         DPRINTF(("A-MSDU subframe too short (%d)\n", len));
     999             :                         /* stop processing A-MSDU subframes */
    1000           0 :                         ic->ic_stats.is_rx_decap++;
    1001           0 :                         m_freem(m);
    1002           0 :                         break;
    1003             :                 }
    1004           0 :                 llc = (struct llc *)&eh[1];
    1005             :                 /* examine 802.2 LLC header */
    1006           0 :                 if (llc->llc_dsap == LLC_SNAP_LSAP &&
    1007           0 :                     llc->llc_ssap == LLC_SNAP_LSAP &&
    1008           0 :                     llc->llc_control == LLC_UI &&
    1009           0 :                     llc->llc_snap.org_code[0] == 0 &&
    1010           0 :                     llc->llc_snap.org_code[1] == 0 &&
    1011           0 :                     llc->llc_snap.org_code[2] == 0) {
    1012             :                         /* convert to Ethernet II header */
    1013           0 :                         eh->ether_type = llc->llc_snap.ether_type;
    1014             :                         /* strip LLC+SNAP headers */
    1015           0 :                         memmove((u_int8_t *)eh + LLC_SNAPFRAMELEN, eh,
    1016             :                             ETHER_HDR_LEN);
    1017           0 :                         m_adj(m, LLC_SNAPFRAMELEN);
    1018           0 :                         len -= LLC_SNAPFRAMELEN;
    1019           0 :                 }
    1020           0 :                 len += ETHER_HDR_LEN;
    1021           0 :                 if (len > m->m_pkthdr.len) {
    1022             :                         /* stop processing A-MSDU subframes */
    1023             :                         DPRINTF(("A-MSDU subframe too long (%d)\n", len));
    1024           0 :                         ic->ic_stats.is_rx_decap++;
    1025           0 :                         m_freem(m);
    1026           0 :                         break;
    1027             :                 }
    1028             : 
    1029             :                 /* "detach" our A-MSDU subframe from the others */
    1030           0 :                 n = m_split(m, len, M_NOWAIT);
    1031           0 :                 if (n == NULL) {
    1032             :                         /* stop processing A-MSDU subframes */
    1033           0 :                         ic->ic_stats.is_rx_decap++;
    1034           0 :                         m_freem(m);
    1035           0 :                         break;
    1036             :                 }
    1037           0 :                 ieee80211_deliver_data(ic, m, ni, mcast);
    1038             : 
    1039           0 :                 if (n->m_pkthdr.len == 0) {
    1040           0 :                         m_freem(n);
    1041           0 :                         break;
    1042             :                 }
    1043             :                 m = n;
    1044             :                 /* remove padding */
    1045           0 :                 pad = ((len + 3) & ~3) - len;
    1046           0 :                 m_adj(m, pad);
    1047             :         }
    1048           0 : }
    1049             : 
    1050             : /*
    1051             :  * Parse an EDCA Parameter Set element (see 7.3.2.27).
    1052             :  */
    1053             : int
    1054           0 : ieee80211_parse_edca_params_body(struct ieee80211com *ic, const u_int8_t *frm)
    1055             : {
    1056             :         u_int updtcount;
    1057             :         int aci;
    1058             : 
    1059             :         /*
    1060             :          * Check if EDCA parameters have changed XXX if we miss more than
    1061             :          * 15 consecutive beacons, we might not detect changes to EDCA
    1062             :          * parameters due to wraparound of the 4-bit Update Count field.
    1063             :          */
    1064           0 :         updtcount = frm[0] & 0xf;
    1065           0 :         if (updtcount == ic->ic_edca_updtcount)
    1066           0 :                 return 0;       /* no changes to EDCA parameters, ignore */
    1067           0 :         ic->ic_edca_updtcount = updtcount;
    1068             : 
    1069           0 :         frm += 2;       /* skip QoS Info & Reserved fields */
    1070             : 
    1071             :         /* parse AC Parameter Records */
    1072           0 :         for (aci = 0; aci < EDCA_NUM_AC; aci++) {
    1073           0 :                 struct ieee80211_edca_ac_params *ac = &ic->ic_edca_ac[aci];
    1074             : 
    1075           0 :                 ac->ac_acm       = (frm[0] >> 4) & 0x1;
    1076           0 :                 ac->ac_aifsn     = frm[0] & 0xf;
    1077           0 :                 ac->ac_ecwmin    = frm[1] & 0xf;
    1078           0 :                 ac->ac_ecwmax    = frm[1] >> 4;
    1079           0 :                 ac->ac_txoplimit = LE_READ_2(frm + 2);
    1080           0 :                 frm += 4;
    1081             :         }
    1082             :         /* give drivers a chance to update their settings */
    1083           0 :         if ((ic->ic_flags & IEEE80211_F_QOS) && ic->ic_updateedca != NULL)
    1084           0 :                 (*ic->ic_updateedca)(ic);
    1085             : 
    1086           0 :         return 0;
    1087           0 : }
    1088             : 
    1089             : int
    1090           0 : ieee80211_parse_edca_params(struct ieee80211com *ic, const u_int8_t *frm)
    1091             : {
    1092           0 :         if (frm[1] < 18) {
    1093           0 :                 ic->ic_stats.is_rx_elem_toosmall++;
    1094           0 :                 return IEEE80211_REASON_IE_INVALID;
    1095             :         }
    1096           0 :         return ieee80211_parse_edca_params_body(ic, frm + 2);
    1097           0 : }
    1098             : 
    1099             : int
    1100           0 : ieee80211_parse_wmm_params(struct ieee80211com *ic, const u_int8_t *frm)
    1101             : {
    1102           0 :         if (frm[1] < 24) {
    1103           0 :                 ic->ic_stats.is_rx_elem_toosmall++;
    1104           0 :                 return IEEE80211_REASON_IE_INVALID;
    1105             :         }
    1106           0 :         return ieee80211_parse_edca_params_body(ic, frm + 8);
    1107           0 : }
    1108             : 
    1109             : enum ieee80211_cipher
    1110           0 : ieee80211_parse_rsn_cipher(const u_int8_t selector[4])
    1111             : {
    1112           0 :         if (memcmp(selector, MICROSOFT_OUI, 3) == 0) {  /* WPA */
    1113           0 :                 switch (selector[3]) {
    1114             :                 case 0: /* use group data cipher suite */
    1115           0 :                         return IEEE80211_CIPHER_USEGROUP;
    1116             :                 case 1: /* WEP-40 */
    1117           0 :                         return IEEE80211_CIPHER_WEP40;
    1118             :                 case 2: /* TKIP */
    1119           0 :                         return IEEE80211_CIPHER_TKIP;
    1120             :                 case 4: /* CCMP (RSNA default) */
    1121           0 :                         return IEEE80211_CIPHER_CCMP;
    1122             :                 case 5: /* WEP-104 */
    1123           0 :                         return IEEE80211_CIPHER_WEP104;
    1124             :                 }
    1125           0 :         } else if (memcmp(selector, IEEE80211_OUI, 3) == 0) {   /* RSN */
    1126             :                 /* see 802.11-2012 Table 8-99 */
    1127           0 :                 switch (selector[3]) {
    1128             :                 case 0: /* use group data cipher suite */
    1129           0 :                         return IEEE80211_CIPHER_USEGROUP;
    1130             :                 case 1: /* WEP-40 */
    1131           0 :                         return IEEE80211_CIPHER_WEP40;
    1132             :                 case 2: /* TKIP */
    1133           0 :                         return IEEE80211_CIPHER_TKIP;
    1134             :                 case 4: /* CCMP (RSNA default) */
    1135           0 :                         return IEEE80211_CIPHER_CCMP;
    1136             :                 case 5: /* WEP-104 */
    1137           0 :                         return IEEE80211_CIPHER_WEP104;
    1138             :                 case 6: /* BIP */
    1139           0 :                         return IEEE80211_CIPHER_BIP;
    1140             :                 }
    1141             :         }
    1142           0 :         return IEEE80211_CIPHER_NONE;   /* ignore unknown ciphers */
    1143           0 : }
    1144             : 
    1145             : enum ieee80211_akm
    1146           0 : ieee80211_parse_rsn_akm(const u_int8_t selector[4])
    1147             : {
    1148           0 :         if (memcmp(selector, MICROSOFT_OUI, 3) == 0) {  /* WPA */
    1149           0 :                 switch (selector[3]) {
    1150             :                 case 1: /* IEEE 802.1X (RSNA default) */
    1151           0 :                         return IEEE80211_AKM_8021X;
    1152             :                 case 2: /* PSK */
    1153           0 :                         return IEEE80211_AKM_PSK;
    1154             :                 }
    1155           0 :         } else if (memcmp(selector, IEEE80211_OUI, 3) == 0) {   /* RSN */
    1156             :                 /* from IEEE Std 802.11i-2004 - Table 20dc */
    1157           0 :                 switch (selector[3]) {
    1158             :                 case 1: /* IEEE 802.1X (RSNA default) */
    1159           0 :                         return IEEE80211_AKM_8021X;
    1160             :                 case 2: /* PSK */
    1161           0 :                         return IEEE80211_AKM_PSK;
    1162             :                 case 5: /* IEEE 802.1X with SHA256 KDF */
    1163           0 :                         return IEEE80211_AKM_SHA256_8021X;
    1164             :                 case 6: /* PSK with SHA256 KDF */
    1165           0 :                         return IEEE80211_AKM_SHA256_PSK;
    1166             :                 }
    1167             :         }
    1168           0 :         return IEEE80211_AKM_NONE;      /* ignore unknown AKMs */
    1169           0 : }
    1170             : 
    1171             : /*
    1172             :  * Parse an RSN element (see 802.11-2012 8.4.2.27)
    1173             :  */
    1174             : int
    1175           0 : ieee80211_parse_rsn_body(struct ieee80211com *ic, const u_int8_t *frm,
    1176             :     u_int len, struct ieee80211_rsnparams *rsn)
    1177             : {
    1178             :         const u_int8_t *efrm;
    1179             :         u_int16_t m, n, s;
    1180             : 
    1181           0 :         efrm = frm + len;
    1182             : 
    1183             :         /* check Version field */
    1184           0 :         if (LE_READ_2(frm) != 1)
    1185           0 :                 return IEEE80211_STATUS_RSN_IE_VER_UNSUP;
    1186           0 :         frm += 2;
    1187             : 
    1188             :         /* all fields after the Version field are optional */
    1189             : 
    1190             :         /* if Cipher Suite missing, default to CCMP */
    1191           0 :         rsn->rsn_groupcipher = IEEE80211_CIPHER_CCMP;
    1192           0 :         rsn->rsn_nciphers = 1;
    1193           0 :         rsn->rsn_ciphers = IEEE80211_CIPHER_CCMP;
    1194             :         /* if Group Management Cipher Suite missing, defaut to BIP */
    1195           0 :         rsn->rsn_groupmgmtcipher = IEEE80211_CIPHER_BIP;
    1196             :         /* if AKM Suite missing, default to 802.1X */
    1197           0 :         rsn->rsn_nakms = 1;
    1198           0 :         rsn->rsn_akms = IEEE80211_AKM_8021X;
    1199             :         /* if RSN capabilities missing, default to 0 */
    1200           0 :         rsn->rsn_caps = 0;
    1201           0 :         rsn->rsn_npmkids = 0;
    1202             : 
    1203             :         /* read Group Data Cipher Suite field */
    1204           0 :         if (frm + 4 > efrm)
    1205           0 :                 return 0;
    1206           0 :         rsn->rsn_groupcipher = ieee80211_parse_rsn_cipher(frm);
    1207           0 :         if (rsn->rsn_groupcipher == IEEE80211_CIPHER_NONE ||
    1208           0 :             rsn->rsn_groupcipher == IEEE80211_CIPHER_USEGROUP ||
    1209           0 :             rsn->rsn_groupcipher == IEEE80211_CIPHER_BIP)
    1210           0 :                 return IEEE80211_STATUS_BAD_GROUP_CIPHER;
    1211             :         frm += 4;
    1212             : 
    1213             :         /* read Pairwise Cipher Suite Count field */
    1214           0 :         if (frm + 2 > efrm)
    1215           0 :                 return 0;
    1216           0 :         m = rsn->rsn_nciphers = LE_READ_2(frm);
    1217             :         frm += 2;
    1218             : 
    1219             :         /* read Pairwise Cipher Suite List */
    1220           0 :         if (frm + m * 4 > efrm)
    1221           0 :                 return IEEE80211_STATUS_IE_INVALID;
    1222           0 :         rsn->rsn_ciphers = IEEE80211_CIPHER_NONE;
    1223           0 :         while (m-- > 0) {
    1224           0 :                 rsn->rsn_ciphers |= ieee80211_parse_rsn_cipher(frm);
    1225           0 :                 frm += 4;
    1226             :         }
    1227           0 :         if (rsn->rsn_ciphers & IEEE80211_CIPHER_USEGROUP) {
    1228           0 :                 if (rsn->rsn_ciphers != IEEE80211_CIPHER_USEGROUP)
    1229           0 :                         return IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
    1230           0 :                 if (rsn->rsn_groupcipher == IEEE80211_CIPHER_CCMP)
    1231           0 :                         return IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
    1232             :         }
    1233             : 
    1234             :         /* read AKM Suite List Count field */
    1235           0 :         if (frm + 2 > efrm)
    1236           0 :                 return 0;
    1237           0 :         n = rsn->rsn_nakms = LE_READ_2(frm);
    1238             :         frm += 2;
    1239             : 
    1240             :         /* read AKM Suite List */
    1241           0 :         if (frm + n * 4 > efrm)
    1242           0 :                 return IEEE80211_STATUS_IE_INVALID;
    1243           0 :         rsn->rsn_akms = IEEE80211_AKM_NONE;
    1244           0 :         while (n-- > 0) {
    1245           0 :                 rsn->rsn_akms |= ieee80211_parse_rsn_akm(frm);
    1246           0 :                 frm += 4;
    1247             :         }
    1248             : 
    1249             :         /* read RSN Capabilities field */
    1250           0 :         if (frm + 2 > efrm)
    1251           0 :                 return 0;
    1252           0 :         rsn->rsn_caps = LE_READ_2(frm);
    1253             :         frm += 2;
    1254             : 
    1255             :         /* read PMKID Count field */
    1256           0 :         if (frm + 2 > efrm)
    1257           0 :                 return 0;
    1258           0 :         s = rsn->rsn_npmkids = LE_READ_2(frm);
    1259             :         frm += 2;
    1260             : 
    1261             :         /* read PMKID List */
    1262           0 :         if (frm + s * IEEE80211_PMKID_LEN > efrm)
    1263           0 :                 return IEEE80211_STATUS_IE_INVALID;
    1264           0 :         if (s != 0) {
    1265           0 :                 rsn->rsn_pmkids = frm;
    1266             :                 frm += s * IEEE80211_PMKID_LEN;
    1267           0 :         }
    1268             : 
    1269             :         /* read Group Management Cipher Suite field */
    1270           0 :         if (frm + 4 > efrm)
    1271           0 :                 return 0;
    1272           0 :         rsn->rsn_groupmgmtcipher = ieee80211_parse_rsn_cipher(frm);
    1273           0 :         if (rsn->rsn_groupmgmtcipher != IEEE80211_CIPHER_BIP)
    1274           0 :                 return IEEE80211_STATUS_BAD_GROUP_CIPHER;
    1275             : 
    1276           0 :         return IEEE80211_STATUS_SUCCESS;
    1277           0 : }
    1278             : 
    1279             : int
    1280           0 : ieee80211_parse_rsn(struct ieee80211com *ic, const u_int8_t *frm,
    1281             :     struct ieee80211_rsnparams *rsn)
    1282             : {
    1283           0 :         if (frm[1] < 2) {
    1284           0 :                 ic->ic_stats.is_rx_elem_toosmall++;
    1285           0 :                 return IEEE80211_STATUS_IE_INVALID;
    1286             :         }
    1287           0 :         return ieee80211_parse_rsn_body(ic, frm + 2, frm[1], rsn);
    1288           0 : }
    1289             : 
    1290             : int
    1291           0 : ieee80211_parse_wpa(struct ieee80211com *ic, const u_int8_t *frm,
    1292             :     struct ieee80211_rsnparams *rsn)
    1293             : {
    1294           0 :         if (frm[1] < 6) {
    1295           0 :                 ic->ic_stats.is_rx_elem_toosmall++;
    1296           0 :                 return IEEE80211_STATUS_IE_INVALID;
    1297             :         }
    1298           0 :         return ieee80211_parse_rsn_body(ic, frm + 6, frm[1] - 4, rsn);
    1299           0 : }
    1300             : 
    1301             : /*
    1302             :  * Create (or update) a copy of an information element.
    1303             :  */
    1304             : int
    1305           0 : ieee80211_save_ie(const u_int8_t *frm, u_int8_t **ie)
    1306             : {
    1307           0 :         int olen = *ie ? 2 + (*ie)[1] : 0;
    1308           0 :         int len = 2 + frm[1];
    1309             : 
    1310           0 :         if (*ie == NULL || olen != len) {
    1311           0 :                 if (*ie != NULL)
    1312           0 :                         free(*ie, M_DEVBUF, olen);
    1313           0 :                 *ie = malloc(len, M_DEVBUF, M_NOWAIT);
    1314           0 :                 if (*ie == NULL)
    1315           0 :                         return ENOMEM;
    1316             :         }
    1317           0 :         memcpy(*ie, frm, len);
    1318           0 :         return 0;
    1319           0 : }
    1320             : 
    1321             : /*-
    1322             :  * Beacon/Probe response frame format:
    1323             :  * [8]   Timestamp
    1324             :  * [2]   Beacon interval
    1325             :  * [2]   Capability
    1326             :  * [tlv] Service Set Identifier (SSID)
    1327             :  * [tlv] Supported rates
    1328             :  * [tlv] DS Parameter Set (802.11g)
    1329             :  * [tlv] ERP Information (802.11g)
    1330             :  * [tlv] Extended Supported Rates (802.11g)
    1331             :  * [tlv] RSN (802.11i)
    1332             :  * [tlv] EDCA Parameter Set (802.11e)
    1333             :  * [tlv] QoS Capability (Beacon only, 802.11e)
    1334             :  * [tlv] HT Capabilities (802.11n)
    1335             :  * [tlv] HT Operation (802.11n)
    1336             :  */
    1337             : void
    1338           0 : ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
    1339             :     struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int isprobe)
    1340             : {
    1341             :         const struct ieee80211_frame *wh;
    1342             :         const u_int8_t *frm, *efrm;
    1343             :         const u_int8_t *tstamp, *ssid, *rates, *xrates, *edcaie, *wmmie;
    1344             :         const u_int8_t *rsnie, *wpaie, *htcaps, *htop;
    1345             :         u_int16_t capinfo, bintval;
    1346             :         u_int8_t chan, bchan, erp, dtim_count, dtim_period;
    1347             :         int is_new;
    1348             : 
    1349             :         /*
    1350             :          * We process beacon/probe response frames for:
    1351             :          *    o station mode: to collect state
    1352             :          *      updates such as 802.11g slot time and for passive
    1353             :          *      scanning of APs
    1354             :          *    o adhoc mode: to discover neighbors
    1355             :          *    o hostap mode: for passive scanning of neighbor APs
    1356             :          *    o when scanning
    1357             :          * In other words, in all modes other than monitor (which
    1358             :          * does not process incoming frames) and adhoc-demo (which
    1359             :          * does not use management frames at all).
    1360             :          */
    1361             : #ifdef DIAGNOSTIC
    1362           0 :         if (ic->ic_opmode != IEEE80211_M_STA &&
    1363             : #ifndef IEEE80211_STA_ONLY
    1364           0 :             ic->ic_opmode != IEEE80211_M_IBSS &&
    1365           0 :             ic->ic_opmode != IEEE80211_M_HOSTAP &&
    1366             : #endif
    1367           0 :             ic->ic_state != IEEE80211_S_SCAN) {
    1368           0 :                 panic("%s: impossible operating mode", __func__);
    1369             :         }
    1370             : #endif
    1371             :         /* make sure all mandatory fixed fields are present */
    1372           0 :         if (m->m_len < sizeof(*wh) + 12) {
    1373             :                 DPRINTF(("frame too short\n"));
    1374           0 :                 return;
    1375             :         }
    1376           0 :         wh = mtod(m, struct ieee80211_frame *);
    1377           0 :         frm = (const u_int8_t *)&wh[1];
    1378           0 :         efrm = mtod(m, u_int8_t *) + m->m_len;
    1379             : 
    1380           0 :         tstamp  = frm; frm += 8;
    1381           0 :         bintval = LE_READ_2(frm); frm += 2;
    1382           0 :         capinfo = LE_READ_2(frm); frm += 2;
    1383             : 
    1384             :         ssid = rates = xrates = edcaie = wmmie = rsnie = wpaie = NULL;
    1385             :         htcaps = htop = NULL;
    1386           0 :         bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
    1387             :         chan = bchan;
    1388             :         erp = 0;
    1389             :         dtim_count = dtim_period = 0;
    1390           0 :         while (frm + 2 <= efrm) {
    1391           0 :                 if (frm + 2 + frm[1] > efrm) {
    1392           0 :                         ic->ic_stats.is_rx_elem_toosmall++;
    1393           0 :                         break;
    1394             :                 }
    1395           0 :                 switch (frm[0]) {
    1396             :                 case IEEE80211_ELEMID_SSID:
    1397             :                         ssid = frm;
    1398           0 :                         break;
    1399             :                 case IEEE80211_ELEMID_RATES:
    1400             :                         rates = frm;
    1401           0 :                         break;
    1402             :                 case IEEE80211_ELEMID_DSPARMS:
    1403           0 :                         if (frm[1] < 1) {
    1404           0 :                                 ic->ic_stats.is_rx_elem_toosmall++;
    1405           0 :                                 break;
    1406             :                         }
    1407           0 :                         chan = frm[2];
    1408           0 :                         break;
    1409             :                 case IEEE80211_ELEMID_XRATES:
    1410             :                         xrates = frm;
    1411           0 :                         break;
    1412             :                 case IEEE80211_ELEMID_ERP:
    1413           0 :                         if (frm[1] < 1) {
    1414           0 :                                 ic->ic_stats.is_rx_elem_toosmall++;
    1415           0 :                                 break;
    1416             :                         }
    1417           0 :                         erp = frm[2];
    1418           0 :                         break;
    1419             :                 case IEEE80211_ELEMID_RSN:
    1420             :                         rsnie = frm;
    1421           0 :                         break;
    1422             :                 case IEEE80211_ELEMID_EDCAPARMS:
    1423             :                         edcaie = frm;
    1424           0 :                         break;
    1425             :                 case IEEE80211_ELEMID_HTCAPS:
    1426             :                         htcaps = frm;
    1427           0 :                         break;
    1428             :                 case IEEE80211_ELEMID_HTOP:
    1429             :                         htop = frm;
    1430           0 :                         break;
    1431             :                 case IEEE80211_ELEMID_TIM:
    1432           0 :                         if (frm[1] > 3) {
    1433           0 :                                 dtim_count = frm[2];
    1434           0 :                                 dtim_period = frm[3];
    1435           0 :                         }
    1436             :                         break;
    1437             :                 case IEEE80211_ELEMID_VENDOR:
    1438           0 :                         if (frm[1] < 4) {
    1439           0 :                                 ic->ic_stats.is_rx_elem_toosmall++;
    1440           0 :                                 break;
    1441             :                         }
    1442           0 :                         if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
    1443           0 :                                 if (frm[5] == 1)
    1444           0 :                                         wpaie = frm;
    1445           0 :                                 else if (frm[1] >= 5 &&
    1446           0 :                                     frm[5] == 2 && frm[6] == 1)
    1447           0 :                                         wmmie = frm;
    1448             :                         }
    1449             :                         break;
    1450             :                 }
    1451           0 :                 frm += 2 + frm[1];
    1452             :         }
    1453             :         /* supported rates element is mandatory */
    1454           0 :         if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
    1455             :                 DPRINTF(("invalid supported rates element\n"));
    1456           0 :                 return;
    1457             :         }
    1458             :         /* SSID element is mandatory */
    1459           0 :         if (ssid == NULL || ssid[1] > IEEE80211_NWID_LEN) {
    1460             :                 DPRINTF(("invalid SSID element\n"));
    1461           0 :                 return;
    1462             :         }
    1463             : 
    1464             :         if (
    1465             : #if IEEE80211_CHAN_MAX < 255
    1466             :             chan > IEEE80211_CHAN_MAX ||
    1467             : #endif
    1468           0 :             isclr(ic->ic_chan_active, chan)) {
    1469             :                 DPRINTF(("ignore %s with invalid channel %u\n",
    1470             :                     isprobe ? "probe response" : "beacon", chan));
    1471           0 :                 ic->ic_stats.is_rx_badchan++;
    1472           0 :                 return;
    1473             :         }
    1474           0 :         if ((ic->ic_state != IEEE80211_S_SCAN ||
    1475           0 :              !(ic->ic_caps & IEEE80211_C_SCANALL)) &&
    1476           0 :             chan != bchan) {
    1477             :                 /*
    1478             :                  * Frame was received on a channel different from the
    1479             :                  * one indicated in the DS params element id;
    1480             :                  * silently discard it.
    1481             :                  *
    1482             :                  * NB: this can happen due to signal leakage.
    1483             :                  */
    1484             :                 DPRINTF(("ignore %s on channel %u marked for channel %u\n",
    1485             :                     isprobe ? "probe response" : "beacon", bchan, chan));
    1486           0 :                 ic->ic_stats.is_rx_chanmismatch++;
    1487           0 :                 return;
    1488             :         }
    1489             :         /*
    1490             :          * Use mac, channel and rssi so we collect only the
    1491             :          * best potential AP with the equal bssid while scanning.
    1492             :          * Collecting all potential APs may result in bloat of
    1493             :          * the node tree. This call will return NULL if the node
    1494             :          * for this APs does not exist or if the new node is the
    1495             :          * potential better one.
    1496             :          */
    1497           0 :         ni = ieee80211_find_node_for_beacon(ic, wh->i_addr2,
    1498           0 :             &ic->ic_channels[chan], ssid, rxi->rxi_rssi);
    1499           0 :         if (ni != NULL) {
    1500             :                 /*
    1501             :                  * If we are doing a directed scan for an AP with a hidden SSID
    1502             :                  * we must collect the SSID from a probe response to override
    1503             :                  * a non-zero-length SSID filled with zeroes that we may have
    1504             :                  * received earlier in a beacon.
    1505             :                  */
    1506           0 :                 if (isprobe && ssid[1] != 0 && ni->ni_essid[0] == '\0') {
    1507           0 :                         ni->ni_esslen = ssid[1];
    1508           0 :                         memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
    1509             :                         /* we know that ssid[1] <= IEEE80211_NWID_LEN */
    1510           0 :                         memcpy(ni->ni_essid, &ssid[2], ssid[1]);
    1511           0 :                 }
    1512             : 
    1513           0 :                 return;
    1514             :         }
    1515             : 
    1516             : #ifdef IEEE80211_DEBUG
    1517             :         if (ieee80211_debug > 1 &&
    1518             :             (ni == NULL || ic->ic_state == IEEE80211_S_SCAN ||
    1519             :             (ic->ic_flags & IEEE80211_F_BGSCAN))) {
    1520             :                 printf("%s: %s%s on chan %u (bss chan %u) ",
    1521             :                     __func__, (ni == NULL ? "new " : ""),
    1522             :                     isprobe ? "probe response" : "beacon",
    1523             :                     chan, bchan);
    1524             :                 ieee80211_print_essid(ssid + 2, ssid[1]);
    1525             :                 printf(" from %s\n", ether_sprintf((u_int8_t *)wh->i_addr2));
    1526             :                 printf("%s: caps 0x%x bintval %u erp 0x%x\n",
    1527             :                         __func__, capinfo, bintval, erp);
    1528             :         }
    1529             : #endif
    1530             : 
    1531           0 :         if ((ni = ieee80211_find_node(ic, wh->i_addr2)) == NULL) {
    1532           0 :                 ni = ieee80211_alloc_node(ic, wh->i_addr2);
    1533           0 :                 if (ni == NULL)
    1534           0 :                         return;
    1535             :                 is_new = 1;
    1536           0 :         } else
    1537             :                 is_new = 0;
    1538             : 
    1539           0 :         if (htcaps)
    1540           0 :                 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
    1541           0 :         if (htop && !ieee80211_setup_htop(ni, htop + 2, htop[1], 1))
    1542           0 :                 htop = NULL; /* invalid HTOP */
    1543             : 
    1544           0 :         ni->ni_dtimcount = dtim_count;
    1545           0 :         ni->ni_dtimperiod = dtim_period;
    1546             : 
    1547             :         /*
    1548             :          * When operating in station mode, check for state updates
    1549             :          * while we're associated.
    1550             :          */
    1551           0 :         if (ic->ic_opmode == IEEE80211_M_STA &&
    1552           0 :             ic->ic_state == IEEE80211_S_RUN &&
    1553           0 :             ni->ni_state == IEEE80211_STA_BSS) {
    1554             :                 /*
    1555             :                  * Check if protection mode has changed since last beacon.
    1556             :                  */
    1557           0 :                 if (ni->ni_erp != erp) {
    1558             :                         DPRINTF(("[%s] erp change: was 0x%x, now 0x%x\n",
    1559             :                             ether_sprintf((u_int8_t *)wh->i_addr2),
    1560             :                             ni->ni_erp, erp));
    1561           0 :                         if (ic->ic_curmode == IEEE80211_MODE_11G &&
    1562           0 :                             (erp & IEEE80211_ERP_USE_PROTECTION))
    1563           0 :                                 ic->ic_flags |= IEEE80211_F_USEPROT;
    1564             :                         else
    1565           0 :                                 ic->ic_flags &= ~IEEE80211_F_USEPROT;
    1566           0 :                         ic->ic_bss->ni_erp = erp;
    1567           0 :                 }
    1568           0 :                 if (htop && (ic->ic_bss->ni_flags & IEEE80211_NODE_HT)) {
    1569             :                         enum ieee80211_htprot htprot_last, htprot;
    1570             :                         htprot_last =
    1571           0 :                             ((ic->ic_bss->ni_htop1 & IEEE80211_HTOP1_PROT_MASK)
    1572             :                             >> IEEE80211_HTOP1_PROT_SHIFT);
    1573           0 :                         htprot = ((ni->ni_htop1 & IEEE80211_HTOP1_PROT_MASK) >>
    1574             :                             IEEE80211_HTOP1_PROT_SHIFT);
    1575           0 :                         if (htprot_last != htprot) {
    1576             :                                 DPRINTF(("[%s] htprot change: was %d, now %d\n",
    1577             :                                     ether_sprintf((u_int8_t *)wh->i_addr2),
    1578             :                                     htprot_last, htprot));
    1579           0 :                                 ic->ic_stats.is_ht_prot_change++;
    1580           0 :                                 ic->ic_bss->ni_htop1 = ni->ni_htop1;
    1581           0 :                                 if (ic->ic_update_htprot)
    1582           0 :                                         ic->ic_update_htprot(ic, ic->ic_bss);
    1583             :                         }
    1584           0 :                 }
    1585             : 
    1586             :                 /*
    1587             :                  * Check if AP short slot time setting has changed
    1588             :                  * since last beacon and give the driver a chance to
    1589             :                  * update the hardware.
    1590             :                  */
    1591           0 :                 if ((ni->ni_capinfo ^ capinfo) &
    1592             :                     IEEE80211_CAPINFO_SHORT_SLOTTIME) {
    1593           0 :                         ieee80211_set_shortslottime(ic,
    1594           0 :                             ic->ic_curmode == IEEE80211_MODE_11A ||
    1595           0 :                             (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
    1596           0 :                 }
    1597             : 
    1598             :                 /* 
    1599             :                  * Reset management timer. If it is non-zero in RUN state, the
    1600             :                  * driver sent a probe request after a missed beacon event.
    1601             :                  * This probe response indicates the AP is still serving us
    1602             :                  * so don't allow ieee80211_watchdog() to move us into SCAN.
    1603             :                  */
    1604           0 :                  if ((ic->ic_flags & IEEE80211_F_BGSCAN) == 0)
    1605           0 :                         ic->ic_mgt_timer = 0;
    1606             :         }
    1607             :         /*
    1608             :          * We do not try to update EDCA parameters if QoS was not negotiated
    1609             :          * with the AP at association time.
    1610             :          */
    1611           0 :         if (ni->ni_flags & IEEE80211_NODE_QOS) {
    1612             :                 /* always prefer EDCA IE over Wi-Fi Alliance WMM IE */
    1613           0 :                 if ((edcaie != NULL &&
    1614           0 :                      ieee80211_parse_edca_params(ic, edcaie) == 0) ||
    1615           0 :                     (wmmie != NULL &&
    1616           0 :                      ieee80211_parse_wmm_params(ic, wmmie) == 0))
    1617           0 :                         ni->ni_flags |= IEEE80211_NODE_QOS;
    1618             :                 else
    1619           0 :                         ni->ni_flags &= ~IEEE80211_NODE_QOS;
    1620             :         }
    1621             : 
    1622           0 :         if (ic->ic_state == IEEE80211_S_SCAN ||
    1623           0 :             (ic->ic_flags & IEEE80211_F_BGSCAN)) {
    1624           0 :                 struct ieee80211_rsnparams rsn, wpa;
    1625             : 
    1626           0 :                 ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    1627           0 :                 ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE;
    1628           0 :                 ni->ni_rsnakms = 0;
    1629           0 :                 ni->ni_supported_rsnakms = 0;
    1630           0 :                 ni->ni_rsnciphers = 0;
    1631           0 :                 ni->ni_rsngroupcipher = 0;
    1632           0 :                 ni->ni_rsngroupmgmtcipher = 0;
    1633           0 :                 ni->ni_rsncaps = 0;
    1634             : 
    1635           0 :                 if (rsnie != NULL &&
    1636           0 :                     ieee80211_parse_rsn(ic, rsnie, &rsn) == 0) {
    1637           0 :                         ni->ni_supported_rsnprotos |= IEEE80211_PROTO_RSN;
    1638           0 :                         ni->ni_supported_rsnakms |= rsn.rsn_akms;
    1639           0 :                 }
    1640           0 :                 if (wpaie != NULL &&
    1641           0 :                     ieee80211_parse_wpa(ic, wpaie, &wpa) == 0) {
    1642           0 :                         ni->ni_supported_rsnprotos |= IEEE80211_PROTO_WPA;
    1643           0 :                         ni->ni_supported_rsnakms |= wpa.rsn_akms;
    1644           0 :                 }
    1645             : 
    1646             :                 /*
    1647             :                  * If the AP advertises both WPA and RSN IEs (WPA1+WPA2),
    1648             :                  * we only use the highest protocol version we support.
    1649             :                  */
    1650           0 :                 if (rsnie != NULL &&
    1651           0 :                     (ni->ni_supported_rsnprotos & IEEE80211_PROTO_RSN) &&
    1652           0 :                     (ic->ic_rsnprotos & IEEE80211_PROTO_RSN)) {
    1653           0 :                         if (ieee80211_save_ie(rsnie, &ni->ni_rsnie) == 0
    1654             : #ifndef IEEE80211_STA_ONLY
    1655           0 :                         && ic->ic_opmode != IEEE80211_M_HOSTAP
    1656             : #endif
    1657             :                         ) {
    1658           0 :                                 ni->ni_rsnprotos = IEEE80211_PROTO_RSN;
    1659           0 :                                 ni->ni_rsnakms = rsn.rsn_akms;
    1660           0 :                                 ni->ni_rsnciphers = rsn.rsn_ciphers;
    1661           0 :                                 ni->ni_rsngroupcipher = rsn.rsn_groupcipher;
    1662           0 :                                 ni->ni_rsngroupmgmtcipher =
    1663           0 :                                     rsn.rsn_groupmgmtcipher;
    1664           0 :                                 ni->ni_rsncaps = rsn.rsn_caps;
    1665           0 :                         }
    1666           0 :                 } else if (wpaie != NULL &&
    1667           0 :                     (ni->ni_supported_rsnprotos & IEEE80211_PROTO_WPA) &&
    1668           0 :                     (ic->ic_rsnprotos & IEEE80211_PROTO_WPA)) {
    1669           0 :                         if (ieee80211_save_ie(wpaie, &ni->ni_rsnie) == 0
    1670             : #ifndef IEEE80211_STA_ONLY
    1671           0 :                         && ic->ic_opmode != IEEE80211_M_HOSTAP
    1672             : #endif
    1673             :                         ) {
    1674           0 :                                 ni->ni_rsnprotos = IEEE80211_PROTO_WPA;
    1675           0 :                                 ni->ni_rsnakms = wpa.rsn_akms;
    1676           0 :                                 ni->ni_rsnciphers = wpa.rsn_ciphers;
    1677           0 :                                 ni->ni_rsngroupcipher = wpa.rsn_groupcipher;
    1678           0 :                                 ni->ni_rsngroupmgmtcipher =
    1679           0 :                                     wpa.rsn_groupmgmtcipher;
    1680           0 :                                 ni->ni_rsncaps = wpa.rsn_caps;
    1681           0 :                         }
    1682             :                 }
    1683           0 :         }
    1684             : 
    1685           0 :         if (ssid[1] != 0 && ni->ni_essid[0] == '\0') {
    1686           0 :                 ni->ni_esslen = ssid[1];
    1687           0 :                 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
    1688             :                 /* we know that ssid[1] <= IEEE80211_NWID_LEN */
    1689           0 :                 memcpy(ni->ni_essid, &ssid[2], ssid[1]);
    1690           0 :         }
    1691           0 :         IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
    1692             :         /* XXX validate channel # */
    1693           0 :         ni->ni_chan = &ic->ic_channels[chan];
    1694           0 :         if (ic->ic_state == IEEE80211_S_SCAN &&
    1695           0 :             IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) {
    1696             :                 /*
    1697             :                  * During a scan on 5Ghz, prefer RSSI measured for probe
    1698             :                  * response frames. i.e. don't allow beacons to lower the
    1699             :                  * measured RSSI. Some 5GHz APs send beacons with much
    1700             :                  * less Tx power than they use for probe responses.
    1701             :                  */
    1702           0 :                  if (isprobe)
    1703           0 :                         ni->ni_rssi = rxi->rxi_rssi;
    1704           0 :                 else if (ni->ni_rssi < rxi->rxi_rssi)
    1705           0 :                         ni->ni_rssi = rxi->rxi_rssi;
    1706             :         } else
    1707           0 :                 ni->ni_rssi = rxi->rxi_rssi;
    1708           0 :         ni->ni_rstamp = rxi->rxi_tstamp;
    1709           0 :         memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp));
    1710           0 :         ni->ni_intval = bintval;
    1711           0 :         ni->ni_capinfo = capinfo;
    1712           0 :         ni->ni_erp = erp;
    1713             :         /* NB: must be after ni_chan is setup */
    1714           0 :         ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
    1715             : #ifndef IEEE80211_STA_ONLY
    1716           0 :         if (ic->ic_opmode == IEEE80211_M_IBSS && is_new && isprobe) {
    1717             :                 /*
    1718             :                  * Fake an association so the driver can setup it's
    1719             :                  * private state.  The rate set has been setup above;
    1720             :                  * there is no handshake as in ap/station operation.
    1721             :                  */
    1722           0 :                 if (ic->ic_newassoc)
    1723           0 :                         (*ic->ic_newassoc)(ic, ni, 1);
    1724             :         }
    1725             : #endif
    1726           0 : }
    1727             : 
    1728             : #ifndef IEEE80211_STA_ONLY
    1729             : /*-
    1730             :  * Probe request frame format:
    1731             :  * [tlv] SSID
    1732             :  * [tlv] Supported rates
    1733             :  * [tlv] Extended Supported Rates (802.11g)
    1734             :  * [tlv] HT Capabilities (802.11n)
    1735             :  */
    1736             : void
    1737           0 : ieee80211_recv_probe_req(struct ieee80211com *ic, struct mbuf *m,
    1738             :     struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi)
    1739             : {
    1740             :         const struct ieee80211_frame *wh;
    1741             :         const u_int8_t *frm, *efrm;
    1742             :         const u_int8_t *ssid, *rates, *xrates, *htcaps;
    1743             :         u_int8_t rate;
    1744             : 
    1745           0 :         if (ic->ic_opmode == IEEE80211_M_STA ||
    1746           0 :             ic->ic_state != IEEE80211_S_RUN)
    1747           0 :                 return;
    1748             : 
    1749           0 :         wh = mtod(m, struct ieee80211_frame *);
    1750           0 :         frm = (const u_int8_t *)&wh[1];
    1751           0 :         efrm = mtod(m, u_int8_t *) + m->m_len;
    1752             : 
    1753             :         ssid = rates = xrates = htcaps = NULL;
    1754           0 :         while (frm + 2 <= efrm) {
    1755           0 :                 if (frm + 2 + frm[1] > efrm) {
    1756           0 :                         ic->ic_stats.is_rx_elem_toosmall++;
    1757           0 :                         break;
    1758             :                 }
    1759           0 :                 switch (frm[0]) {
    1760             :                 case IEEE80211_ELEMID_SSID:
    1761             :                         ssid = frm;
    1762           0 :                         break;
    1763             :                 case IEEE80211_ELEMID_RATES:
    1764             :                         rates = frm;
    1765           0 :                         break;
    1766             :                 case IEEE80211_ELEMID_XRATES:
    1767             :                         xrates = frm;
    1768           0 :                         break;
    1769             :                 case IEEE80211_ELEMID_HTCAPS:
    1770             :                         htcaps = frm;
    1771           0 :                         break;
    1772             :                 }
    1773           0 :                 frm += 2 + frm[1];
    1774             :         }
    1775             :         /* supported rates element is mandatory */
    1776           0 :         if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
    1777             :                 DPRINTF(("invalid supported rates element\n"));
    1778           0 :                 return;
    1779             :         }
    1780             :         /* SSID element is mandatory */
    1781           0 :         if (ssid == NULL || ssid[1] > IEEE80211_NWID_LEN) {
    1782             :                 DPRINTF(("invalid SSID element\n"));
    1783           0 :                 return;
    1784             :         }
    1785             :         /* check that the specified SSID (if not wildcard) matches ours */
    1786           0 :         if (ssid[1] != 0 && (ssid[1] != ic->ic_bss->ni_esslen ||
    1787           0 :             memcmp(&ssid[2], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen))) {
    1788             :                 DPRINTF(("SSID mismatch\n"));
    1789           0 :                 ic->ic_stats.is_rx_ssidmismatch++;
    1790           0 :                 return;
    1791             :         }
    1792             :         /* refuse wildcard SSID if we're hiding our SSID in beacons */
    1793           0 :         if (ssid[1] == 0 && (ic->ic_flags & IEEE80211_F_HIDENWID)) {
    1794             :                 DPRINTF(("wildcard SSID rejected"));
    1795           0 :                 ic->ic_stats.is_rx_ssidmismatch++;
    1796           0 :                 return;
    1797             :         }
    1798             : 
    1799           0 :         if (ni == ic->ic_bss) {
    1800           0 :                 ni = ieee80211_find_node(ic, wh->i_addr2);
    1801           0 :                 if (ni == NULL)
    1802           0 :                         ni = ieee80211_dup_bss(ic, wh->i_addr2);
    1803           0 :                 if (ni == NULL)
    1804           0 :                         return;
    1805             :                 DPRINTF(("new probe req from %s\n",
    1806             :                     ether_sprintf((u_int8_t *)wh->i_addr2)));
    1807             :         }
    1808           0 :         ni->ni_rssi = rxi->rxi_rssi;
    1809           0 :         ni->ni_rstamp = rxi->rxi_tstamp;
    1810           0 :         rate = ieee80211_setup_rates(ic, ni, rates, xrates,
    1811             :             IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
    1812             :             IEEE80211_F_DODEL);
    1813           0 :         if (rate & IEEE80211_RATE_BASIC) {
    1814             :                 DPRINTF(("rate mismatch for %s\n",
    1815             :                     ether_sprintf((u_int8_t *)wh->i_addr2)));
    1816           0 :                 return;
    1817             :         }
    1818           0 :         if (htcaps)
    1819           0 :                 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
    1820             :         else
    1821           0 :                 ieee80211_clear_htcaps(ni);
    1822           0 :         IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
    1823           0 : }
    1824             : #endif  /* IEEE80211_STA_ONLY */
    1825             : 
    1826             : /*-
    1827             :  * Authentication frame format:
    1828             :  * [2] Authentication algorithm number
    1829             :  * [2] Authentication transaction sequence number
    1830             :  * [2] Status code
    1831             :  */
    1832             : void
    1833           0 : ieee80211_recv_auth(struct ieee80211com *ic, struct mbuf *m,
    1834             :     struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi)
    1835             : {
    1836             :         const struct ieee80211_frame *wh;
    1837             :         const u_int8_t *frm;
    1838             :         u_int16_t algo, seq, status;
    1839             : 
    1840             :         /* make sure all mandatory fixed fields are present */
    1841           0 :         if (m->m_len < sizeof(*wh) + 6) {
    1842             :                 DPRINTF(("frame too short\n"));
    1843           0 :                 return;
    1844             :         }
    1845           0 :         wh = mtod(m, struct ieee80211_frame *);
    1846           0 :         frm = (const u_int8_t *)&wh[1];
    1847             : 
    1848           0 :         algo   = LE_READ_2(frm); frm += 2;
    1849           0 :         seq    = LE_READ_2(frm); frm += 2;
    1850           0 :         status = LE_READ_2(frm); frm += 2;
    1851             :         DPRINTF(("auth %d seq %d from %s\n", algo, seq,
    1852             :             ether_sprintf((u_int8_t *)wh->i_addr2)));
    1853             : 
    1854             :         /* only "open" auth mode is supported */
    1855           0 :         if (algo != IEEE80211_AUTH_ALG_OPEN) {
    1856             :                 DPRINTF(("unsupported auth algorithm %d from %s\n",
    1857             :                     algo, ether_sprintf((u_int8_t *)wh->i_addr2)));
    1858           0 :                 ic->ic_stats.is_rx_auth_unsupported++;
    1859             : #ifndef IEEE80211_STA_ONLY
    1860           0 :                 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
    1861             :                         /* XXX hack to workaround calling convention */
    1862           0 :                         IEEE80211_SEND_MGMT(ic, ni,
    1863             :                             IEEE80211_FC0_SUBTYPE_AUTH,
    1864             :                             IEEE80211_STATUS_ALG << 16 | ((seq + 1) & 0xffff));
    1865           0 :                 }
    1866             : #endif
    1867           0 :                 return;
    1868             :         }
    1869           0 :         ieee80211_auth_open(ic, wh, ni, rxi, seq, status);
    1870           0 : }
    1871             : 
    1872             : #ifndef IEEE80211_STA_ONLY
    1873             : /*-
    1874             :  * (Re)Association request frame format:
    1875             :  * [2]   Capability information
    1876             :  * [2]   Listen interval
    1877             :  * [6*]  Current AP address (Reassociation only)
    1878             :  * [tlv] SSID
    1879             :  * [tlv] Supported rates
    1880             :  * [tlv] Extended Supported Rates (802.11g)
    1881             :  * [tlv] RSN (802.11i)
    1882             :  * [tlv] QoS Capability (802.11e)
    1883             :  * [tlv] HT Capabilities (802.11n)
    1884             :  */
    1885             : void
    1886           0 : ieee80211_recv_assoc_req(struct ieee80211com *ic, struct mbuf *m,
    1887             :     struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int reassoc)
    1888             : {
    1889             :         const struct ieee80211_frame *wh;
    1890             :         const u_int8_t *frm, *efrm;
    1891             :         const u_int8_t *ssid, *rates, *xrates, *rsnie, *wpaie, *htcaps;
    1892             :         u_int16_t capinfo, bintval;
    1893             :         int resp, status = 0;
    1894           0 :         struct ieee80211_rsnparams rsn;
    1895             :         u_int8_t rate;
    1896             :         const u_int8_t *saveie = NULL;
    1897             : 
    1898           0 :         if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
    1899           0 :             ic->ic_state != IEEE80211_S_RUN)
    1900           0 :                 return;
    1901             : 
    1902             :         /* make sure all mandatory fixed fields are present */
    1903           0 :         if (m->m_len < sizeof(*wh) + (reassoc ? 10 : 4)) {
    1904             :                 DPRINTF(("frame too short\n"));
    1905           0 :                 return;
    1906             :         }
    1907           0 :         wh = mtod(m, struct ieee80211_frame *);
    1908           0 :         frm = (const u_int8_t *)&wh[1];
    1909           0 :         efrm = mtod(m, u_int8_t *) + m->m_len;
    1910             : 
    1911           0 :         if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
    1912             :                 DPRINTF(("ignore other bss from %s\n",
    1913             :                     ether_sprintf((u_int8_t *)wh->i_addr2)));
    1914           0 :                 ic->ic_stats.is_rx_assoc_bss++;
    1915           0 :                 return;
    1916             :         }
    1917           0 :         capinfo = LE_READ_2(frm); frm += 2;
    1918           0 :         bintval = LE_READ_2(frm); frm += 2;
    1919           0 :         if (reassoc) {
    1920           0 :                 frm += IEEE80211_ADDR_LEN;      /* skip current AP address */
    1921             :                 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
    1922           0 :         } else
    1923             :                 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
    1924             : 
    1925             :         ssid = rates = xrates = rsnie = wpaie = htcaps = NULL;
    1926           0 :         while (frm + 2 <= efrm) {
    1927           0 :                 if (frm + 2 + frm[1] > efrm) {
    1928           0 :                         ic->ic_stats.is_rx_elem_toosmall++;
    1929           0 :                         break;
    1930             :                 }
    1931           0 :                 switch (frm[0]) {
    1932             :                 case IEEE80211_ELEMID_SSID:
    1933             :                         ssid = frm;
    1934           0 :                         break;
    1935             :                 case IEEE80211_ELEMID_RATES:
    1936             :                         rates = frm;
    1937           0 :                         break;
    1938             :                 case IEEE80211_ELEMID_XRATES:
    1939             :                         xrates = frm;
    1940           0 :                         break;
    1941             :                 case IEEE80211_ELEMID_RSN:
    1942             :                         rsnie = frm;
    1943           0 :                         break;
    1944             :                 case IEEE80211_ELEMID_QOS_CAP:
    1945             :                         break;
    1946             :                 case IEEE80211_ELEMID_HTCAPS:
    1947             :                         htcaps = frm;
    1948           0 :                         break;
    1949             :                 case IEEE80211_ELEMID_VENDOR:
    1950           0 :                         if (frm[1] < 4) {
    1951           0 :                                 ic->ic_stats.is_rx_elem_toosmall++;
    1952           0 :                                 break;
    1953             :                         }
    1954           0 :                         if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
    1955           0 :                                 if (frm[5] == 1)
    1956           0 :                                         wpaie = frm;
    1957             :                         }
    1958             :                         break;
    1959             :                 }
    1960           0 :                 frm += 2 + frm[1];
    1961             :         }
    1962             :         /* supported rates element is mandatory */
    1963           0 :         if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
    1964             :                 DPRINTF(("invalid supported rates element\n"));
    1965           0 :                 return;
    1966             :         }
    1967             :         /* SSID element is mandatory */
    1968           0 :         if (ssid == NULL || ssid[1] > IEEE80211_NWID_LEN) {
    1969             :                 DPRINTF(("invalid SSID element\n"));
    1970           0 :                 return;
    1971             :         }
    1972             :         /* check that the specified SSID matches ours */
    1973           0 :         if (ssid[1] != ic->ic_bss->ni_esslen ||
    1974           0 :             memcmp(&ssid[2], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen)) {
    1975             :                 DPRINTF(("SSID mismatch\n"));
    1976           0 :                 ic->ic_stats.is_rx_ssidmismatch++;
    1977           0 :                 return;
    1978             :         }
    1979             : 
    1980           0 :         if (ni->ni_state != IEEE80211_STA_AUTH &&
    1981           0 :             ni->ni_state != IEEE80211_STA_ASSOC) {
    1982             :                 DPRINTF(("deny %sassoc from %s, not authenticated\n",
    1983             :                     reassoc ? "re" : "",
    1984             :                     ether_sprintf((u_int8_t *)wh->i_addr2)));
    1985           0 :                 ni = ieee80211_find_node(ic, wh->i_addr2);
    1986           0 :                 if (ni == NULL)
    1987           0 :                         ni = ieee80211_dup_bss(ic, wh->i_addr2);
    1988           0 :                 if (ni != NULL) {
    1989           0 :                         IEEE80211_SEND_MGMT(ic, ni,
    1990             :                             IEEE80211_FC0_SUBTYPE_DEAUTH,
    1991             :                             IEEE80211_REASON_ASSOC_NOT_AUTHED);
    1992           0 :                 }
    1993           0 :                 ic->ic_stats.is_rx_assoc_notauth++;
    1994           0 :                 return;
    1995             :         }
    1996             : 
    1997           0 :         if (ni->ni_state == IEEE80211_STA_ASSOC &&
    1998           0 :             (ni->ni_flags & IEEE80211_NODE_MFP)) {
    1999           0 :                 if (ni->ni_flags & IEEE80211_NODE_SA_QUERY_FAILED) {
    2000             :                         /* send a protected Disassociate frame */
    2001           0 :                         IEEE80211_SEND_MGMT(ic, ni,
    2002             :                             IEEE80211_FC0_SUBTYPE_DISASSOC,
    2003             :                             IEEE80211_REASON_AUTH_EXPIRE);
    2004             :                         /* terminate the old SA */
    2005           0 :                         ieee80211_node_leave(ic, ni);
    2006           0 :                 } else {
    2007             :                         /* reject the (Re)Association Request temporarily */
    2008           0 :                         IEEE80211_SEND_MGMT(ic, ni, resp,
    2009             :                             IEEE80211_STATUS_TRY_AGAIN_LATER);
    2010             :                         /* start SA Query procedure if not already engaged */
    2011           0 :                         if (!(ni->ni_flags & IEEE80211_NODE_SA_QUERY))
    2012           0 :                                 ieee80211_sa_query_request(ic, ni);
    2013             :                         /* do not modify association state */
    2014             :                 }
    2015           0 :                 return;
    2016             :         }
    2017             : 
    2018           0 :         if (!(capinfo & IEEE80211_CAPINFO_ESS)) {
    2019           0 :                 ic->ic_stats.is_rx_assoc_capmismatch++;
    2020             :                 status = IEEE80211_STATUS_CAPINFO;
    2021           0 :                 goto end;
    2022             :         }
    2023           0 :         rate = ieee80211_setup_rates(ic, ni, rates, xrates,
    2024             :             IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
    2025             :             IEEE80211_F_DODEL);
    2026           0 :         if (rate & IEEE80211_RATE_BASIC) {
    2027           0 :                 ic->ic_stats.is_rx_assoc_norate++;
    2028             :                 status = IEEE80211_STATUS_BASIC_RATE;
    2029           0 :                 goto end;
    2030             :         }
    2031             : 
    2032           0 :         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2033           0 :         ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE;
    2034           0 :         ni->ni_rsnakms = 0;
    2035           0 :         ni->ni_supported_rsnakms = 0;
    2036           0 :         ni->ni_rsnciphers = 0;
    2037           0 :         ni->ni_rsngroupcipher = 0;
    2038           0 :         ni->ni_rsngroupmgmtcipher = 0;
    2039           0 :         ni->ni_rsncaps = 0;
    2040             : 
    2041             :         /*
    2042             :          * A station should never include both a WPA and an RSN IE
    2043             :          * in its (Re)Association Requests, but if it does, we only
    2044             :          * consider the IE of the highest version of the protocol
    2045             :          * that is allowed (ie RSN over WPA).
    2046             :          */
    2047           0 :         if (rsnie != NULL) {
    2048           0 :                 status = ieee80211_parse_rsn(ic, rsnie, &rsn);
    2049           0 :                 if (status != 0)
    2050             :                         goto end;
    2051           0 :                 ni->ni_supported_rsnprotos = IEEE80211_PROTO_RSN;
    2052           0 :                 ni->ni_supported_rsnakms = rsn.rsn_akms;
    2053           0 :                 if ((ic->ic_flags & IEEE80211_F_RSNON) &&
    2054           0 :                     (ic->ic_rsnprotos & IEEE80211_PROTO_RSN)) {
    2055           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_RSN;
    2056             :                         saveie = rsnie;
    2057           0 :                 }
    2058           0 :         } else if (wpaie != NULL) {
    2059           0 :                 status = ieee80211_parse_wpa(ic, wpaie, &rsn);
    2060           0 :                 if (status != 0)
    2061             :                         goto end;
    2062           0 :                 ni->ni_supported_rsnprotos = IEEE80211_PROTO_WPA;
    2063           0 :                 ni->ni_supported_rsnakms = rsn.rsn_akms;
    2064           0 :                 if ((ic->ic_flags & IEEE80211_F_RSNON) &&
    2065           0 :                     (ic->ic_rsnprotos & IEEE80211_PROTO_WPA)) {
    2066           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_WPA;
    2067             :                         saveie = wpaie;
    2068           0 :                 }
    2069             :         }
    2070             : 
    2071           0 :         if (ic->ic_flags & IEEE80211_F_RSNON) {
    2072           0 :                 if (ni->ni_rsnprotos == IEEE80211_PROTO_NONE) {
    2073             :                         /*
    2074             :                          * In an RSN, an AP shall not associate with STAs
    2075             :                          * that fail to include the RSN IE in the
    2076             :                          * (Re)Association Request.
    2077             :                          */
    2078             :                         status = IEEE80211_STATUS_IE_INVALID;
    2079           0 :                         goto end;
    2080             :                 }
    2081             :                 /*
    2082             :                  * The initiating STA's RSN IE shall include one authentication
    2083             :                  * and pairwise cipher suite among those advertised by the
    2084             :                  * targeted AP.  It shall also specify the group cipher suite
    2085             :                  * specified by the targeted AP.
    2086             :                  */
    2087           0 :                 if (rsn.rsn_nakms != 1 ||
    2088           0 :                     !(rsn.rsn_akms & ic->ic_bss->ni_rsnakms)) {
    2089             :                         status = IEEE80211_STATUS_BAD_AKMP;
    2090           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2091           0 :                         goto end;
    2092             :                 }
    2093           0 :                 if (rsn.rsn_nciphers != 1 ||
    2094           0 :                     !(rsn.rsn_ciphers & ic->ic_bss->ni_rsnciphers)) {
    2095             :                         status = IEEE80211_STATUS_BAD_PAIRWISE_CIPHER;
    2096           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2097           0 :                         goto end;
    2098             :                 }
    2099           0 :                 if (rsn.rsn_groupcipher != ic->ic_bss->ni_rsngroupcipher) {
    2100             :                         status = IEEE80211_STATUS_BAD_GROUP_CIPHER;
    2101           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2102           0 :                         goto end;
    2103             :                 }
    2104             : 
    2105           0 :                 if ((ic->ic_bss->ni_rsncaps & IEEE80211_RSNCAP_MFPR) &&
    2106           0 :                     !(rsn.rsn_caps & IEEE80211_RSNCAP_MFPC)) {
    2107             :                         status = IEEE80211_STATUS_MFP_POLICY;
    2108           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2109           0 :                         goto end;
    2110             :                 }
    2111           0 :                 if ((ic->ic_bss->ni_rsncaps & IEEE80211_RSNCAP_MFPC) &&
    2112           0 :                     (rsn.rsn_caps & (IEEE80211_RSNCAP_MFPC |
    2113           0 :                      IEEE80211_RSNCAP_MFPR)) == IEEE80211_RSNCAP_MFPR) {
    2114             :                         /* STA advertises an invalid setting */
    2115             :                         status = IEEE80211_STATUS_MFP_POLICY;
    2116           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2117           0 :                         goto end;
    2118             :                 }
    2119             :                 /*
    2120             :                  * A STA that has associated with Management Frame Protection
    2121             :                  * enabled shall not use cipher suite pairwise selector WEP40,
    2122             :                  * WEP104, TKIP, or "Use Group cipher suite".
    2123             :                  */
    2124           0 :                 if ((rsn.rsn_caps & IEEE80211_RSNCAP_MFPC) &&
    2125           0 :                     (rsn.rsn_ciphers != IEEE80211_CIPHER_CCMP ||
    2126           0 :                      rsn.rsn_groupmgmtcipher !=
    2127           0 :                      ic->ic_bss->ni_rsngroupmgmtcipher)) {
    2128             :                         status = IEEE80211_STATUS_MFP_POLICY;
    2129           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2130           0 :                         goto end;
    2131             :                 }
    2132             : 
    2133             :                 /*
    2134             :                  * Disallow new associations using TKIP if countermeasures
    2135             :                  * are active.
    2136             :                  */
    2137           0 :                 if ((ic->ic_flags & IEEE80211_F_COUNTERM) &&
    2138           0 :                     (rsn.rsn_ciphers == IEEE80211_CIPHER_TKIP ||
    2139           0 :                      rsn.rsn_groupcipher == IEEE80211_CIPHER_TKIP)) {
    2140             :                         status = IEEE80211_STATUS_CIPHER_REJ_POLICY;
    2141           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2142           0 :                         goto end;
    2143             :                 }
    2144             : 
    2145             :                 /* everything looks fine, save IE and parameters */
    2146           0 :                 if (saveie == NULL ||
    2147           0 :                     ieee80211_save_ie(saveie, &ni->ni_rsnie) != 0) {
    2148             :                         status = IEEE80211_STATUS_TOOMANY;
    2149           0 :                         ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
    2150           0 :                         goto end;
    2151             :                 }
    2152           0 :                 ni->ni_rsnakms = rsn.rsn_akms;
    2153           0 :                 ni->ni_rsnciphers = rsn.rsn_ciphers;
    2154           0 :                 ni->ni_rsngroupcipher = ic->ic_bss->ni_rsngroupcipher;
    2155           0 :                 ni->ni_rsngroupmgmtcipher = ic->ic_bss->ni_rsngroupmgmtcipher;
    2156           0 :                 ni->ni_rsncaps = rsn.rsn_caps;
    2157             : 
    2158           0 :                 if (ieee80211_is_8021x_akm(ni->ni_rsnakms)) {
    2159             :                         struct ieee80211_pmk *pmk = NULL;
    2160           0 :                         const u_int8_t *pmkid = rsn.rsn_pmkids;
    2161             :                         /*
    2162             :                          * Check if we have a cached PMK entry matching one
    2163             :                          * of the PMKIDs specified in the RSN IE.
    2164             :                          */
    2165           0 :                         while (rsn.rsn_npmkids-- > 0) {
    2166           0 :                                 pmk = ieee80211_pmksa_find(ic, ni, pmkid);
    2167           0 :                                 if (pmk != NULL)
    2168             :                                         break;
    2169           0 :                                 pmkid += IEEE80211_PMKID_LEN;
    2170             :                         }
    2171           0 :                         if (pmk != NULL) {
    2172           0 :                                 memcpy(ni->ni_pmk, pmk->pmk_key,
    2173             :                                     IEEE80211_PMK_LEN);
    2174           0 :                                 memcpy(ni->ni_pmkid, pmk->pmk_pmkid,
    2175             :                                     IEEE80211_PMKID_LEN);
    2176           0 :                                 ni->ni_flags |= IEEE80211_NODE_PMK;
    2177           0 :                         }
    2178           0 :                 }
    2179             :         }
    2180             : 
    2181           0 :         ni->ni_rssi = rxi->rxi_rssi;
    2182           0 :         ni->ni_rstamp = rxi->rxi_tstamp;
    2183           0 :         ni->ni_intval = bintval;
    2184           0 :         ni->ni_capinfo = capinfo;
    2185           0 :         ni->ni_chan = ic->ic_bss->ni_chan;
    2186           0 :         if (htcaps)
    2187           0 :                 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
    2188             :         else
    2189           0 :                 ieee80211_clear_htcaps(ni);
    2190             :  end:
    2191           0 :         if (status != 0) {
    2192           0 :                 IEEE80211_SEND_MGMT(ic, ni, resp, status);
    2193           0 :                 ieee80211_node_leave(ic, ni);
    2194           0 :         } else
    2195           0 :                 ieee80211_node_join(ic, ni, resp);
    2196           0 : }
    2197             : #endif  /* IEEE80211_STA_ONLY */
    2198             : 
    2199             : /*-
    2200             :  * (Re)Association response frame format:
    2201             :  * [2]   Capability information
    2202             :  * [2]   Status code
    2203             :  * [2]   Association ID (AID)
    2204             :  * [tlv] Supported rates
    2205             :  * [tlv] Extended Supported Rates (802.11g)
    2206             :  * [tlv] EDCA Parameter Set (802.11e)
    2207             :  * [tlv] HT Capabilities (802.11n)
    2208             :  * [tlv] HT Operation (802.11n)
    2209             :  */
    2210             : void
    2211           0 : ieee80211_recv_assoc_resp(struct ieee80211com *ic, struct mbuf *m,
    2212             :     struct ieee80211_node *ni, int reassoc)
    2213             : {
    2214           0 :         struct ifnet *ifp = &ic->ic_if;
    2215             :         const struct ieee80211_frame *wh;
    2216             :         const u_int8_t *frm, *efrm;
    2217             :         const u_int8_t *rates, *xrates, *edcaie, *wmmie, *htcaps, *htop;
    2218             :         u_int16_t capinfo, status, associd;
    2219             :         u_int8_t rate;
    2220             : 
    2221           0 :         if (ic->ic_opmode != IEEE80211_M_STA ||
    2222           0 :             ic->ic_state != IEEE80211_S_ASSOC) {
    2223           0 :                 ic->ic_stats.is_rx_mgtdiscard++;
    2224           0 :                 return;
    2225             :         }
    2226             : 
    2227             :         /* make sure all mandatory fixed fields are present */
    2228           0 :         if (m->m_len < sizeof(*wh) + 6) {
    2229             :                 DPRINTF(("frame too short\n"));
    2230           0 :                 return;
    2231             :         }
    2232           0 :         wh = mtod(m, struct ieee80211_frame *);
    2233           0 :         frm = (const u_int8_t *)&wh[1];
    2234           0 :         efrm = mtod(m, u_int8_t *) + m->m_len;
    2235             : 
    2236           0 :         capinfo = LE_READ_2(frm); frm += 2;
    2237           0 :         status =  LE_READ_2(frm); frm += 2;
    2238           0 :         if (status != IEEE80211_STATUS_SUCCESS) {
    2239           0 :                 if (ifp->if_flags & IFF_DEBUG)
    2240           0 :                         printf("%s: %sassociation failed (status %d)"
    2241           0 :                             " for %s\n", ifp->if_xname,
    2242           0 :                             reassoc ?  "re" : "",
    2243           0 :                             status, ether_sprintf((u_int8_t *)wh->i_addr3));
    2244           0 :                 if (ni != ic->ic_bss)
    2245           0 :                         ni->ni_fails++;
    2246           0 :                 ic->ic_stats.is_rx_auth_fail++;
    2247           0 :                 return;
    2248             :         }
    2249           0 :         associd = LE_READ_2(frm); frm += 2;
    2250             : 
    2251             :         rates = xrates = edcaie = wmmie = htcaps = htop = NULL;
    2252           0 :         while (frm + 2 <= efrm) {
    2253           0 :                 if (frm + 2 + frm[1] > efrm) {
    2254           0 :                         ic->ic_stats.is_rx_elem_toosmall++;
    2255           0 :                         break;
    2256             :                 }
    2257           0 :                 switch (frm[0]) {
    2258             :                 case IEEE80211_ELEMID_RATES:
    2259             :                         rates = frm;
    2260           0 :                         break;
    2261             :                 case IEEE80211_ELEMID_XRATES:
    2262             :                         xrates = frm;
    2263           0 :                         break;
    2264             :                 case IEEE80211_ELEMID_EDCAPARMS:
    2265             :                         edcaie = frm;
    2266           0 :                         break;
    2267             :                 case IEEE80211_ELEMID_HTCAPS:
    2268             :                         htcaps = frm;
    2269           0 :                         break;
    2270             :                 case IEEE80211_ELEMID_HTOP:
    2271             :                         htop = frm;
    2272           0 :                         break;
    2273             :                 case IEEE80211_ELEMID_VENDOR:
    2274           0 :                         if (frm[1] < 4) {
    2275           0 :                                 ic->ic_stats.is_rx_elem_toosmall++;
    2276           0 :                                 break;
    2277             :                         }
    2278           0 :                         if (memcmp(frm + 2, MICROSOFT_OUI, 3) == 0) {
    2279           0 :                                 if (frm[1] >= 5 && frm[5] == 2 && frm[6] == 1)
    2280           0 :                                         wmmie = frm;
    2281             :                         }
    2282             :                         break;
    2283             :                 }
    2284           0 :                 frm += 2 + frm[1];
    2285             :         }
    2286             :         /* supported rates element is mandatory */
    2287           0 :         if (rates == NULL || rates[1] > IEEE80211_RATE_MAXSIZE) {
    2288             :                 DPRINTF(("invalid supported rates element\n"));
    2289           0 :                 return;
    2290             :         }
    2291           0 :         rate = ieee80211_setup_rates(ic, ni, rates, xrates,
    2292             :             IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | IEEE80211_F_DONEGO |
    2293             :             IEEE80211_F_DODEL);
    2294           0 :         if (rate & IEEE80211_RATE_BASIC) {
    2295             :                 DPRINTF(("rate mismatch for %s\n",
    2296             :                     ether_sprintf((u_int8_t *)wh->i_addr2)));
    2297           0 :                 ic->ic_stats.is_rx_assoc_norate++;
    2298           0 :                 return;
    2299             :         }
    2300           0 :         ni->ni_capinfo = capinfo;
    2301           0 :         ni->ni_associd = associd;
    2302           0 :         if (edcaie != NULL || wmmie != NULL) {
    2303             :                 /* force update of EDCA parameters */
    2304           0 :                 ic->ic_edca_updtcount = -1;
    2305             : 
    2306           0 :                 if ((edcaie != NULL &&
    2307           0 :                      ieee80211_parse_edca_params(ic, edcaie) == 0) ||
    2308           0 :                     (wmmie != NULL &&
    2309           0 :                      ieee80211_parse_wmm_params(ic, wmmie) == 0))
    2310           0 :                         ni->ni_flags |= IEEE80211_NODE_QOS;
    2311             :                 else    /* for Reassociation */
    2312           0 :                         ni->ni_flags &= ~IEEE80211_NODE_QOS;
    2313             :         }
    2314           0 :         if (htcaps)
    2315           0 :                 ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
    2316           0 :         if (htop)
    2317           0 :                 ieee80211_setup_htop(ni, htop + 2, htop[1], 0);
    2318           0 :         ieee80211_ht_negotiate(ic, ni);
    2319             : 
    2320             :         /* Hop into 11n mode after associating to an HT AP in a non-11n mode. */
    2321           0 :         if (ni->ni_flags & IEEE80211_NODE_HT)
    2322           0 :                 ieee80211_setmode(ic, IEEE80211_MODE_11N);
    2323             :         else
    2324           0 :                 ieee80211_setmode(ic, ieee80211_chan2mode(ic, ni->ni_chan));
    2325             :         /*
    2326             :          * Reset the erp state (mostly the slot time) now that
    2327             :          * our operating mode has been nailed down.
    2328             :          */
    2329           0 :         ieee80211_reset_erp(ic);
    2330             : 
    2331             :         /*
    2332             :          * Configure state now that we are associated.
    2333             :          */
    2334           0 :         if (ic->ic_curmode == IEEE80211_MODE_11A ||
    2335           0 :             (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
    2336           0 :                 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
    2337             :         else
    2338           0 :                 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
    2339             : 
    2340           0 :         ieee80211_set_shortslottime(ic,
    2341           0 :             ic->ic_curmode == IEEE80211_MODE_11A ||
    2342           0 :             (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
    2343             :         /*
    2344             :          * Honor ERP protection.
    2345             :          */
    2346           0 :         if ((ic->ic_curmode == IEEE80211_MODE_11G ||
    2347           0 :             (ic->ic_curmode == IEEE80211_MODE_11N &&
    2348           0 :             IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))) &&
    2349           0 :             (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
    2350           0 :                 ic->ic_flags |= IEEE80211_F_USEPROT;
    2351             :         else
    2352           0 :                 ic->ic_flags &= ~IEEE80211_F_USEPROT;
    2353             :         /*
    2354             :          * If not an RSNA, mark the port as valid, otherwise wait for
    2355             :          * 802.1X authentication and 4-way handshake to complete..
    2356             :          */
    2357           0 :         if (ic->ic_flags & IEEE80211_F_RSNON) {
    2358             :                 /* XXX ic->ic_mgt_timer = 5; */
    2359           0 :                 ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART;
    2360           0 :         } else if (ic->ic_flags & IEEE80211_F_WEPON)
    2361           0 :                 ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
    2362             : 
    2363           0 :         ieee80211_new_state(ic, IEEE80211_S_RUN,
    2364             :             IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
    2365           0 : }
    2366             : 
    2367             : /*-
    2368             :  * Deauthentication frame format:
    2369             :  * [2] Reason code
    2370             :  */
    2371             : void
    2372           0 : ieee80211_recv_deauth(struct ieee80211com *ic, struct mbuf *m,
    2373             :     struct ieee80211_node *ni)
    2374             : {
    2375             :         const struct ieee80211_frame *wh;
    2376             :         const u_int8_t *frm;
    2377             :         u_int16_t reason;
    2378             : 
    2379             :         /* make sure all mandatory fixed fields are present */
    2380           0 :         if (m->m_len < sizeof(*wh) + 2) {
    2381             :                 DPRINTF(("frame too short\n"));
    2382           0 :                 return;
    2383             :         }
    2384           0 :         wh = mtod(m, struct ieee80211_frame *);
    2385           0 :         frm = (const u_int8_t *)&wh[1];
    2386             : 
    2387           0 :         reason = LE_READ_2(frm);
    2388             : 
    2389           0 :         ic->ic_stats.is_rx_deauth++;
    2390           0 :         switch (ic->ic_opmode) {
    2391             :         case IEEE80211_M_STA: {
    2392           0 :                 int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
    2393           0 :                     ic->ic_state == IEEE80211_S_RUN);
    2394           0 :                 if (!bgscan) /* ignore deauth during bgscan */
    2395           0 :                         ieee80211_new_state(ic, IEEE80211_S_AUTH,
    2396             :                             IEEE80211_FC0_SUBTYPE_DEAUTH);
    2397             :                 }
    2398           0 :                 break;
    2399             : #ifndef IEEE80211_STA_ONLY
    2400             :         case IEEE80211_M_HOSTAP:
    2401           0 :                 if (ni != ic->ic_bss) {
    2402           0 :                         if (ic->ic_if.if_flags & IFF_DEBUG)
    2403           0 :                                 printf("%s: station %s deauthenticated "
    2404             :                                     "by peer (reason %d)\n",
    2405           0 :                                     ic->ic_if.if_xname,
    2406           0 :                                     ether_sprintf(ni->ni_macaddr),
    2407           0 :                                     reason);
    2408           0 :                         ieee80211_node_leave(ic, ni);
    2409           0 :                 }
    2410             :                 break;
    2411             : #endif
    2412             :         default:
    2413             :                 break;
    2414             :         }
    2415           0 : }
    2416             : 
    2417             : /*-
    2418             :  * Disassociation frame format:
    2419             :  * [2] Reason code
    2420             :  */
    2421             : void
    2422           0 : ieee80211_recv_disassoc(struct ieee80211com *ic, struct mbuf *m,
    2423             :     struct ieee80211_node *ni)
    2424             : {
    2425             :         const struct ieee80211_frame *wh;
    2426             :         const u_int8_t *frm;
    2427             :         u_int16_t reason;
    2428             : 
    2429             :         /* make sure all mandatory fixed fields are present */
    2430           0 :         if (m->m_len < sizeof(*wh) + 2) {
    2431             :                 DPRINTF(("frame too short\n"));
    2432           0 :                 return;
    2433             :         }
    2434           0 :         wh = mtod(m, struct ieee80211_frame *);
    2435           0 :         frm = (const u_int8_t *)&wh[1];
    2436             : 
    2437           0 :         reason = LE_READ_2(frm);
    2438             : 
    2439           0 :         ic->ic_stats.is_rx_disassoc++;
    2440           0 :         switch (ic->ic_opmode) {
    2441             :         case IEEE80211_M_STA: {
    2442           0 :                 int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
    2443           0 :                     ic->ic_state == IEEE80211_S_RUN);
    2444           0 :                 if (!bgscan) /* ignore disassoc during bgscan */
    2445           0 :                         ieee80211_new_state(ic, IEEE80211_S_ASSOC,
    2446             :                             IEEE80211_FC0_SUBTYPE_DISASSOC);
    2447             :                 }
    2448           0 :                 break;
    2449             : #ifndef IEEE80211_STA_ONLY
    2450             :         case IEEE80211_M_HOSTAP:
    2451           0 :                 if (ni != ic->ic_bss) {
    2452           0 :                         if (ic->ic_if.if_flags & IFF_DEBUG)
    2453           0 :                                 printf("%s: station %s disassociated "
    2454             :                                     "by peer (reason %d)\n",
    2455           0 :                                     ic->ic_if.if_xname,
    2456           0 :                                     ether_sprintf(ni->ni_macaddr),
    2457           0 :                                     reason);
    2458           0 :                         ieee80211_node_leave(ic, ni);
    2459           0 :                 }
    2460             :                 break;
    2461             : #endif
    2462             :         default:
    2463             :                 break;
    2464             :         }
    2465           0 : }
    2466             : 
    2467             : /*-
    2468             :  * ADDBA Request frame format:
    2469             :  * [1] Category
    2470             :  * [1] Action
    2471             :  * [1] Dialog Token
    2472             :  * [2] Block Ack Parameter Set
    2473             :  * [2] Block Ack Timeout Value
    2474             :  * [2] Block Ack Starting Sequence Control
    2475             :  */
    2476             : void
    2477           0 : ieee80211_recv_addba_req(struct ieee80211com *ic, struct mbuf *m,
    2478             :     struct ieee80211_node *ni)
    2479             : {
    2480             :         const struct ieee80211_frame *wh;
    2481             :         const u_int8_t *frm;
    2482             :         struct ieee80211_rx_ba *ba;
    2483             :         u_int16_t params, ssn, bufsz, timeout;
    2484             :         u_int8_t token, tid;
    2485             :         int err = 0;
    2486             : 
    2487           0 :         if (!(ni->ni_flags & IEEE80211_NODE_HT)) {
    2488             :                 DPRINTF(("received ADDBA req from non-HT STA %s\n",
    2489             :                     ether_sprintf(ni->ni_macaddr)));
    2490           0 :                 return;
    2491             :         }
    2492           0 :         if (m->m_len < sizeof(*wh) + 9) {
    2493             :                 DPRINTF(("frame too short\n"));
    2494           0 :                 return;
    2495             :         }
    2496             :         /* MLME-ADDBA.indication */
    2497           0 :         wh = mtod(m, struct ieee80211_frame *);
    2498           0 :         frm = (const u_int8_t *)&wh[1];
    2499             : 
    2500           0 :         token = frm[2];
    2501           0 :         params = LE_READ_2(&frm[3]);
    2502           0 :         tid = ((params & IEEE80211_ADDBA_TID_MASK) >>
    2503             :             IEEE80211_ADDBA_TID_SHIFT);
    2504           0 :         bufsz = (params & IEEE80211_ADDBA_BUFSZ_MASK) >>
    2505             :             IEEE80211_ADDBA_BUFSZ_SHIFT;
    2506           0 :         timeout = LE_READ_2(&frm[5]);
    2507           0 :         ssn = LE_READ_2(&frm[7]) >> 4;
    2508             : 
    2509           0 :         ba = &ni->ni_rx_ba[tid];
    2510             :         /* check if we already have a Block Ack agreement for this RA/TID */
    2511           0 :         if (ba->ba_state == IEEE80211_BA_AGREED) {
    2512             :                 /* XXX should we update the timeout value? */
    2513             :                 /* reset Block Ack inactivity timer */
    2514           0 :                 if (ba->ba_timeout_val != 0)
    2515           0 :                         timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
    2516             : 
    2517             :                 /* check if it's a Protected Block Ack agreement */
    2518           0 :                 if (!(ni->ni_flags & IEEE80211_NODE_MFP) ||
    2519           0 :                     !(ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC))
    2520           0 :                         return; /* not a PBAC, ignore */
    2521             : 
    2522             :                 /* PBAC: treat the ADDBA Request like a BlockAckReq */
    2523           0 :                 if (SEQ_LT(ba->ba_winstart, ssn))
    2524           0 :                         ieee80211_ba_move_window(ic, ni, tid, ssn);
    2525           0 :                 return;
    2526             :         }
    2527             : 
    2528             :         /* if PBAC required but RA does not support it, refuse request */
    2529           0 :         if ((ic->ic_flags & IEEE80211_F_PBAR) &&
    2530           0 :             (!(ni->ni_flags & IEEE80211_NODE_MFP) ||
    2531           0 :              !(ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC)))
    2532             :                 goto refuse;
    2533             :         /*
    2534             :          * If the TID for which the Block Ack agreement is requested is
    2535             :          * configured with a no-ACK policy, refuse the agreement.
    2536             :          */
    2537           0 :         if (ic->ic_tid_noack & (1 << tid))
    2538             :                 goto refuse;
    2539             : 
    2540             :         /* check that we support the requested Block Ack Policy */
    2541           0 :         if (!(ic->ic_htcaps & IEEE80211_HTCAP_DELAYEDBA) &&
    2542           0 :             !(params & IEEE80211_ADDBA_BA_POLICY))
    2543             :                 goto refuse;
    2544             : 
    2545             :         /* setup Block Ack agreement */
    2546           0 :         ba->ba_state = IEEE80211_BA_INIT;
    2547           0 :         ba->ba_timeout_val = timeout * IEEE80211_DUR_TU;
    2548           0 :         ba->ba_ni = ni;
    2549           0 :         ba->ba_token = token;
    2550           0 :         timeout_set(&ba->ba_to, ieee80211_rx_ba_timeout, ba);
    2551           0 :         timeout_set(&ba->ba_gap_to, ieee80211_input_ba_gap_timeout, ba);
    2552           0 :         ba->ba_winsize = bufsz;
    2553           0 :         if (ba->ba_winsize == 0 || ba->ba_winsize > IEEE80211_BA_MAX_WINSZ)
    2554           0 :                 ba->ba_winsize = IEEE80211_BA_MAX_WINSZ;
    2555           0 :         ba->ba_params = (params & IEEE80211_ADDBA_BA_POLICY);
    2556           0 :         ba->ba_params |= ((ba->ba_winsize << IEEE80211_ADDBA_BUFSZ_SHIFT) |
    2557           0 :             (tid << IEEE80211_ADDBA_TID_SHIFT) | IEEE80211_ADDBA_AMSDU);
    2558           0 :         ba->ba_winstart = ssn;
    2559           0 :         ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
    2560             :         /* allocate and setup our reordering buffer */
    2561           0 :         ba->ba_buf = malloc(IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf),
    2562             :             M_DEVBUF, M_NOWAIT | M_ZERO);
    2563           0 :         if (ba->ba_buf == NULL)
    2564             :                 goto refuse;
    2565             : 
    2566           0 :         ba->ba_head = 0;
    2567             : 
    2568             :         /* notify drivers of this new Block Ack agreement */
    2569           0 :         if (ic->ic_ampdu_rx_start != NULL)
    2570           0 :                 err = ic->ic_ampdu_rx_start(ic, ni, tid);
    2571           0 :         if (err == EBUSY) {
    2572             :                 /* driver will accept or refuse agreement when done */
    2573           0 :                 return;
    2574           0 :         } else if (err) {
    2575             :                 /* driver failed to setup, rollback */
    2576           0 :                 ieee80211_addba_req_refuse(ic, ni, tid);
    2577           0 :         } else
    2578           0 :                 ieee80211_addba_req_accept(ic, ni, tid);
    2579           0 :         return;
    2580             : 
    2581             :  refuse:
    2582             :         /* MLME-ADDBA.response */
    2583           0 :         IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
    2584             :             IEEE80211_ACTION_ADDBA_RESP,
    2585             :             IEEE80211_STATUS_REFUSED << 16 | token << 8 | tid);
    2586           0 : }
    2587             : 
    2588             : void
    2589           0 : ieee80211_addba_req_accept(struct ieee80211com *ic, struct ieee80211_node *ni,
    2590             :     uint8_t tid)
    2591             : {
    2592           0 :         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
    2593             : 
    2594           0 :         ba->ba_state = IEEE80211_BA_AGREED;
    2595           0 :         ic->ic_stats.is_ht_rx_ba_agreements++;
    2596             :         /* start Block Ack inactivity timer */
    2597           0 :         if (ba->ba_timeout_val != 0)
    2598           0 :                 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
    2599             : 
    2600             :         /* MLME-ADDBA.response */
    2601           0 :         IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
    2602             :             IEEE80211_ACTION_ADDBA_RESP,
    2603             :             IEEE80211_STATUS_SUCCESS << 16 | ba->ba_token << 8 | tid);
    2604           0 : }
    2605             : 
    2606             : void
    2607           0 : ieee80211_addba_req_refuse(struct ieee80211com *ic, struct ieee80211_node *ni,
    2608             :     uint8_t tid)
    2609             : {
    2610           0 :         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
    2611             : 
    2612           0 :         free(ba->ba_buf, M_DEVBUF,
    2613             :             IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf));
    2614           0 :         ba->ba_buf = NULL;
    2615             : 
    2616             :         /* MLME-ADDBA.response */
    2617           0 :         IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
    2618             :             IEEE80211_ACTION_ADDBA_RESP,
    2619             :             IEEE80211_STATUS_REFUSED << 16 | ba->ba_token << 8 | tid);
    2620           0 : }
    2621             : 
    2622             : /*-
    2623             :  * ADDBA Response frame format:
    2624             :  * [1] Category
    2625             :  * [1] Action
    2626             :  * [1] Dialog Token
    2627             :  * [2] Status Code
    2628             :  * [2] Block Ack Parameter Set
    2629             :  * [2] Block Ack Timeout Value
    2630             :  */
    2631             : void
    2632           0 : ieee80211_recv_addba_resp(struct ieee80211com *ic, struct mbuf *m,
    2633             :     struct ieee80211_node *ni)
    2634             : {
    2635             :         const struct ieee80211_frame *wh;
    2636             :         const u_int8_t *frm;
    2637             :         struct ieee80211_tx_ba *ba;
    2638             :         u_int16_t status, params, bufsz, timeout;
    2639             :         u_int8_t token, tid;
    2640             : 
    2641           0 :         if (m->m_len < sizeof(*wh) + 9) {
    2642             :                 DPRINTF(("frame too short\n"));
    2643           0 :                 return;
    2644             :         }
    2645           0 :         wh = mtod(m, struct ieee80211_frame *);
    2646           0 :         frm = (const u_int8_t *)&wh[1];
    2647             : 
    2648           0 :         token = frm[2];
    2649           0 :         status = LE_READ_2(&frm[3]);
    2650           0 :         params = LE_READ_2(&frm[5]);
    2651           0 :         tid = (params >> 2) & 0xf;
    2652           0 :         bufsz = (params >> 6) & 0x3ff;
    2653           0 :         timeout = LE_READ_2(&frm[7]);
    2654             : 
    2655             :         DPRINTF(("received ADDBA resp from %s, TID %d, status %d\n",
    2656             :             ether_sprintf(ni->ni_macaddr), tid, status));
    2657             : 
    2658             :         /*
    2659             :          * Ignore if no ADDBA request has been sent for this RA/TID or
    2660             :          * if we already have a Block Ack agreement.
    2661             :          */
    2662           0 :         ba = &ni->ni_tx_ba[tid];
    2663           0 :         if (ba->ba_state != IEEE80211_BA_REQUESTED) {
    2664             :                 DPRINTF(("no matching ADDBA req found\n"));
    2665           0 :                 return;
    2666             :         }
    2667           0 :         if (token != ba->ba_token) {
    2668             :                 DPRINTF(("ignoring ADDBA resp from %s: token %x!=%x\n",
    2669             :                     ether_sprintf(ni->ni_macaddr), token, ba->ba_token));
    2670           0 :                 return;
    2671             :         }
    2672             :         /* we got an ADDBA Response matching our request, stop timeout */
    2673           0 :         timeout_del(&ba->ba_to);
    2674             : 
    2675           0 :         if (status != IEEE80211_STATUS_SUCCESS) {
    2676             :                 /* MLME-ADDBA.confirm(Failure) */
    2677           0 :                 ba->ba_state = IEEE80211_BA_INIT;
    2678           0 :                 return;
    2679             :         }
    2680             :         /* MLME-ADDBA.confirm(Success) */
    2681           0 :         ba->ba_state = IEEE80211_BA_AGREED;
    2682           0 :         ic->ic_stats.is_ht_tx_ba_agreements++;
    2683             : 
    2684             :         /* notify drivers of this new Block Ack agreement */
    2685           0 :         if (ic->ic_ampdu_tx_start != NULL)
    2686           0 :                 (void)ic->ic_ampdu_tx_start(ic, ni, tid);
    2687             : 
    2688             :         /* start Block Ack inactivity timeout */
    2689           0 :         if (ba->ba_timeout_val != 0)
    2690           0 :                 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
    2691           0 : }
    2692             : 
    2693             : /*-
    2694             :  * DELBA frame format:
    2695             :  * [1] Category
    2696             :  * [1] Action
    2697             :  * [2] DELBA Parameter Set
    2698             :  * [2] Reason Code
    2699             :  */
    2700             : void
    2701           0 : ieee80211_recv_delba(struct ieee80211com *ic, struct mbuf *m,
    2702             :     struct ieee80211_node *ni)
    2703             : {
    2704             :         const struct ieee80211_frame *wh;
    2705             :         const u_int8_t *frm;
    2706             :         u_int16_t params, reason;
    2707             :         u_int8_t tid;
    2708             :         int i;
    2709             : 
    2710           0 :         if (m->m_len < sizeof(*wh) + 6) {
    2711             :                 DPRINTF(("frame too short\n"));
    2712           0 :                 return;
    2713             :         }
    2714           0 :         wh = mtod(m, struct ieee80211_frame *);
    2715           0 :         frm = (const u_int8_t *)&wh[1];
    2716             : 
    2717           0 :         params = LE_READ_2(&frm[2]);
    2718           0 :         reason = LE_READ_2(&frm[4]);
    2719           0 :         tid = params >> 12;
    2720             : 
    2721             :         DPRINTF(("received DELBA from %s, TID %d, reason %d\n",
    2722             :             ether_sprintf(ni->ni_macaddr), tid, reason));
    2723             : 
    2724           0 :         if (params & IEEE80211_DELBA_INITIATOR) {
    2725             :                 /* MLME-DELBA.indication(Originator) */
    2726           0 :                 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
    2727             : 
    2728           0 :                 if (ba->ba_state != IEEE80211_BA_AGREED) {
    2729             :                         DPRINTF(("no matching Block Ack agreement\n"));
    2730           0 :                         return;
    2731             :                 }
    2732             :                 /* notify drivers of the end of the Block Ack agreement */
    2733           0 :                 if (ic->ic_ampdu_rx_stop != NULL)
    2734           0 :                         ic->ic_ampdu_rx_stop(ic, ni, tid);
    2735             : 
    2736           0 :                 ba->ba_state = IEEE80211_BA_INIT;
    2737             :                 /* stop Block Ack inactivity timer */
    2738           0 :                 timeout_del(&ba->ba_to);
    2739           0 :                 timeout_del(&ba->ba_gap_to);
    2740             : 
    2741           0 :                 if (ba->ba_buf != NULL) {
    2742             :                         /* free all MSDUs stored in reordering buffer */
    2743           0 :                         for (i = 0; i < IEEE80211_BA_MAX_WINSZ; i++)
    2744           0 :                                 m_freem(ba->ba_buf[i].m);
    2745             :                         /* free reordering buffer */
    2746           0 :                         free(ba->ba_buf, M_DEVBUF,
    2747             :                             IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf));
    2748           0 :                         ba->ba_buf = NULL;
    2749           0 :                 }
    2750           0 :         } else {
    2751             :                 /* MLME-DELBA.indication(Recipient) */
    2752           0 :                 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
    2753             : 
    2754           0 :                 if (ba->ba_state != IEEE80211_BA_AGREED) {
    2755             :                         DPRINTF(("no matching Block Ack agreement\n"));
    2756           0 :                         return;
    2757             :                 }
    2758             :                 /* notify drivers of the end of the Block Ack agreement */
    2759           0 :                 if (ic->ic_ampdu_tx_stop != NULL)
    2760           0 :                         ic->ic_ampdu_tx_stop(ic, ni, tid);
    2761             : 
    2762           0 :                 ba->ba_state = IEEE80211_BA_INIT;
    2763             :                 /* stop Block Ack inactivity timer */
    2764           0 :                 timeout_del(&ba->ba_to);
    2765           0 :         }
    2766           0 : }
    2767             : 
    2768             : /*-
    2769             :  * SA Query Request frame format:
    2770             :  * [1] Category
    2771             :  * [1] Action
    2772             :  * [2] Transaction Identifier
    2773             :  */
    2774             : void
    2775           0 : ieee80211_recv_sa_query_req(struct ieee80211com *ic, struct mbuf *m,
    2776             :     struct ieee80211_node *ni)
    2777             : {
    2778             :         const struct ieee80211_frame *wh;
    2779             :         const u_int8_t *frm;
    2780             : 
    2781           0 :         if (ic->ic_opmode != IEEE80211_M_STA ||
    2782           0 :             !(ni->ni_flags & IEEE80211_NODE_MFP)) {
    2783             :                 DPRINTF(("unexpected SA Query req from %s\n",
    2784             :                     ether_sprintf(ni->ni_macaddr)));
    2785           0 :                 return;
    2786             :         }
    2787           0 :         if (m->m_len < sizeof(*wh) + 4) {
    2788             :                 DPRINTF(("frame too short\n"));
    2789           0 :                 return;
    2790             :         }
    2791           0 :         wh = mtod(m, struct ieee80211_frame *);
    2792           0 :         frm = (const u_int8_t *)&wh[1];
    2793             : 
    2794             :         /* MLME-SAQuery.indication */
    2795             : 
    2796             :         /* save Transaction Identifier for SA Query Response */
    2797           0 :         ni->ni_sa_query_trid = LE_READ_2(&frm[2]);
    2798             : 
    2799             :         /* MLME-SAQuery.response */
    2800           0 :         IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_SA_QUERY,
    2801             :             IEEE80211_ACTION_SA_QUERY_RESP, 0);
    2802           0 : }
    2803             : 
    2804             : #ifndef IEEE80211_STA_ONLY
    2805             : /*-
    2806             :  * SA Query Response frame format:
    2807             :  * [1] Category
    2808             :  * [1] Action
    2809             :  * [2] Transaction Identifier
    2810             :  */
    2811             : void
    2812           0 : ieee80211_recv_sa_query_resp(struct ieee80211com *ic, struct mbuf *m,
    2813             :     struct ieee80211_node *ni)
    2814             : {
    2815             :         const struct ieee80211_frame *wh;
    2816             :         const u_int8_t *frm;
    2817             : 
    2818             :         /* ignore if we're not engaged in an SA Query with that STA */
    2819           0 :         if (!(ni->ni_flags & IEEE80211_NODE_SA_QUERY)) {
    2820             :                 DPRINTF(("unexpected SA Query resp from %s\n",
    2821             :                     ether_sprintf(ni->ni_macaddr)));
    2822           0 :                 return;
    2823             :         }
    2824           0 :         if (m->m_len < sizeof(*wh) + 4) {
    2825             :                 DPRINTF(("frame too short\n"));
    2826           0 :                 return;
    2827             :         }
    2828           0 :         wh = mtod(m, struct ieee80211_frame *);
    2829           0 :         frm = (const u_int8_t *)&wh[1];
    2830             : 
    2831             :         /* check that Transaction Identifier matches */
    2832           0 :         if (ni->ni_sa_query_trid != LE_READ_2(&frm[2])) {
    2833             :                 DPRINTF(("transaction identifier does not match\n"));
    2834           0 :                 return;
    2835             :         }
    2836             :         /* MLME-SAQuery.confirm */
    2837           0 :         timeout_del(&ni->ni_sa_query_to);
    2838           0 :         ni->ni_flags &= ~IEEE80211_NODE_SA_QUERY;
    2839           0 : }
    2840             : #endif
    2841             : 
    2842             : /*-
    2843             :  * Action frame format:
    2844             :  * [1] Category
    2845             :  * [1] Action
    2846             :  */
    2847             : void
    2848           0 : ieee80211_recv_action(struct ieee80211com *ic, struct mbuf *m,
    2849             :     struct ieee80211_node *ni)
    2850             : {
    2851             :         const struct ieee80211_frame *wh;
    2852             :         const u_int8_t *frm;
    2853             : 
    2854           0 :         if (m->m_len < sizeof(*wh) + 2) {
    2855             :                 DPRINTF(("frame too short\n"));
    2856           0 :                 return;
    2857             :         }
    2858           0 :         wh = mtod(m, struct ieee80211_frame *);
    2859           0 :         frm = (const u_int8_t *)&wh[1];
    2860             : 
    2861           0 :         switch (frm[0]) {
    2862             :         case IEEE80211_CATEG_BA:
    2863           0 :                 switch (frm[1]) {
    2864             :                 case IEEE80211_ACTION_ADDBA_REQ:
    2865           0 :                         ieee80211_recv_addba_req(ic, m, ni);
    2866           0 :                         break;
    2867             :                 case IEEE80211_ACTION_ADDBA_RESP:
    2868           0 :                         ieee80211_recv_addba_resp(ic, m, ni);
    2869           0 :                         break;
    2870             :                 case IEEE80211_ACTION_DELBA:
    2871           0 :                         ieee80211_recv_delba(ic, m, ni);
    2872           0 :                         break;
    2873             :                 }
    2874             :                 break;
    2875             :         case IEEE80211_CATEG_SA_QUERY:
    2876           0 :                 switch (frm[1]) {
    2877             :                 case IEEE80211_ACTION_SA_QUERY_REQ:
    2878           0 :                         ieee80211_recv_sa_query_req(ic, m, ni);
    2879           0 :                         break;
    2880             : #ifndef IEEE80211_STA_ONLY
    2881             :                 case IEEE80211_ACTION_SA_QUERY_RESP:
    2882           0 :                         ieee80211_recv_sa_query_resp(ic, m, ni);
    2883           0 :                         break;
    2884             : #endif
    2885             :                 }
    2886             :                 break;
    2887             :         default:
    2888             :                 DPRINTF(("action frame category %d not handled\n", frm[0]));
    2889             :                 break;
    2890             :         }
    2891           0 : }
    2892             : 
    2893             : void
    2894           0 : ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
    2895             :     struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int subtype)
    2896             : {
    2897           0 :         switch (subtype) {
    2898             :         case IEEE80211_FC0_SUBTYPE_BEACON:
    2899           0 :                 ieee80211_recv_probe_resp(ic, m, ni, rxi, 0);
    2900           0 :                 break;
    2901             :         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
    2902           0 :                 ieee80211_recv_probe_resp(ic, m, ni, rxi, 1);
    2903           0 :                 break;
    2904             : #ifndef IEEE80211_STA_ONLY
    2905             :         case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
    2906           0 :                 ieee80211_recv_probe_req(ic, m, ni, rxi);
    2907           0 :                 break;
    2908             : #endif
    2909             :         case IEEE80211_FC0_SUBTYPE_AUTH:
    2910           0 :                 ieee80211_recv_auth(ic, m, ni, rxi);
    2911           0 :                 break;
    2912             : #ifndef IEEE80211_STA_ONLY
    2913             :         case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
    2914           0 :                 ieee80211_recv_assoc_req(ic, m, ni, rxi, 0);
    2915           0 :                 break;
    2916             :         case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
    2917           0 :                 ieee80211_recv_assoc_req(ic, m, ni, rxi, 1);
    2918           0 :                 break;
    2919             : #endif
    2920             :         case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
    2921           0 :                 ieee80211_recv_assoc_resp(ic, m, ni, 0);
    2922           0 :                 break;
    2923             :         case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
    2924           0 :                 ieee80211_recv_assoc_resp(ic, m, ni, 1);
    2925           0 :                 break;
    2926             :         case IEEE80211_FC0_SUBTYPE_DEAUTH:
    2927           0 :                 ieee80211_recv_deauth(ic, m, ni);
    2928           0 :                 break;
    2929             :         case IEEE80211_FC0_SUBTYPE_DISASSOC:
    2930           0 :                 ieee80211_recv_disassoc(ic, m, ni);
    2931           0 :                 break;
    2932             :         case IEEE80211_FC0_SUBTYPE_ACTION:
    2933           0 :                 ieee80211_recv_action(ic, m, ni);
    2934           0 :                 break;
    2935             :         default:
    2936             :                 DPRINTF(("mgmt frame with subtype 0x%x not handled\n",
    2937             :                     subtype));
    2938           0 :                 ic->ic_stats.is_rx_badsubtype++;
    2939           0 :                 break;
    2940             :         }
    2941           0 : }
    2942             : 
    2943             : #ifndef IEEE80211_STA_ONLY
    2944             : /*
    2945             :  * Process an incoming PS-Poll control frame (see 11.2).
    2946             :  */
    2947             : void
    2948           0 : ieee80211_recv_pspoll(struct ieee80211com *ic, struct mbuf *m,
    2949             :     struct ieee80211_node *ni)
    2950             : {
    2951           0 :         struct ifnet *ifp = &ic->ic_if;
    2952             :         struct ieee80211_frame_pspoll *psp;
    2953             :         struct ieee80211_frame *wh;
    2954             :         u_int16_t aid;
    2955             : 
    2956           0 :         if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
    2957           0 :             !(ic->ic_caps & IEEE80211_C_APPMGT) ||
    2958           0 :             ni->ni_state != IEEE80211_STA_ASSOC)
    2959           0 :                 return;
    2960             : 
    2961           0 :         if (m->m_len < sizeof(*psp)) {
    2962             :                 DPRINTF(("frame too short, len %u\n", m->m_len));
    2963           0 :                 ic->ic_stats.is_rx_tooshort++;
    2964           0 :                 return;
    2965             :         }
    2966           0 :         psp = mtod(m, struct ieee80211_frame_pspoll *);
    2967           0 :         if (!IEEE80211_ADDR_EQ(psp->i_bssid, ic->ic_bss->ni_bssid)) {
    2968             :                 DPRINTF(("discard pspoll frame to BSS %s\n",
    2969             :                     ether_sprintf(psp->i_bssid)));
    2970           0 :                 ic->ic_stats.is_rx_wrongbss++;
    2971           0 :                 return;
    2972             :         }
    2973           0 :         aid = letoh16(*(u_int16_t *)psp->i_aid);
    2974           0 :         if (aid != ni->ni_associd) {
    2975             :                 DPRINTF(("invalid pspoll aid %x from %s\n", aid,
    2976             :                     ether_sprintf(psp->i_ta)));
    2977           0 :                 return;
    2978             :         }
    2979             : 
    2980             :         /* take the first queued frame and put it out.. */
    2981           0 :         m = mq_dequeue(&ni->ni_savedq);
    2982           0 :         if (m == NULL)
    2983           0 :                 return;
    2984           0 :         if (mq_empty(&ni->ni_savedq)) {
    2985             :                 /* last queued frame, turn off the TIM bit */
    2986           0 :                 (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
    2987           0 :         } else {
    2988             :                 /* more queued frames, set the more data bit */
    2989           0 :                 wh = mtod(m, struct ieee80211_frame *);
    2990           0 :                 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
    2991             :         }
    2992           0 :         mq_enqueue(&ic->ic_pwrsaveq, m);
    2993           0 :         if_start(ifp);
    2994           0 : }
    2995             : #endif  /* IEEE80211_STA_ONLY */
    2996             : 
    2997             : /*
    2998             :  * Process an incoming BlockAckReq control frame (see 7.2.1.7).
    2999             :  */
    3000             : void
    3001           0 : ieee80211_recv_bar(struct ieee80211com *ic, struct mbuf *m,
    3002             :     struct ieee80211_node *ni)
    3003             : {
    3004             :         const struct ieee80211_frame_min *wh;
    3005             :         const u_int8_t *frm;
    3006             :         u_int16_t ctl, ssn;
    3007             :         u_int8_t tid, ntids;
    3008             : 
    3009           0 :         if (!(ni->ni_flags & IEEE80211_NODE_HT)) {
    3010             :                 DPRINTF(("received BlockAckReq from non-HT STA %s\n",
    3011             :                     ether_sprintf(ni->ni_macaddr)));
    3012           0 :                 return;
    3013             :         }
    3014           0 :         if (m->m_len < sizeof(*wh) + 4) {
    3015             :                 DPRINTF(("frame too short\n"));
    3016           0 :                 return;
    3017             :         }
    3018           0 :         wh = mtod(m, struct ieee80211_frame_min *);
    3019           0 :         frm = (const u_int8_t *)&wh[1];
    3020             : 
    3021             :         /* read BlockAckReq Control field */
    3022           0 :         ctl = LE_READ_2(&frm[0]);
    3023           0 :         tid = ctl >> 12;
    3024             : 
    3025             :         /* determine BlockAckReq frame variant */
    3026           0 :         if (ctl & IEEE80211_BA_MULTI_TID) {
    3027             :                 /* Multi-TID BlockAckReq variant (PSMP only) */
    3028           0 :                 ntids = tid + 1;
    3029             : 
    3030           0 :                 if (m->m_len < sizeof(*wh) + 2 + 4 * ntids) {
    3031             :                         DPRINTF(("MTBAR frame too short\n"));
    3032           0 :                         return;
    3033             :                 }
    3034           0 :                 frm += 2;       /* skip BlockAckReq Control field */
    3035           0 :                 while (ntids-- > 0) {
    3036             :                         /* read MTBAR Information field */
    3037           0 :                         tid = LE_READ_2(&frm[0]) >> 12;
    3038           0 :                         ssn = LE_READ_2(&frm[2]) >> 4;
    3039           0 :                         ieee80211_bar_tid(ic, ni, tid, ssn);
    3040           0 :                         frm += 4;
    3041             :                 }
    3042             :         } else {
    3043             :                 /* Basic or Compressed BlockAckReq variants */
    3044           0 :                 ssn = LE_READ_2(&frm[2]) >> 4;
    3045           0 :                 ieee80211_bar_tid(ic, ni, tid, ssn);
    3046             :         }
    3047           0 : }
    3048             : 
    3049             : /*
    3050             :  * Process a BlockAckReq for a specific TID (see 9.10.7.6.3).
    3051             :  * This is the common back-end for all BlockAckReq frame variants.
    3052             :  */
    3053             : void
    3054           0 : ieee80211_bar_tid(struct ieee80211com *ic, struct ieee80211_node *ni,
    3055             :     u_int8_t tid, u_int16_t ssn)
    3056             : {
    3057           0 :         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
    3058             : 
    3059             :         /* check if we have a Block Ack agreement for RA/TID */
    3060           0 :         if (ba->ba_state != IEEE80211_BA_AGREED) {
    3061             :                 /* XXX not sure in PBAC case */
    3062             :                 /* send a DELBA with reason code UNKNOWN-BA */
    3063           0 :                 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
    3064             :                     IEEE80211_ACTION_DELBA,
    3065             :                     IEEE80211_REASON_SETUP_REQUIRED << 16 | tid);
    3066           0 :                 return;
    3067             :         }
    3068             :         /* check if it is a Protected Block Ack agreement */
    3069           0 :         if ((ni->ni_flags & IEEE80211_NODE_MFP) &&
    3070           0 :             (ni->ni_rsncaps & IEEE80211_RSNCAP_PBAC)) {
    3071             :                 /* ADDBA Requests must be used in PBAC case */
    3072           0 :                 if (SEQ_LT(ssn, ba->ba_winstart) ||
    3073           0 :                     SEQ_LT(ba->ba_winend, ssn))
    3074           0 :                         ic->ic_stats.is_pbac_errs++;
    3075           0 :                 return; /* PBAC, do not move window */
    3076             :         }
    3077             :         /* reset Block Ack inactivity timer */
    3078           0 :         if (ba->ba_timeout_val != 0)
    3079           0 :                 timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
    3080             : 
    3081           0 :         if (SEQ_LT(ba->ba_winstart, ssn))
    3082           0 :                 ieee80211_ba_move_window(ic, ni, tid, ssn);
    3083           0 : }

Generated by: LCOV version 1.13