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


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

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

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

    1 /*      $OpenBSD: ieee80211_proto.c,v 1.108 2022/03/14 15:07:24 stsp Exp $      */
    2 /*      $NetBSD: ieee80211_proto.c,v 1.8 2004/04/30 23:58:20 dyoung Exp $       */
    3 
    4 /*-
    5  * Copyright (c) 2001 Atsushi Onoe
    6  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
    7  * Copyright (c) 2008, 2009 Damien Bergamini
    8  * All rights reserved.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * IEEE 802.11 protocol support.
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/mbuf.h>
   40 #include <sys/kernel.h>
   41 #include <sys/socket.h>
   42 #include <sys/sockio.h>
   43 #include <sys/endian.h>
   44 #include <sys/errno.h>
   45 #include <sys/sysctl.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_dl.h>
   49 #include <net/if_media.h>
   50 #include <net/if_llc.h>
   51 #include <net/route.h>
   52 
   53 #include <netinet/in.h>
   54 #include <netinet/if_ether.h>
   55 
   56 #include <net80211/ieee80211_var.h>
   57 #include <net80211/ieee80211_priv.h>
   58 
   59 const char * const ieee80211_mgt_subtype_name[] = {
   60         "assoc_req",    "assoc_resp",   "reassoc_req",  "reassoc_resp",
   61         "probe_req",    "probe_resp",   "reserved#6",   "reserved#7",
   62         "beacon",       "atim",         "disassoc",     "auth",
   63         "deauth",       "action",       "action_noack", "reserved#15"
   64 };
   65 const char * const ieee80211_state_name[IEEE80211_S_MAX] = {
   66         "INIT",         /* IEEE80211_S_INIT */
   67         "SCAN",         /* IEEE80211_S_SCAN */
   68         "AUTH",         /* IEEE80211_S_AUTH */
   69         "ASSOC",        /* IEEE80211_S_ASSOC */
   70         "RUN"           /* IEEE80211_S_RUN */
   71 };
   72 const char * const ieee80211_phymode_name[] = {
   73         "auto",         /* IEEE80211_MODE_AUTO */
   74         "11a",          /* IEEE80211_MODE_11A */
   75         "11b",          /* IEEE80211_MODE_11B */
   76         "11g",          /* IEEE80211_MODE_11G */
   77         "11n",          /* IEEE80211_MODE_11N */
   78         "11ac",         /* IEEE80211_MODE_11AC */
   79 };
   80 
   81 void ieee80211_set_beacon_miss_threshold(struct ieee80211com *);
   82 int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int);
   83 
   84 void
   85 ieee80211_proto_attach(struct ifnet *ifp)
   86 {
   87         struct ieee80211com *ic = (void *)ifp;
   88 
   89         mq_init(&ic->ic_mgtq, IFQ_MAXLEN, IPL_NET);
   90         mq_init(&ic->ic_pwrsaveq, IFQ_MAXLEN, IPL_NET);
   91 
   92         ifp->if_hdrlen = sizeof(struct ieee80211_frame);
   93 
   94         ic->ic_rtsthreshold = IEEE80211_RTS_MAX;
   95         ic->ic_fragthreshold = 2346;            /* XXX not used yet */
   96         ic->ic_fixed_rate = -1;                 /* no fixed rate */
   97         ic->ic_fixed_mcs = -1;                  /* no fixed mcs */
   98         ic->ic_protmode = IEEE80211_PROT_CTSONLY;
   99 
  100         /* protocol state change handler */
  101         ic->ic_newstate = ieee80211_newstate;
  102 
  103         /* initialize management frame handlers */
  104         ic->ic_recv_mgmt = ieee80211_recv_mgmt;
  105         ic->ic_send_mgmt = ieee80211_send_mgmt;
  106 }
  107 
  108 void
  109 ieee80211_proto_detach(struct ifnet *ifp)
  110 {
  111         struct ieee80211com *ic = (void *)ifp;
  112 
  113         mq_purge(&ic->ic_mgtq);
  114         mq_purge(&ic->ic_pwrsaveq);
  115 }
  116 
  117 void
  118 ieee80211_print_essid(const u_int8_t *essid, int len)
  119 {
  120         int i;
  121         const u_int8_t *p;
  122 
  123         if (len > IEEE80211_NWID_LEN)
  124                 len = IEEE80211_NWID_LEN;
  125         /* determine printable or not */
  126         for (i = 0, p = essid; i < len; i++, p++) {
  127                 if (*p < ' ' || *p > 0x7e)
  128                         break;
  129         }
  130         if (i == len) {
  131                 printf("\"");
  132                 for (i = 0, p = essid; i < len; i++, p++)
  133                         printf("%c", *p);
  134                 printf("\"");
  135         } else {
  136                 printf("0x");
  137                 for (i = 0, p = essid; i < len; i++, p++)
  138                         printf("%02x", *p);
  139         }
  140 }
  141 
  142 #ifdef IEEE80211_DEBUG
  143 void
  144 ieee80211_dump_pkt(const u_int8_t *buf, int len, int rate, int rssi)
  145 {
  146         struct ieee80211_frame *wh;
  147         int i;
  148 
  149         wh = (struct ieee80211_frame *)buf;
  150         switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
  151         case IEEE80211_FC1_DIR_NODS:
  152                 printf("NODS %s", ether_sprintf(wh->i_addr2));
  153                 printf("->%s", ether_sprintf(wh->i_addr1));
  154                 printf("(%s)", ether_sprintf(wh->i_addr3));
  155                 break;
  156         case IEEE80211_FC1_DIR_TODS:
  157                 printf("TODS %s", ether_sprintf(wh->i_addr2));
  158                 printf("->%s", ether_sprintf(wh->i_addr3));
  159                 printf("(%s)", ether_sprintf(wh->i_addr1));
  160                 break;
  161         case IEEE80211_FC1_DIR_FROMDS:
  162                 printf("FRDS %s", ether_sprintf(wh->i_addr3));
  163                 printf("->%s", ether_sprintf(wh->i_addr1));
  164                 printf("(%s)", ether_sprintf(wh->i_addr2));
  165                 break;
  166         case IEEE80211_FC1_DIR_DSTODS:
  167                 printf("DSDS %s", ether_sprintf((u_int8_t *)&wh[1]));
  168                 printf("->%s", ether_sprintf(wh->i_addr3));
  169                 printf("(%s", ether_sprintf(wh->i_addr2));
  170                 printf("->%s)", ether_sprintf(wh->i_addr1));
  171                 break;
  172         }
  173         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
  174         case IEEE80211_FC0_TYPE_DATA:
  175                 printf(" data");
  176                 break;
  177         case IEEE80211_FC0_TYPE_MGT:
  178                 printf(" %s", ieee80211_mgt_subtype_name[
  179                     (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
  180                     >> IEEE80211_FC0_SUBTYPE_SHIFT]);
  181                 break;
  182         default:
  183                 printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
  184                 break;
  185         }
  186         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
  187                 printf(" WEP");
  188         if (rate >= 0)
  189                 printf(" %d%sM", rate / 2, (rate & 1) ? ".5" : "");
  190         if (rssi >= 0)
  191                 printf(" +%d", rssi);
  192         printf("\n");
  193         if (len > 0) {
  194                 for (i = 0; i < len; i++) {
  195                         if ((i & 1) == 0)
  196                                 printf(" ");
  197                         printf("%02x", buf[i]);
  198                 }
  199                 printf("\n");
  200         }
  201 }
  202 #endif
  203 
  204 int
  205 ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni,
  206     int flags)
  207 {
  208 #define RV(v)   ((v) & IEEE80211_RATE_VAL)
  209         int i, j, ignore, error;
  210         int okrate, badrate, fixedrate;
  211         const struct ieee80211_rateset *srs;
  212         struct ieee80211_rateset *nrs;
  213         u_int8_t r;
  214 
  215         /*
  216          * If the fixed rate check was requested but no fixed rate has been
  217          * defined then just remove the check.
  218          */
  219         if ((flags & IEEE80211_F_DOFRATE) && ic->ic_fixed_rate == -1)
  220                 flags &= ~IEEE80211_F_DOFRATE;
  221 
  222         error = 0;
  223         okrate = badrate = fixedrate = 0;
  224         srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
  225         nrs = &ni->ni_rates;
  226         for (i = 0; i < nrs->rs_nrates; ) {
  227                 ignore = 0;
  228                 if (flags & IEEE80211_F_DOSORT) {
  229                         /*
  230                          * Sort rates.
  231                          */
  232                         for (j = i + 1; j < nrs->rs_nrates; j++) {
  233                                 if (RV(nrs->rs_rates[i]) >
  234                                     RV(nrs->rs_rates[j])) {
  235                                         r = nrs->rs_rates[i];
  236                                         nrs->rs_rates[i] = nrs->rs_rates[j];
  237                                         nrs->rs_rates[j] = r;
  238                                 }
  239                         }
  240                 }
  241                 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL;
  242                 badrate = r;
  243                 if (flags & IEEE80211_F_DOFRATE) {
  244                         /*
  245                          * Check fixed rate is included.
  246                          */
  247                         if (r == RV(srs->rs_rates[ic->ic_fixed_rate]))
  248                                 fixedrate = r;
  249                 }
  250                 if (flags & IEEE80211_F_DONEGO) {
  251                         /*
  252                          * Check against supported rates.
  253                          */
  254                         for (j = 0; j < srs->rs_nrates; j++) {
  255                                 if (r == RV(srs->rs_rates[j])) {
  256                                         /*
  257                                          * Overwrite with the supported rate
  258                                          * value so any basic rate bit is set.
  259                                          * This insures that response we send
  260                                          * to stations have the necessary basic
  261                                          * rate bit set.
  262                                          */
  263                                         nrs->rs_rates[i] = srs->rs_rates[j];
  264                                         break;
  265                                 }
  266                         }
  267                         if (j == srs->rs_nrates) {
  268                                 /*
  269                                  * A rate in the node's rate set is not
  270                                  * supported.  If this is a basic rate and we
  271                                  * are operating as an AP then this is an error.
  272                                  * Otherwise we just discard/ignore the rate.
  273                                  * Note that this is important for 11b stations
  274                                  * when they want to associate with an 11g AP.
  275                                  */
  276 #ifndef IEEE80211_STA_ONLY
  277                                 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  278                                     (nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
  279                                         error++;
  280 #endif
  281                                 ignore++;
  282                         }
  283                 }
  284                 if (flags & IEEE80211_F_DODEL) {
  285                         /*
  286                          * Delete unacceptable rates.
  287                          */
  288                         if (ignore) {
  289                                 nrs->rs_nrates--;
  290                                 for (j = i; j < nrs->rs_nrates; j++)
  291                                         nrs->rs_rates[j] = nrs->rs_rates[j + 1];
  292                                 nrs->rs_rates[j] = 0;
  293                                 continue;
  294                         }
  295                 }
  296                 if (!ignore)
  297                         okrate = nrs->rs_rates[i];
  298                 i++;
  299         }
  300         if (okrate == 0 || error != 0 ||
  301             ((flags & IEEE80211_F_DOFRATE) && fixedrate == 0))
  302                 return badrate | IEEE80211_RATE_BASIC;
  303         else
  304                 return RV(okrate);
  305 #undef RV
  306 }
  307 
  308 /*
  309  * Reset 11g-related state.
  310  */
  311 void
  312 ieee80211_reset_erp(struct ieee80211com *ic)
  313 {
  314         ic->ic_flags &= ~IEEE80211_F_USEPROT;
  315 
  316         ieee80211_set_shortslottime(ic,
  317             ic->ic_curmode == IEEE80211_MODE_11A ||
  318             (ic->ic_curmode == IEEE80211_MODE_11N &&
  319             IEEE80211_IS_CHAN_5GHZ(ic->ic_ibss_chan))
  320 #ifndef IEEE80211_STA_ONLY
  321             ||
  322             ((ic->ic_curmode == IEEE80211_MODE_11G ||
  323             (ic->ic_curmode == IEEE80211_MODE_11N &&
  324             IEEE80211_IS_CHAN_2GHZ(ic->ic_ibss_chan))) &&
  325              ic->ic_opmode == IEEE80211_M_HOSTAP &&
  326              (ic->ic_caps & IEEE80211_C_SHSLOT))
  327 #endif
  328         );
  329 
  330         if (ic->ic_curmode == IEEE80211_MODE_11A ||
  331             (ic->ic_curmode == IEEE80211_MODE_11N &&
  332             IEEE80211_IS_CHAN_5GHZ(ic->ic_ibss_chan)) ||
  333             (ic->ic_caps & IEEE80211_C_SHPREAMBLE))
  334                 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
  335         else
  336                 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
  337 }
  338 
  339 /*
  340  * Set the short slot time state and notify the driver.
  341  */
  342 void
  343 ieee80211_set_shortslottime(struct ieee80211com *ic, int on)
  344 {
  345         if (on)
  346                 ic->ic_flags |= IEEE80211_F_SHSLOT;
  347         else
  348                 ic->ic_flags &= ~IEEE80211_F_SHSLOT;
  349 
  350         /* notify the driver */
  351         if (ic->ic_updateslot != NULL)
  352                 ic->ic_updateslot(ic);
  353 }
  354 
  355 /*
  356  * This function is called by the 802.1X PACP machine (via an ioctl) when
  357  * the transmit key machine (4-Way Handshake for 802.11) should run.
  358  */
  359 int
  360 ieee80211_keyrun(struct ieee80211com *ic, u_int8_t *macaddr)
  361 {
  362         struct ieee80211_node *ni = ic->ic_bss;
  363 #ifndef IEEE80211_STA_ONLY
  364         struct ieee80211_pmk *pmk;
  365 #endif
  366 
  367         /* STA must be associated or AP must be ready */
  368         if (ic->ic_state != IEEE80211_S_RUN ||
  369             !(ic->ic_flags & IEEE80211_F_RSNON))
  370                 return ENETDOWN;
  371 
  372         ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART;
  373 #ifndef IEEE80211_STA_ONLY
  374         if (ic->ic_opmode == IEEE80211_M_STA)
  375 #endif
  376                 return 0;       /* supplicant only, do nothing */
  377 
  378 #ifndef IEEE80211_STA_ONLY
  379         /* find the STA with which we must start the key exchange */
  380         if ((ni = ieee80211_find_node(ic, macaddr)) == NULL) {
  381                 DPRINTF(("no node found for %s\n", ether_sprintf(macaddr)));
  382                 return EINVAL;
  383         }
  384         /* check that the STA is in the correct state */
  385         if (ni->ni_state != IEEE80211_STA_ASSOC ||
  386             ni->ni_rsn_state != RSNA_AUTHENTICATION_2) {
  387                 DPRINTF(("unexpected in state %d\n", ni->ni_rsn_state));
  388                 return EINVAL;
  389         }
  390         ni->ni_rsn_state = RSNA_INITPMK;
  391 
  392         /* make sure a PMK is available for this STA, otherwise deauth it */
  393         if ((pmk = ieee80211_pmksa_find(ic, ni, NULL)) == NULL) {
  394                 DPRINTF(("no PMK available for %s\n", ether_sprintf(macaddr)));
  395                 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
  396                     IEEE80211_REASON_AUTH_LEAVE);
  397                 ieee80211_node_leave(ic, ni);
  398                 return EINVAL;
  399         }
  400         memcpy(ni->ni_pmk, pmk->pmk_key, IEEE80211_PMK_LEN);
  401         memcpy(ni->ni_pmkid, pmk->pmk_pmkid, IEEE80211_PMKID_LEN);
  402         ni->ni_flags |= IEEE80211_NODE_PMK;
  403 
  404         /* initiate key exchange (4-Way Handshake) with STA */
  405         return ieee80211_send_4way_msg1(ic, ni);
  406 #endif  /* IEEE80211_STA_ONLY */
  407 }
  408 
  409 #ifndef IEEE80211_STA_ONLY
  410 /*
  411  * Initiate a group key handshake with a node.
  412  */
  413 static void
  414 ieee80211_node_gtk_rekey(void *arg, struct ieee80211_node *ni)
  415 {
  416         struct ieee80211com *ic = arg;
  417 
  418         if (ni->ni_state != IEEE80211_STA_ASSOC ||
  419             ni->ni_rsn_gstate != RSNA_IDLE)
  420                 return;
  421 
  422         /* initiate a group key handshake with STA */
  423         ni->ni_flags |= IEEE80211_NODE_REKEY;
  424         if (ieee80211_send_group_msg1(ic, ni) != 0)
  425                 ni->ni_flags &= ~IEEE80211_NODE_REKEY;
  426 }
  427 
  428 /*
  429  * This function is called in HostAP mode when the group key needs to be
  430  * changed.
  431  */
  432 void
  433 ieee80211_setkeys(struct ieee80211com *ic)
  434 {
  435         struct ieee80211_key *k;
  436         u_int8_t kid;
  437         int rekeysta = 0;
  438 
  439         /* Swap(GM, GN) */
  440         kid = (ic->ic_def_txkey == 1) ? 2 : 1;
  441         k = &ic->ic_nw_keys[kid];
  442         memset(k, 0, sizeof(*k));
  443         k->k_id = kid;
  444         k->k_cipher = ic->ic_bss->ni_rsngroupcipher;
  445         k->k_flags = IEEE80211_KEY_GROUP | IEEE80211_KEY_TX;
  446         k->k_len = ieee80211_cipher_keylen(k->k_cipher);
  447         arc4random_buf(k->k_key, k->k_len);
  448 
  449         if (ic->ic_caps & IEEE80211_C_MFP) {
  450                 /* Swap(GM_igtk, GN_igtk) */
  451                 kid = (ic->ic_igtk_kid == 4) ? 5 : 4;
  452                 k = &ic->ic_nw_keys[kid];
  453                 memset(k, 0, sizeof(*k));
  454                 k->k_id = kid;
  455                 k->k_cipher = ic->ic_bss->ni_rsngroupmgmtcipher;
  456                 k->k_flags = IEEE80211_KEY_IGTK | IEEE80211_KEY_TX;
  457                 k->k_len = 16;
  458                 arc4random_buf(k->k_key, k->k_len);
  459         }
  460 
  461         ieee80211_iterate_nodes(ic, ieee80211_node_gtk_rekey, ic);
  462         ieee80211_iterate_nodes(ic, ieee80211_count_rekeysta, &rekeysta);
  463         if (rekeysta == 0)
  464                 ieee80211_setkeysdone(ic);
  465 }
  466 
  467 /*
  468  * The group key handshake has been completed with all associated stations.
  469  */
  470 void
  471 ieee80211_setkeysdone(struct ieee80211com *ic)
  472 {
  473         u_int8_t kid;
  474 
  475         /* install GTK */
  476         kid = (ic->ic_def_txkey == 1) ? 2 : 1;
  477         switch ((*ic->ic_set_key)(ic, ic->ic_bss, &ic->ic_nw_keys[kid])) {
  478         case 0:
  479         case EBUSY:
  480                 ic->ic_def_txkey = kid;
  481                 break;
  482         default:
  483                 break;
  484         }
  485 
  486         if (ic->ic_caps & IEEE80211_C_MFP) {
  487                 /* install IGTK */
  488                 kid = (ic->ic_igtk_kid == 4) ? 5 : 4;
  489                 switch ((*ic->ic_set_key)(ic, ic->ic_bss, &ic->ic_nw_keys[kid])) {
  490                 case 0:
  491                 case EBUSY:
  492                         ic->ic_igtk_kid = kid;
  493                         break;
  494                 default:
  495                         break;
  496                 }
  497         }
  498 }
  499 
  500 /*
  501  * Group key lifetime has expired, update it.
  502  */
  503 void
  504 ieee80211_gtk_rekey_timeout(void *arg)
  505 {
  506         struct ieee80211com *ic = arg;
  507         int s;
  508 
  509         s = splnet();
  510         ieee80211_setkeys(ic);
  511         splx(s);
  512 
  513         /* re-schedule a GTK rekeying after 3600s */
  514         timeout_add_sec(&ic->ic_rsn_timeout, 3600);
  515 }
  516 
  517 void
  518 ieee80211_sa_query_timeout(void *arg)
  519 {
  520         struct ieee80211_node *ni = arg;
  521         struct ieee80211com *ic = ni->ni_ic;
  522         int s;
  523 
  524         s = splnet();
  525         if (++ni->ni_sa_query_count >= 3) {
  526                 ni->ni_flags &= ~IEEE80211_NODE_SA_QUERY;
  527                 ni->ni_flags |= IEEE80211_NODE_SA_QUERY_FAILED;
  528         } else  /* retry SA Query Request */
  529                 ieee80211_sa_query_request(ic, ni);
  530         splx(s);
  531 }
  532 
  533 /*
  534  * Request that a SA Query Request frame be sent to a specified peer STA
  535  * to which the STA is associated.
  536  */
  537 void
  538 ieee80211_sa_query_request(struct ieee80211com *ic, struct ieee80211_node *ni)
  539 {
  540         /* MLME-SAQuery.request */
  541 
  542         if (!(ni->ni_flags & IEEE80211_NODE_SA_QUERY)) {
  543                 ni->ni_flags |= IEEE80211_NODE_SA_QUERY;
  544                 ni->ni_flags &= ~IEEE80211_NODE_SA_QUERY_FAILED;
  545                 ni->ni_sa_query_count = 0;
  546         }
  547         /* generate new Transaction Identifier */
  548         ni->ni_sa_query_trid++;
  549 
  550         /* send SA Query Request */
  551         IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_SA_QUERY,
  552             IEEE80211_ACTION_SA_QUERY_REQ, 0);
  553         timeout_add_msec(&ni->ni_sa_query_to, 10);
  554 }
  555 #endif  /* IEEE80211_STA_ONLY */
  556 
  557 void
  558 ieee80211_ht_negotiate(struct ieee80211com *ic, struct ieee80211_node *ni)
  559 {
  560         int i;
  561 
  562         ni->ni_flags &= ~(IEEE80211_NODE_HT | IEEE80211_NODE_HT_SGI20 |
  563             IEEE80211_NODE_HT_SGI40);
  564 
  565         /* Check if we support HT. */
  566         if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11N)) == 0)
  567                 return;
  568 
  569         /* Check if HT support has been explicitly disabled. */
  570         if ((ic->ic_flags & IEEE80211_F_HTON) == 0)
  571                 return;
  572 
  573         /*
  574          * Check if the peer supports HT.
  575          * Require at least one of the mandatory MCS.
  576          * MCS 0-7 are mandatory but some APs have particular MCS disabled.
  577          */
  578         if (!ieee80211_node_supports_ht(ni)) {
  579                 ic->ic_stats.is_ht_nego_no_mandatory_mcs++;
  580                 return;
  581         }
  582 
  583         if (ic->ic_opmode == IEEE80211_M_STA) {
  584                 /* We must support the AP's basic MCS set. */
  585                 for (i = 0; i < IEEE80211_HT_NUM_MCS; i++) {
  586                         if (isset(ni->ni_basic_mcs, i) &&
  587                             !isset(ic->ic_sup_mcs, i)) {
  588                                 ic->ic_stats.is_ht_nego_no_basic_mcs++;
  589                                 return;
  590                         }
  591                 }
  592         }
  593 
  594         /*
  595          * Don't allow group cipher (includes WEP) or TKIP
  596          * for pairwise encryption (see 802.11-2012 11.1.6).
  597          */
  598         if (ic->ic_flags & IEEE80211_F_WEPON) {
  599                 ic->ic_stats.is_ht_nego_bad_crypto++;
  600                 return;
  601         }
  602         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
  603             (ni->ni_rsnciphers & IEEE80211_CIPHER_USEGROUP ||
  604             ni->ni_rsnciphers & IEEE80211_CIPHER_TKIP)) {
  605                 ic->ic_stats.is_ht_nego_bad_crypto++;
  606                 return;
  607         }
  608 
  609         ni->ni_flags |= IEEE80211_NODE_HT;
  610 
  611         if (ieee80211_node_supports_ht_sgi20(ni) &&
  612             (ic->ic_htcaps & IEEE80211_HTCAP_SGI20))
  613                 ni->ni_flags |= IEEE80211_NODE_HT_SGI20;
  614         if (ieee80211_node_supports_ht_sgi40(ni) &&
  615             (ic->ic_htcaps & IEEE80211_HTCAP_SGI40))
  616                 ni->ni_flags |= IEEE80211_NODE_HT_SGI40;
  617 }
  618 
  619 void
  620 ieee80211_vht_negotiate(struct ieee80211com *ic, struct ieee80211_node *ni)
  621 {
  622         int n;
  623 
  624         ni->ni_flags &= ~(IEEE80211_NODE_VHT | IEEE80211_NODE_VHT_SGI80 |
  625             IEEE80211_NODE_VHT_SGI160);
  626 
  627         /* Check if we support VHT. */
  628         if ((ic->ic_modecaps & (1 << IEEE80211_MODE_11AC)) == 0)
  629                 return;
  630 
  631         /* Check if VHT support has been explicitly disabled. */
  632         if ((ic->ic_flags & IEEE80211_F_VHTON) == 0)
  633                 return;
  634 
  635         /*
  636          * Check if the peer supports VHT.
  637          * MCS 0-7 for a single spatial stream are mandatory.
  638          */
  639         if (!ieee80211_node_supports_vht(ni)) {
  640                 ic->ic_stats.is_vht_nego_no_mandatory_mcs++;
  641                 return;
  642         }
  643 
  644         if (ic->ic_opmode == IEEE80211_M_STA) {
  645                 /* We must support the AP's basic MCS set. */
  646                 for (n = 1; n <= IEEE80211_VHT_NUM_SS; n++) {
  647                         uint16_t basic_mcs = (ni->ni_vht_basic_mcs &
  648                             IEEE80211_VHT_MCS_FOR_SS_MASK(n)) >>
  649                             IEEE80211_VHT_MCS_FOR_SS_SHIFT(n);
  650                         uint16_t rx_mcs = (ic->ic_vht_rxmcs &
  651                             IEEE80211_VHT_MCS_FOR_SS_MASK(n)) >>
  652                             IEEE80211_VHT_MCS_FOR_SS_SHIFT(n);
  653                         if (basic_mcs != IEEE80211_VHT_MCS_SS_NOT_SUPP &&
  654                             basic_mcs > rx_mcs) {
  655                                 ic->ic_stats.is_vht_nego_no_basic_mcs++;
  656                                 return;
  657                         }
  658                 }
  659         }
  660 
  661         ni->ni_flags |= IEEE80211_NODE_VHT;
  662 
  663         if ((ni->ni_vhtcaps & IEEE80211_VHTCAP_SGI80) &&
  664             (ic->ic_vhtcaps & IEEE80211_VHTCAP_SGI80))
  665                 ni->ni_flags |= IEEE80211_NODE_VHT_SGI80;
  666         if ((ni->ni_vhtcaps & IEEE80211_VHTCAP_SGI160) &&
  667             (ic->ic_vhtcaps & IEEE80211_VHTCAP_SGI160))
  668                 ni->ni_flags |= IEEE80211_NODE_VHT_SGI160;
  669 }
  670 
  671 void
  672 ieee80211_tx_ba_timeout(void *arg)
  673 {
  674         struct ieee80211_tx_ba *ba = arg;
  675         struct ieee80211_node *ni = ba->ba_ni;
  676         struct ieee80211com *ic = ni->ni_ic;
  677         u_int8_t tid;
  678         int s;
  679 
  680         s = splnet();
  681         tid = ((caddr_t)ba - (caddr_t)ni->ni_tx_ba) / sizeof(*ba);
  682         if (ba->ba_state == IEEE80211_BA_REQUESTED) {
  683                 /* MLME-ADDBA.confirm(TIMEOUT) */
  684                 ba->ba_state = IEEE80211_BA_INIT;
  685                 if (ni->ni_addba_req_intval[tid] <
  686                     IEEE80211_ADDBA_REQ_INTVAL_MAX)
  687                         ni->ni_addba_req_intval[tid]++;
  688                 /*
  689                  * In case the peer believes there is an existing
  690                  * block ack agreement with us, try to delete it.
  691                  */
  692                 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
  693                     IEEE80211_ACTION_DELBA,
  694                     IEEE80211_REASON_SETUP_REQUIRED << 16 | 1 << 8 | tid);
  695         } else if (ba->ba_state == IEEE80211_BA_AGREED) {
  696                 /* Block Ack inactivity timeout */
  697                 ic->ic_stats.is_ht_tx_ba_timeout++;
  698                 ieee80211_delba_request(ic, ni, IEEE80211_REASON_TIMEOUT,
  699                     1, tid);
  700         }
  701         splx(s);
  702 }
  703 
  704 void
  705 ieee80211_rx_ba_timeout(void *arg)
  706 {
  707         struct ieee80211_rx_ba *ba = arg;
  708         struct ieee80211_node *ni = ba->ba_ni;
  709         struct ieee80211com *ic = ni->ni_ic;
  710         u_int8_t tid;
  711         int s;
  712 
  713         ic->ic_stats.is_ht_rx_ba_timeout++;
  714 
  715         s = splnet();
  716 
  717         /* Block Ack inactivity timeout */
  718         tid = ((caddr_t)ba - (caddr_t)ni->ni_rx_ba) / sizeof(*ba);
  719         ieee80211_delba_request(ic, ni, IEEE80211_REASON_TIMEOUT, 0, tid);
  720 
  721         splx(s);
  722 }
  723 
  724 /*
  725  * Request initiation of Block Ack with the specified peer.
  726  */
  727 int
  728 ieee80211_addba_request(struct ieee80211com *ic, struct ieee80211_node *ni,
  729     u_int16_t ssn, u_int8_t tid)
  730 {
  731         struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
  732 
  733         if (ba->ba_state != IEEE80211_BA_INIT)
  734                 return EBUSY;
  735 
  736         /* MLME-ADDBA.request */
  737 
  738         /* setup Block Ack */
  739         ba->ba_ni = ni;
  740         ba->ba_state = IEEE80211_BA_REQUESTED;
  741         ba->ba_token = ic->ic_dialog_token++;
  742         ba->ba_timeout_val = 0;
  743         timeout_set(&ba->ba_to, ieee80211_tx_ba_timeout, ba);
  744         ba->ba_winsize = IEEE80211_BA_MAX_WINSZ;
  745         ba->ba_winstart = ssn;
  746         ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
  747         ba->ba_params =
  748             (ba->ba_winsize << IEEE80211_ADDBA_BUFSZ_SHIFT) |
  749             (tid << IEEE80211_ADDBA_TID_SHIFT);
  750         ba->ba_params |= IEEE80211_ADDBA_AMSDU;
  751         if ((ic->ic_htcaps & IEEE80211_HTCAP_DELAYEDBA) == 0)
  752                 /* immediate BA */
  753                 ba->ba_params |= IEEE80211_ADDBA_BA_POLICY;
  754 
  755         if ((ic->ic_caps & IEEE80211_C_ADDBA_OFFLOAD) &&
  756             ic->ic_ampdu_tx_start != NULL) {
  757                 int err = ic->ic_ampdu_tx_start(ic, ni, tid);
  758                 if (err && err != EBUSY) {
  759                         /* driver failed to setup, rollback */
  760                         ieee80211_addba_resp_refuse(ic, ni, tid,
  761                             IEEE80211_STATUS_UNSPECIFIED);
  762                 } else if (err == 0)
  763                         ieee80211_addba_resp_accept(ic, ni, tid);
  764                 return err; /* The device will send an ADDBA frame. */
  765         }
  766 
  767         timeout_add_sec(&ba->ba_to, 1); /* dot11ADDBAResponseTimeout */
  768         IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
  769             IEEE80211_ACTION_ADDBA_REQ, tid);
  770         return 0;
  771 }
  772 
  773 /*
  774  * Request the deletion of Block Ack with a peer and notify driver.
  775  */
  776 void
  777 ieee80211_delba_request(struct ieee80211com *ic, struct ieee80211_node *ni,
  778     u_int16_t reason, u_int8_t dir, u_int8_t tid)
  779 {
  780         /* MLME-DELBA.request */
  781 
  782         if (reason) {
  783                 /* transmit a DELBA frame */
  784                 IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA,
  785                     IEEE80211_ACTION_DELBA, reason << 16 | dir << 8 | tid);
  786         }
  787         if (dir) {
  788                 /* MLME-DELBA.confirm(Originator) */
  789                 if (ic->ic_ampdu_tx_stop != NULL)
  790                         ic->ic_ampdu_tx_stop(ic, ni, tid);
  791                 ieee80211_node_tx_ba_clear(ni, tid);
  792         } else {
  793                 /* MLME-DELBA.confirm(Recipient) */
  794                 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
  795                 int i;
  796 
  797                 if (ic->ic_ampdu_rx_stop != NULL)
  798                         ic->ic_ampdu_rx_stop(ic, ni, tid);
  799 
  800                 ba->ba_state = IEEE80211_BA_INIT;
  801                 /* stop Block Ack inactivity timer */
  802                 timeout_del(&ba->ba_to);
  803                 timeout_del(&ba->ba_gap_to);
  804 
  805                 if (ba->ba_buf != NULL) {
  806                         /* free all MSDUs stored in reordering buffer */
  807                         for (i = 0; i < IEEE80211_BA_MAX_WINSZ; i++)
  808                                 m_freem(ba->ba_buf[i].m);
  809                         /* free reordering buffer */
  810                         free(ba->ba_buf, M_DEVBUF,
  811                             IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf));
  812                         ba->ba_buf = NULL;
  813                 }
  814         }
  815 }
  816 
  817 #ifndef IEEE80211_STA_ONLY
  818 void
  819 ieee80211_auth_open_confirm(struct ieee80211com *ic,
  820     struct ieee80211_node *ni, uint16_t seq)
  821 {
  822         struct ifnet *ifp = &ic->ic_if;
  823 
  824         IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
  825         if (ifp->if_flags & IFF_DEBUG)
  826                 printf("%s: station %s %s authenticated (open)\n",
  827                     ifp->if_xname,
  828                     ether_sprintf((u_int8_t *)ni->ni_macaddr),
  829                     ni->ni_state != IEEE80211_STA_CACHE ?
  830                     "newly" : "already");
  831         ieee80211_node_newstate(ni, IEEE80211_STA_AUTH);
  832 }
  833 #endif
  834 
  835 void
  836 ieee80211_try_another_bss(struct ieee80211com *ic)
  837 {
  838         struct ieee80211_node *curbs, *selbs;
  839         struct ifnet *ifp = &ic->ic_if;
  840 
  841         /* Don't select our current AP again. */
  842         curbs = ieee80211_find_node(ic, ic->ic_bss->ni_macaddr);
  843         if (curbs) {
  844                 curbs->ni_fails++;
  845                 ieee80211_node_newstate(curbs, IEEE80211_STA_CACHE);
  846         }
  847 
  848         /* Try a different AP from the same ESS if available. */
  849         if (ic->ic_caps & IEEE80211_C_SCANALLBAND) {
  850                 /*
  851                  * Make sure we will consider APs on all bands during
  852                  * access point selection in ieee80211_node_choose_bss().
  853                  * During multi-band scans, our previous AP may be trying
  854                  * to steer us onto another band by denying authentication.
  855                  */
  856                 ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
  857         }
  858         selbs = ieee80211_node_choose_bss(ic, 0, NULL);
  859         if (selbs == NULL)
  860                 return;
  861 
  862         /* Should not happen but seriously, don't try the same AP again. */
  863         if (memcmp(selbs->ni_macaddr, ic->ic_bss->ni_macaddr,
  864             IEEE80211_NWID_LEN) == 0)
  865                 return;
  866 
  867         if (ifp->if_flags & IFF_DEBUG)
  868                 printf("%s: trying AP %s on channel %d instead\n",
  869                     ifp->if_xname, ether_sprintf(selbs->ni_macaddr),
  870                     ieee80211_chan2ieee(ic, selbs->ni_chan));
  871 
  872         /* Triggers an AUTH->AUTH transition, avoiding another SCAN. */
  873         ieee80211_node_join_bss(ic, selbs);
  874 }
  875 
  876 void
  877 ieee80211_auth_open(struct ieee80211com *ic, const struct ieee80211_frame *wh,
  878     struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, u_int16_t seq,
  879     u_int16_t status)
  880 {
  881         struct ifnet *ifp = &ic->ic_if;
  882         switch (ic->ic_opmode) {
  883 #ifndef IEEE80211_STA_ONLY
  884         case IEEE80211_M_IBSS:
  885                 if (ic->ic_state != IEEE80211_S_RUN ||
  886                     seq != IEEE80211_AUTH_OPEN_REQUEST) {
  887                         DPRINTF(("discard auth from %s; state %u, seq %u\n",
  888                             ether_sprintf((u_int8_t *)wh->i_addr2),
  889                             ic->ic_state, seq));
  890                         ic->ic_stats.is_rx_bad_auth++;
  891                         return;
  892                 }
  893                 ieee80211_new_state(ic, IEEE80211_S_AUTH,
  894                     wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
  895 
  896                 /* In IBSS mode no (re)association frames are sent. */
  897                 if (ic->ic_flags & IEEE80211_F_RSNON)
  898                         ni->ni_rsn_supp_state = RSNA_SUPP_PTKSTART;
  899                 break;
  900 
  901         case IEEE80211_M_AHDEMO:
  902                 /* should not come here */
  903                 break;
  904 
  905         case IEEE80211_M_HOSTAP:
  906                 if (ic->ic_state != IEEE80211_S_RUN ||
  907                     seq != IEEE80211_AUTH_OPEN_REQUEST) {
  908                         DPRINTF(("discard auth from %s; state %u, seq %u\n",
  909                             ether_sprintf((u_int8_t *)wh->i_addr2),
  910                             ic->ic_state, seq));
  911                         ic->ic_stats.is_rx_bad_auth++;
  912                         return;
  913                 }
  914                 if (ni == ic->ic_bss) {
  915                         ni = ieee80211_find_node(ic, wh->i_addr2);
  916                         if (ni == NULL)
  917                                 ni = ieee80211_alloc_node(ic, wh->i_addr2);
  918                         if (ni == NULL) {
  919                                 return;
  920                         }
  921                         IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
  922                         ni->ni_rssi = rxi->rxi_rssi;
  923                         ni->ni_rstamp = rxi->rxi_tstamp;
  924                         ni->ni_chan = ic->ic_bss->ni_chan;
  925                 }
  926 
  927                 /*
  928                  * Drivers may want to set up state before confirming.
  929                  * In which case this returns EBUSY and the driver will
  930                  * later call ieee80211_auth_open_confirm() by itself.
  931                  */
  932                 if (ic->ic_newauth && ic->ic_newauth(ic, ni,
  933                     ni->ni_state != IEEE80211_STA_CACHE, seq) != 0)
  934                         break;
  935                 ieee80211_auth_open_confirm(ic, ni, seq);
  936                 break;
  937 #endif  /* IEEE80211_STA_ONLY */
  938 
  939         case IEEE80211_M_STA:
  940                 if (ic->ic_state != IEEE80211_S_AUTH ||
  941                     seq != IEEE80211_AUTH_OPEN_RESPONSE) {
  942                         ic->ic_stats.is_rx_bad_auth++;
  943                         DPRINTF(("discard auth from %s; state %u, seq %u\n",
  944                             ether_sprintf((u_int8_t *)wh->i_addr2),
  945                             ic->ic_state, seq));
  946                         return;
  947                 }
  948                 if (ic->ic_flags & IEEE80211_F_RSNON) {
  949                         /* XXX not here! */
  950                         ic->ic_bss->ni_flags &= ~IEEE80211_NODE_TXRXPROT;
  951                         ic->ic_bss->ni_port_valid = 0;
  952                         ic->ic_bss->ni_replaycnt_ok = 0;
  953                         (*ic->ic_delete_key)(ic, ic->ic_bss,
  954                             &ic->ic_bss->ni_pairwise_key);
  955                 }
  956                 if (status != 0) {
  957                         if (ifp->if_flags & IFF_DEBUG)
  958                                 printf("%s: open authentication failed "
  959                                     "(status %d) for %s\n", ifp->if_xname,
  960                                     status,
  961                                     ether_sprintf((u_int8_t *)wh->i_addr3));
  962                         if (ni != ic->ic_bss)
  963                                 ni->ni_fails++;
  964                         else
  965                                 ieee80211_try_another_bss(ic);
  966                         ic->ic_stats.is_rx_auth_fail++;
  967                         return;
  968                 }
  969                 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
  970                     wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
  971                 break;
  972         default:
  973                 break;
  974         }
  975 }
  976 
  977 void
  978 ieee80211_set_beacon_miss_threshold(struct ieee80211com *ic)
  979 {
  980         struct ifnet *ifp = &ic->ic_if;
  981 
  982         /*
  983          * Scale the missed beacon counter threshold to the AP's actual
  984          * beacon interval.
  985          */
  986         int btimeout = MIN(IEEE80211_BEACON_MISS_THRES * ic->ic_bss->ni_intval,
  987             IEEE80211_BEACON_MISS_THRES * (IEEE80211_DUR_TU / 10));
  988         /* Ensure that at least one beacon may be missed. */
  989         btimeout = MAX(btimeout, 2 * ic->ic_bss->ni_intval);
  990         if (ic->ic_bss->ni_intval > 0) /* don't crash if interval is bogus */
  991                 ic->ic_bmissthres = btimeout / ic->ic_bss->ni_intval;
  992 
  993         if (ifp->if_flags & IFF_DEBUG)
  994                 printf("%s: missed beacon threshold set to %d beacons, "
  995                     "beacon interval is %u TU\n", ifp->if_xname,
  996                     ic->ic_bmissthres, ic->ic_bss->ni_intval);
  997 }
  998 
  999 /* Tell our peer, and the driver, to stop A-MPDU Tx for all TIDs. */
 1000 void
 1001 ieee80211_stop_ampdu_tx(struct ieee80211com *ic, struct ieee80211_node *ni,
 1002     int mgt)
 1003 {
 1004         int tid;
 1005 
 1006         for (tid = 0; tid < nitems(ni->ni_tx_ba); tid++) {
 1007                 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 1008                 if (ba->ba_state != IEEE80211_BA_AGREED)
 1009                         continue;
 1010 
 1011                 if (ic->ic_caps & IEEE80211_C_ADDBA_OFFLOAD) {
 1012                         if (ic->ic_ampdu_tx_stop != NULL)
 1013                                 ic->ic_ampdu_tx_stop(ic, ni, tid);
 1014                         continue; /* Don't change ba->ba_state! */
 1015                 }
 1016 
 1017                 ieee80211_delba_request(ic, ni,
 1018                     mgt == -1 ? 0 : IEEE80211_REASON_AUTH_LEAVE, 1, tid);
 1019         }
 1020 }
 1021 
 1022 void
 1023 ieee80211_check_wpa_supplicant_failure(struct ieee80211com *ic,
 1024     struct ieee80211_node *ni)
 1025 {
 1026         struct ieee80211_node *ni2;
 1027 
 1028         if (ic->ic_opmode != IEEE80211_M_STA
 1029 #ifndef IEEE80211_STA_ONLY
 1030             && ic->ic_opmode != IEEE80211_M_IBSS
 1031 #endif
 1032             )
 1033                 return;
 1034 
 1035         if (ni->ni_rsn_supp_state != RSNA_SUPP_PTKNEGOTIATING)
 1036                 return;
 1037 
 1038         ni->ni_assoc_fail |= IEEE80211_NODE_ASSOCFAIL_WPA_KEY;
 1039 
 1040         if (ni != ic->ic_bss)
 1041                 return;
 1042 
 1043         /* Also update the copy of our AP's node in the node cache. */
 1044         ni2 = ieee80211_find_node(ic, ic->ic_bss->ni_macaddr);
 1045         if (ni2)
 1046                 ni2->ni_assoc_fail |= ic->ic_bss->ni_assoc_fail;
 1047 }
 1048 
 1049 int
 1050 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
 1051     int mgt)
 1052 {
 1053         struct ifnet *ifp = &ic->ic_if;
 1054         struct ieee80211_node *ni;
 1055         enum ieee80211_state ostate;
 1056         u_int rate;
 1057 #ifndef IEEE80211_STA_ONLY
 1058         int s;
 1059 #endif
 1060 
 1061         ostate = ic->ic_state;
 1062         if (ifp->if_flags & IFF_DEBUG)
 1063                 printf("%s: %s -> %s\n", ifp->if_xname,
 1064                     ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
 1065         ic->ic_state = nstate;                  /* state transition */
 1066         ni = ic->ic_bss;                        /* NB: no reference held */
 1067         ieee80211_set_link_state(ic, LINK_STATE_DOWN);
 1068         ic->ic_xflags &= ~IEEE80211_F_TX_MGMT_ONLY;
 1069         switch (nstate) {
 1070         case IEEE80211_S_INIT:
 1071                 /*
 1072                  * If mgt = -1, driver is already partway down, so do
 1073                  * not send management frames.
 1074                  */
 1075                 switch (ostate) {
 1076                 case IEEE80211_S_INIT:
 1077                         break;
 1078                 case IEEE80211_S_RUN:
 1079                         if (mgt == -1)
 1080                                 goto justcleanup;
 1081                         ieee80211_stop_ampdu_tx(ic, ni, mgt);
 1082                         ieee80211_ba_del(ni);
 1083                         switch (ic->ic_opmode) {
 1084                         case IEEE80211_M_STA:
 1085                                 IEEE80211_SEND_MGMT(ic, ni,
 1086                                     IEEE80211_FC0_SUBTYPE_DISASSOC,
 1087                                     IEEE80211_REASON_ASSOC_LEAVE);
 1088                                 break;
 1089 #ifndef IEEE80211_STA_ONLY
 1090                         case IEEE80211_M_HOSTAP:
 1091                                 s = splnet();
 1092                                 RBT_FOREACH(ni, ieee80211_tree, &ic->ic_tree) {
 1093                                         if (ni->ni_state != IEEE80211_STA_ASSOC)
 1094                                                 continue;
 1095                                         IEEE80211_SEND_MGMT(ic, ni,
 1096                                             IEEE80211_FC0_SUBTYPE_DISASSOC,
 1097                                             IEEE80211_REASON_ASSOC_LEAVE);
 1098                                 }
 1099                                 splx(s);
 1100                                 break;
 1101 #endif
 1102                         default:
 1103                                 break;
 1104                         }
 1105                         /* FALLTHROUGH */
 1106                 case IEEE80211_S_ASSOC:
 1107                         if (mgt == -1)
 1108                                 goto justcleanup;
 1109                         switch (ic->ic_opmode) {
 1110                         case IEEE80211_M_STA:
 1111                                 IEEE80211_SEND_MGMT(ic, ni,
 1112                                     IEEE80211_FC0_SUBTYPE_DEAUTH,
 1113                                     IEEE80211_REASON_AUTH_LEAVE);
 1114                                 break;
 1115 #ifndef IEEE80211_STA_ONLY
 1116                         case IEEE80211_M_HOSTAP:
 1117                                 s = splnet();
 1118                                 RBT_FOREACH(ni, ieee80211_tree, &ic->ic_tree) {
 1119                                         IEEE80211_SEND_MGMT(ic, ni,
 1120                                             IEEE80211_FC0_SUBTYPE_DEAUTH,
 1121                                             IEEE80211_REASON_AUTH_LEAVE);
 1122                                 }
 1123                                 splx(s);
 1124                                 break;
 1125 #endif
 1126                         default:
 1127                                 break;
 1128                         }
 1129                         /* FALLTHROUGH */
 1130                 case IEEE80211_S_AUTH:
 1131                 case IEEE80211_S_SCAN:
 1132 justcleanup:
 1133 #ifndef IEEE80211_STA_ONLY
 1134                         if (ic->ic_opmode == IEEE80211_M_HOSTAP)
 1135                                 timeout_del(&ic->ic_rsn_timeout);
 1136 #endif
 1137                         ieee80211_ba_del(ni);
 1138                         timeout_del(&ic->ic_bgscan_timeout);
 1139                         ic->ic_bgscan_fail = 0;
 1140                         ic->ic_mgt_timer = 0;
 1141                         mq_purge(&ic->ic_mgtq);
 1142                         mq_purge(&ic->ic_pwrsaveq);
 1143                         ieee80211_free_allnodes(ic, 1);
 1144                         break;
 1145                 }
 1146                 ni->ni_rsn_supp_state = RSNA_SUPP_INITIALIZE;
 1147                 ni->ni_assoc_fail = 0;
 1148                 if (ic->ic_flags & IEEE80211_F_RSNON)
 1149                         ieee80211_crypto_clear_groupkeys(ic);
 1150                 break;
 1151         case IEEE80211_S_SCAN:
 1152                 ic->ic_flags &= ~IEEE80211_F_SIBSS;
 1153                 /* initialize bss for probe request */
 1154                 IEEE80211_ADDR_COPY(ni->ni_macaddr, etherbroadcastaddr);
 1155                 IEEE80211_ADDR_COPY(ni->ni_bssid, etherbroadcastaddr);
 1156                 ni->ni_rates = ic->ic_sup_rates[
 1157                         ieee80211_chan2mode(ic, ni->ni_chan)];
 1158                 ni->ni_associd = 0;
 1159                 ni->ni_rstamp = 0;
 1160                 ni->ni_rsn_supp_state = RSNA_SUPP_INITIALIZE;
 1161                 if (ic->ic_flags & IEEE80211_F_RSNON)
 1162                         ieee80211_crypto_clear_groupkeys(ic);
 1163                 switch (ostate) {
 1164                 case IEEE80211_S_INIT:
 1165 #ifndef IEEE80211_STA_ONLY
 1166                         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
 1167                             ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
 1168                                 /*
 1169                                  * AP operation and we already have a channel;
 1170                                  * bypass the scan and startup immediately.
 1171                                  */
 1172                                 ieee80211_create_ibss(ic, ic->ic_des_chan);
 1173                         } else
 1174 #endif
 1175                                 ieee80211_begin_scan(ifp);
 1176                         break;
 1177                 case IEEE80211_S_SCAN:
 1178                         /* scan next */
 1179                         if (ic->ic_flags & IEEE80211_F_ASCAN) {
 1180                                 IEEE80211_SEND_MGMT(ic, ni,
 1181                                     IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
 1182                         }
 1183                         break;
 1184                 case IEEE80211_S_RUN:
 1185                         /* beacon miss */
 1186                         if (ifp->if_flags & IFF_DEBUG) {
 1187                                 /* XXX bssid clobbered above */
 1188                                 printf("%s: no recent beacons from %s;"
 1189                                     " rescanning\n", ifp->if_xname,
 1190                                     ether_sprintf(ic->ic_bss->ni_bssid));
 1191                         }
 1192                         timeout_del(&ic->ic_bgscan_timeout);
 1193                         ic->ic_bgscan_fail = 0;
 1194                         ieee80211_stop_ampdu_tx(ic, ni, mgt);
 1195                         ieee80211_free_allnodes(ic, 1);
 1196                         /* FALLTHROUGH */
 1197                 case IEEE80211_S_AUTH:
 1198                 case IEEE80211_S_ASSOC:
 1199                         /* timeout restart scan */
 1200                         ni = ieee80211_find_node(ic, ic->ic_bss->ni_macaddr);
 1201                         if (ni != NULL)
 1202                                 ni->ni_fails++;
 1203                         ieee80211_begin_scan(ifp);
 1204                         break;
 1205                 }
 1206                 break;
 1207         case IEEE80211_S_AUTH:
 1208                 if (ostate == IEEE80211_S_RUN)
 1209                         ieee80211_check_wpa_supplicant_failure(ic, ni);
 1210                 ni->ni_rsn_supp_state = RSNA_SUPP_INITIALIZE;
 1211                 if (ic->ic_flags & IEEE80211_F_RSNON)
 1212                         ieee80211_crypto_clear_groupkeys(ic);
 1213                 switch (ostate) {
 1214                 case IEEE80211_S_INIT:
 1215                         if (ifp->if_flags & IFF_DEBUG)
 1216                                 printf("%s: invalid transition %s -> %s\n",
 1217                                     ifp->if_xname, ieee80211_state_name[ostate],
 1218                                     ieee80211_state_name[nstate]);
 1219                         break;
 1220                 case IEEE80211_S_SCAN:
 1221                         IEEE80211_SEND_MGMT(ic, ni,
 1222                             IEEE80211_FC0_SUBTYPE_AUTH, 1);
 1223                         break;
 1224                 case IEEE80211_S_AUTH:
 1225                 case IEEE80211_S_ASSOC:
 1226                         switch (mgt) {
 1227                         case IEEE80211_FC0_SUBTYPE_AUTH:
 1228                                 if (ic->ic_opmode == IEEE80211_M_STA) {
 1229                                         IEEE80211_SEND_MGMT(ic, ni,
 1230                                             IEEE80211_FC0_SUBTYPE_AUTH,
 1231                                             IEEE80211_AUTH_OPEN_REQUEST);
 1232                                 }
 1233                                 break;
 1234                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
 1235                                 /* ignore and retry scan on timeout */
 1236                                 break;
 1237                         }
 1238                         break;
 1239                 case IEEE80211_S_RUN:
 1240                         timeout_del(&ic->ic_bgscan_timeout);
 1241                         ic->ic_bgscan_fail = 0;
 1242                         ieee80211_stop_ampdu_tx(ic, ni, mgt);
 1243                         ieee80211_ba_del(ni);
 1244                         switch (mgt) {
 1245                         case IEEE80211_FC0_SUBTYPE_AUTH:
 1246                                 IEEE80211_SEND_MGMT(ic, ni,
 1247                                     IEEE80211_FC0_SUBTYPE_AUTH, 2);
 1248                                 ic->ic_state = ostate;  /* stay RUN */
 1249                                 break;
 1250                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
 1251                                 /* try to reauth */
 1252                                 IEEE80211_SEND_MGMT(ic, ni,
 1253                                     IEEE80211_FC0_SUBTYPE_AUTH, 1);
 1254                                 break;
 1255                         }
 1256                         break;
 1257                 }
 1258                 break;
 1259         case IEEE80211_S_ASSOC:
 1260                 switch (ostate) {
 1261                 case IEEE80211_S_INIT:
 1262                 case IEEE80211_S_SCAN:
 1263                 case IEEE80211_S_ASSOC:
 1264                         if (ifp->if_flags & IFF_DEBUG)
 1265                                 printf("%s: invalid transition %s -> %s\n",
 1266                                     ifp->if_xname, ieee80211_state_name[ostate],
 1267                                     ieee80211_state_name[nstate]);
 1268                         break;
 1269                 case IEEE80211_S_AUTH:
 1270                         IEEE80211_SEND_MGMT(ic, ni,
 1271                             IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
 1272                         break;
 1273                 case IEEE80211_S_RUN:
 1274                         ieee80211_stop_ampdu_tx(ic, ni, mgt);
 1275                         ieee80211_ba_del(ni);
 1276                         IEEE80211_SEND_MGMT(ic, ni,
 1277                             IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1);
 1278                         break;
 1279                 }
 1280                 break;
 1281         case IEEE80211_S_RUN:
 1282                 switch (ostate) {
 1283                 case IEEE80211_S_INIT:
 1284                         if (ic->ic_opmode == IEEE80211_M_MONITOR)
 1285                                 break;
 1286                 case IEEE80211_S_AUTH:
 1287                 case IEEE80211_S_RUN:
 1288                         if (ifp->if_flags & IFF_DEBUG)
 1289                                 printf("%s: invalid transition %s -> %s\n",
 1290                                     ifp->if_xname, ieee80211_state_name[ostate],
 1291                                     ieee80211_state_name[nstate]);
 1292                         break;
 1293                 case IEEE80211_S_SCAN:          /* adhoc/hostap mode */
 1294                 case IEEE80211_S_ASSOC:         /* infra mode */
 1295                         if (ni->ni_txrate >= ni->ni_rates.rs_nrates)
 1296                                 panic("%s: bogus xmit rate %u setup",
 1297                                     __func__, ni->ni_txrate);
 1298                         if (ifp->if_flags & IFF_DEBUG) {
 1299                                 printf("%s: %s with %s ssid ",
 1300                                     ifp->if_xname,
 1301                                     ic->ic_opmode == IEEE80211_M_STA ?
 1302                                     "associated" : "synchronized",
 1303                                     ether_sprintf(ni->ni_bssid));
 1304                                 ieee80211_print_essid(ic->ic_bss->ni_essid,
 1305                                     ni->ni_esslen);
 1306                                 rate = ni->ni_rates.rs_rates[ni->ni_txrate] &
 1307                                     IEEE80211_RATE_VAL;
 1308                                 printf(" channel %d",
 1309                                     ieee80211_chan2ieee(ic, ni->ni_chan));
 1310                                 if (ni->ni_flags & IEEE80211_NODE_HT)
 1311                                         printf(" start MCS %u", ni->ni_txmcs);
 1312                                 else
 1313                                         printf(" start %u%sMb",
 1314                                             rate / 2, (rate & 1) ? ".5" : "");
 1315                                 printf(" %s preamble %s slot time%s%s%s\n",
 1316                                     (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ?
 1317                                         "short" : "long",
 1318                                     (ic->ic_flags & IEEE80211_F_SHSLOT) ?
 1319                                         "short" : "long",
 1320                                     (ic->ic_flags & IEEE80211_F_USEPROT) ?
 1321                                         " protection enabled" : "",
 1322                                     (ni->ni_flags & IEEE80211_NODE_HT) ?
 1323                                         " HT enabled" : "",
 1324                                     (ni->ni_flags & IEEE80211_NODE_VHT) ?
 1325                                         " VHT enabled" : "");
 1326                         }
 1327                         if (!(ic->ic_flags & IEEE80211_F_RSNON)) {
 1328                                 /*
 1329                                  * NB: When RSN is enabled, we defer setting
 1330                                  * the link up until the port is valid.
 1331                                  */
 1332                                 ieee80211_set_link_state(ic, LINK_STATE_UP);
 1333                                 ni->ni_assoc_fail = 0;
 1334                         }
 1335                         ic->ic_mgt_timer = 0;
 1336                         ieee80211_set_beacon_miss_threshold(ic);
 1337                         if_start(ifp);
 1338                         break;
 1339                 }
 1340                 break;
 1341         }
 1342         return 0;
 1343 }
 1344 
 1345 void
 1346 ieee80211_rtm_80211info_task(void *arg)
 1347 {
 1348         struct ieee80211com *ic = arg;
 1349         struct ifnet *ifp = &ic->ic_if;
 1350         struct if_ieee80211_data ifie;
 1351         int s = splnet();
 1352 
 1353         if (LINK_STATE_IS_UP(ifp->if_link_state)) {
 1354                 memset(&ifie, 0, sizeof(ifie));
 1355                 ifie.ifie_nwid_len = ic->ic_bss->ni_esslen;
 1356                 memcpy(ifie.ifie_nwid, ic->ic_bss->ni_essid,
 1357                     sizeof(ifie.ifie_nwid));
 1358                 memcpy(ifie.ifie_addr, ic->ic_bss->ni_bssid,
 1359                     sizeof(ifie.ifie_addr));
 1360                 ifie.ifie_channel = ieee80211_chan2ieee(ic,
 1361                     ic->ic_bss->ni_chan);
 1362                 ifie.ifie_flags = ic->ic_flags;
 1363                 ifie.ifie_xflags = ic->ic_xflags;
 1364                 rtm_80211info(&ic->ic_if, &ifie);
 1365         }
 1366 
 1367         splx(s);
 1368 }
 1369 
 1370 void
 1371 ieee80211_set_link_state(struct ieee80211com *ic, int nstate)
 1372 {
 1373         struct ifnet *ifp = &ic->ic_if;
 1374 
 1375         switch (ic->ic_opmode) {
 1376 #ifndef IEEE80211_STA_ONLY
 1377         case IEEE80211_M_IBSS:
 1378         case IEEE80211_M_HOSTAP:
 1379                 nstate = LINK_STATE_UNKNOWN;
 1380                 break;
 1381 #endif
 1382         case IEEE80211_M_MONITOR:
 1383                 nstate = LINK_STATE_DOWN;
 1384                 break;
 1385         default:
 1386                 break;
 1387         }
 1388         if (nstate != ifp->if_link_state) {
 1389                 ifp->if_link_state = nstate;
 1390                 if (LINK_STATE_IS_UP(nstate))
 1391                         task_add(systq, &ic->ic_rtm_80211info_task);
 1392                 if_link_state_change(ifp);
 1393         }
 1394 }

Cache object: e400377c2abd525b3929e549e5fff2e3


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


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.