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

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

Generated by: LCOV version 1.13