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

          Line data    Source code
       1             : /*      $OpenBSD: ieee80211_node.c,v 1.150 2018/09/11 19:25:54 phessler Exp $   */
       2             : /*      $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $       */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 2001 Atsushi Onoe
       6             :  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
       7             :  * Copyright (c) 2008 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             : #include "bridge.h"
      34             : 
      35             : #include <sys/param.h>
      36             : #include <sys/systm.h>
      37             : #include <sys/mbuf.h>
      38             : #include <sys/malloc.h>
      39             : #include <sys/kernel.h>
      40             : #include <sys/socket.h>
      41             : #include <sys/sockio.h>
      42             : #include <sys/endian.h>
      43             : #include <sys/errno.h>
      44             : #include <sys/sysctl.h>
      45             : #include <sys/tree.h>
      46             : 
      47             : #include <net/if.h>
      48             : #include <net/if_dl.h>
      49             : #include <net/if_media.h>
      50             : 
      51             : #include <netinet/in.h>
      52             : #include <netinet/if_ether.h>
      53             : 
      54             : #if NBRIDGE > 0
      55             : #include <net/if_bridge.h>
      56             : #endif
      57             : 
      58             : #include <net80211/ieee80211_var.h>
      59             : #include <net80211/ieee80211_priv.h>
      60             : 
      61             : struct ieee80211_node *ieee80211_node_alloc(struct ieee80211com *);
      62             : void ieee80211_node_free(struct ieee80211com *, struct ieee80211_node *);
      63             : void ieee80211_node_copy(struct ieee80211com *, struct ieee80211_node *,
      64             :     const struct ieee80211_node *);
      65             : void ieee80211_choose_rsnparams(struct ieee80211com *);
      66             : u_int8_t ieee80211_node_getrssi(struct ieee80211com *,
      67             :     const struct ieee80211_node *);
      68             : int ieee80211_node_checkrssi(struct ieee80211com *,
      69             :     const struct ieee80211_node *);
      70             : int ieee80211_ess_is_better(struct ieee80211com *ic, struct ieee80211_node *,
      71             :     struct ieee80211_node *);
      72             : void ieee80211_setup_node(struct ieee80211com *, struct ieee80211_node *,
      73             :     const u_int8_t *);
      74             : void ieee80211_free_node(struct ieee80211com *, struct ieee80211_node *);
      75             : void ieee80211_ba_del(struct ieee80211_node *);
      76             : struct ieee80211_node *ieee80211_alloc_node_helper(struct ieee80211com *);
      77             : void ieee80211_node_cleanup(struct ieee80211com *, struct ieee80211_node *);
      78             : void ieee80211_node_switch_bss(struct ieee80211com *, struct ieee80211_node *);
      79             : void ieee80211_needs_auth(struct ieee80211com *, struct ieee80211_node *);
      80             : #ifndef IEEE80211_STA_ONLY
      81             : void ieee80211_node_join_ht(struct ieee80211com *, struct ieee80211_node *);
      82             : void ieee80211_node_join_rsn(struct ieee80211com *, struct ieee80211_node *);
      83             : void ieee80211_node_join_11g(struct ieee80211com *, struct ieee80211_node *);
      84             : void ieee80211_node_leave_ht(struct ieee80211com *, struct ieee80211_node *);
      85             : void ieee80211_node_leave_rsn(struct ieee80211com *, struct ieee80211_node *);
      86             : void ieee80211_node_leave_11g(struct ieee80211com *, struct ieee80211_node *);
      87             : void ieee80211_inact_timeout(void *);
      88             : void ieee80211_node_cache_timeout(void *);
      89             : #endif
      90             : 
      91             : #ifndef IEEE80211_STA_ONLY
      92             : void
      93           0 : ieee80211_inact_timeout(void *arg)
      94             : {
      95           0 :         struct ieee80211com *ic = arg;
      96             :         struct ieee80211_node *ni, *next_ni;
      97             :         int s;
      98             : 
      99           0 :         s = splnet();
     100           0 :         for (ni = RBT_MIN(ieee80211_tree, &ic->ic_tree);
     101           0 :             ni != NULL; ni = next_ni) {
     102           0 :                 next_ni = RBT_NEXT(ieee80211_tree, ni);
     103           0 :                 if (ni->ni_refcnt > 0)
     104             :                         continue;
     105           0 :                 if (ni->ni_inact < IEEE80211_INACT_MAX)
     106           0 :                         ni->ni_inact++;
     107             :         }
     108           0 :         splx(s);
     109             : 
     110           0 :         timeout_add_sec(&ic->ic_inact_timeout, IEEE80211_INACT_WAIT);
     111           0 : }
     112             : 
     113             : void
     114           0 : ieee80211_node_cache_timeout(void *arg)
     115             : {
     116           0 :         struct ieee80211com *ic = arg;
     117             : 
     118           0 :         ieee80211_clean_nodes(ic, 1);
     119           0 :         timeout_add_sec(&ic->ic_node_cache_timeout, IEEE80211_CACHE_WAIT);
     120           0 : }
     121             : #endif
     122             : 
     123             : /*
     124             :  * For debug purposes
     125             :  */
     126             : void
     127           0 : ieee80211_print_ess(struct ieee80211_ess *ess)
     128             : {
     129           0 :         ieee80211_print_essid(ess->essid, ess->esslen);
     130           0 :         if (ess->flags & IEEE80211_F_RSNON) {
     131           0 :                 printf(" wpa");
     132           0 :                 if (ess->rsnprotos & IEEE80211_PROTO_RSN)
     133           0 :                         printf(",wpa2");
     134           0 :                 if (ess->rsnprotos & IEEE80211_PROTO_WPA)
     135           0 :                         printf(",wpa1");
     136             : 
     137           0 :                 if (ess->rsnakms & IEEE80211_AKM_8021X ||
     138           0 :                     ess->rsnakms & IEEE80211_AKM_SHA256_8021X)
     139           0 :                         printf(",802.1x");
     140           0 :                 printf(" ");
     141             : 
     142           0 :                 if (ess->rsnciphers & IEEE80211_CIPHER_USEGROUP)
     143           0 :                         printf("usegroup");
     144           0 :                 if (ess->rsnciphers & IEEE80211_CIPHER_WEP40)
     145           0 :                         printf("wep40");
     146           0 :                 if (ess->rsnciphers & IEEE80211_CIPHER_WEP104)
     147           0 :                         printf("wep104");
     148           0 :                 if (ess->rsnciphers & IEEE80211_CIPHER_TKIP)
     149           0 :                         printf("tkip");
     150           0 :                 if (ess->rsnciphers & IEEE80211_CIPHER_CCMP)
     151           0 :                         printf("ccmp");
     152             :         }
     153           0 :         if (ess->flags & IEEE80211_F_WEPON) {
     154           0 :                 int i = ess->def_txkey;
     155             : 
     156           0 :                 printf(" wep,");
     157           0 :                 if (ess->nw_keys[i].k_cipher & IEEE80211_CIPHER_WEP40)
     158           0 :                         printf("wep40");
     159           0 :                 if (ess->nw_keys[i].k_cipher & IEEE80211_CIPHER_WEP104)
     160           0 :                         printf("wep104");
     161           0 :         }
     162           0 :         if (ess->flags == 0)
     163           0 :                 printf(" clear");
     164           0 :         printf("\n");
     165           0 : }
     166             : 
     167             : void
     168           0 : ieee80211_print_ess_list(struct ieee80211com *ic)
     169             : {
     170           0 :         struct ifnet            *ifp = &ic->ic_if;
     171             :         struct ieee80211_ess    *ess;
     172             : 
     173           0 :         printf("%s: known networks\n", ifp->if_xname);
     174           0 :         TAILQ_FOREACH(ess, &ic->ic_ess, ess_next) {
     175           0 :                 ieee80211_print_ess(ess);
     176             :         }
     177           0 : }
     178             : 
     179             : struct ieee80211_ess *
     180           0 : ieee80211_get_ess(struct ieee80211com *ic, const char *nwid, int len)
     181             : {
     182             :         struct ieee80211_ess    *ess;
     183             : 
     184           0 :         TAILQ_FOREACH(ess, &ic->ic_ess, ess_next) {
     185           0 :                 if (len == ess->esslen &&
     186           0 :                     memcmp(ess->essid, nwid, ess->esslen) == 0)
     187           0 :                         return ess;
     188             :         }
     189             : 
     190           0 :         return NULL;
     191           0 : }
     192             : 
     193             : void
     194           0 : ieee80211_del_ess(struct ieee80211com *ic, char *nwid, int all)
     195             : {
     196             :         struct ieee80211_ess *ess, *next;
     197             : 
     198           0 :         TAILQ_FOREACH_SAFE(ess, &ic->ic_ess, ess_next, next) {
     199           0 :                 if (all == 1 || (memcmp(ess->essid, nwid,
     200           0 :                     IEEE80211_NWID_LEN) == 0)) {
     201           0 :                         TAILQ_REMOVE(&ic->ic_ess, ess, ess_next);
     202           0 :                         explicit_bzero(ess, sizeof(*ess));
     203           0 :                         free(ess, M_DEVBUF, sizeof(*ess));
     204           0 :                         if (all != 1)
     205           0 :                                 return;
     206             :                 }
     207             :         }
     208           0 : }
     209             : 
     210             : /* Keep in sync with ieee80211_ioctl.c:ieee80211_ioctl_setnwkeys() */
     211             : static int
     212           0 : ieee80211_ess_setnwkeys(struct ieee80211_ess *ess,
     213             :     const struct ieee80211_nwkey *nwkey)
     214             : {
     215             :         struct ieee80211_key *k;
     216             :         int i;
     217             : 
     218           0 :         if (nwkey->i_wepon == IEEE80211_NWKEY_OPEN) {
     219           0 :                 if (!(ess->flags & IEEE80211_F_WEPON))
     220           0 :                         return 0;
     221           0 :                 ess->flags &= ~IEEE80211_F_WEPON;
     222           0 :                 return ENETRESET;
     223             :         }
     224           0 :         if (nwkey->i_defkid < 1 || nwkey->i_defkid > IEEE80211_WEP_NKID)
     225           0 :                 return EINVAL;
     226             : 
     227           0 :         for (i = 0; i < IEEE80211_WEP_NKID; i++) {
     228           0 :                 if (nwkey->i_key[i].i_keylen == 0 ||
     229           0 :                     nwkey->i_key[i].i_keydat == NULL)
     230             :                         continue;       /* entry not set */
     231           0 :                 if (nwkey->i_key[i].i_keylen > IEEE80211_KEYBUF_SIZE)
     232           0 :                         return EINVAL;
     233             : 
     234             :                 /* map wep key to ieee80211_key */
     235           0 :                 k = &ess->nw_keys[i];
     236           0 :                 memset(k, 0, sizeof(*k));
     237           0 :                 if (nwkey->i_key[i].i_keylen <= 5)
     238           0 :                         k->k_cipher = IEEE80211_CIPHER_WEP40;
     239             :                 else
     240           0 :                         k->k_cipher = IEEE80211_CIPHER_WEP104;
     241           0 :                 k->k_len = ieee80211_cipher_keylen(k->k_cipher);
     242           0 :                 k->k_flags = IEEE80211_KEY_GROUP | IEEE80211_KEY_TX;
     243           0 :         }
     244           0 :         ess->def_txkey = nwkey->i_defkid - 1;
     245           0 :         ess->flags |= IEEE80211_F_WEPON;
     246             : 
     247           0 :         return ENETRESET;
     248           0 : }
     249             : 
     250             : 
     251             : /* Keep in sync with ieee80211_ioctl.c:ieee80211_ioctl_setwpaparms() */
     252             : static int
     253           0 : ieee80211_ess_setwpaparms(struct ieee80211_ess *ess,
     254             :     const struct ieee80211_wpaparams *wpa)
     255             : {
     256           0 :         if (!wpa->i_enabled) {
     257           0 :                 if (!(ess->flags & IEEE80211_F_RSNON))
     258           0 :                         return 0;
     259           0 :                 ess->flags &= ~IEEE80211_F_RSNON;
     260           0 :                 ess->rsnprotos = 0;
     261           0 :                 ess->rsnakms = 0;
     262           0 :                 ess->rsngroupcipher = 0;
     263           0 :                 ess->rsnciphers = 0;
     264           0 :                 return ENETRESET;
     265             :         }
     266             : 
     267           0 :         ess->rsnprotos = 0;
     268           0 :         if (wpa->i_protos & IEEE80211_WPA_PROTO_WPA1)
     269           0 :                 ess->rsnprotos |= IEEE80211_PROTO_WPA;
     270           0 :         if (wpa->i_protos & IEEE80211_WPA_PROTO_WPA2)
     271           0 :                 ess->rsnprotos |= IEEE80211_PROTO_RSN;
     272           0 :         if (ess->rsnprotos == 0)     /* set to default (RSN) */
     273           0 :                 ess->rsnprotos = IEEE80211_PROTO_RSN;
     274             : 
     275           0 :         ess->rsnakms = 0;
     276           0 :         if (wpa->i_akms & IEEE80211_WPA_AKM_PSK)
     277           0 :                 ess->rsnakms |= IEEE80211_AKM_PSK;
     278           0 :         if (wpa->i_akms & IEEE80211_WPA_AKM_SHA256_PSK)
     279           0 :                 ess->rsnakms |= IEEE80211_AKM_SHA256_PSK;
     280           0 :         if (wpa->i_akms & IEEE80211_WPA_AKM_8021X)
     281           0 :                 ess->rsnakms |= IEEE80211_AKM_8021X;
     282           0 :         if (wpa->i_akms & IEEE80211_WPA_AKM_SHA256_8021X)
     283           0 :                 ess->rsnakms |= IEEE80211_AKM_SHA256_8021X;
     284           0 :         if (ess->rsnakms == 0)       /* set to default (PSK) */
     285           0 :                 ess->rsnakms = IEEE80211_AKM_PSK;
     286             : 
     287           0 :         if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_WEP40)
     288           0 :                 ess->rsngroupcipher = IEEE80211_CIPHER_WEP40;
     289           0 :         else if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_TKIP)
     290           0 :                 ess->rsngroupcipher = IEEE80211_CIPHER_TKIP;
     291           0 :         else if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_CCMP)
     292           0 :                 ess->rsngroupcipher = IEEE80211_CIPHER_CCMP;
     293           0 :         else if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_WEP104)
     294           0 :                 ess->rsngroupcipher = IEEE80211_CIPHER_WEP104;
     295             :         else  { /* set to default */
     296           0 :                 if (ess->rsnprotos & IEEE80211_PROTO_WPA)
     297           0 :                         ess->rsngroupcipher = IEEE80211_CIPHER_TKIP;
     298             :                 else
     299           0 :                         ess->rsngroupcipher = IEEE80211_CIPHER_CCMP;
     300             :         }
     301             : 
     302           0 :         ess->rsnciphers = 0;
     303           0 :         if (wpa->i_ciphers & IEEE80211_WPA_CIPHER_TKIP)
     304           0 :                 ess->rsnciphers |= IEEE80211_CIPHER_TKIP;
     305           0 :         if (wpa->i_ciphers & IEEE80211_WPA_CIPHER_CCMP)
     306           0 :                 ess->rsnciphers |= IEEE80211_CIPHER_CCMP;
     307           0 :         if (wpa->i_ciphers & IEEE80211_WPA_CIPHER_USEGROUP)
     308           0 :                 ess->rsnciphers = IEEE80211_CIPHER_USEGROUP;
     309           0 :         if (ess->rsnciphers == 0) { /* set to default (CCMP, TKIP if WPA1) */
     310           0 :                 ess->rsnciphers = IEEE80211_CIPHER_CCMP;
     311           0 :                 if (ess->rsnprotos & IEEE80211_PROTO_WPA)
     312           0 :                         ess->rsnciphers |= IEEE80211_CIPHER_TKIP;
     313             :         }
     314             : 
     315           0 :         ess->flags |= IEEE80211_F_RSNON;
     316             : 
     317           0 :         return ENETRESET;
     318           0 : }
     319             : 
     320             : static void
     321           0 : ieee80211_ess_clear_wep(struct ieee80211_ess *ess)
     322             : {
     323             :         int i;
     324             : 
     325             :         /* Disable WEP */
     326           0 :         for (i = 0; i < IEEE80211_WEP_NKID; i++) {
     327           0 :                 explicit_bzero(&ess->nw_keys[i], sizeof(ess->nw_keys[0]));
     328             :         }
     329           0 :         ess->def_txkey = 0;
     330           0 :         ess->flags &= ~IEEE80211_F_WEPON;
     331           0 : }
     332             : 
     333             : static void
     334           0 : ieee80211_ess_clear_wpa(struct ieee80211_ess *ess)
     335             : {
     336             :         /* Disable WPA */
     337           0 :         ess->rsnprotos = ess->rsnakms = ess->rsngroupcipher =
     338           0 :             ess->rsnciphers = 0;
     339           0 :         explicit_bzero(ess->psk, sizeof(ess->psk));
     340           0 :         ess->flags &= ~(IEEE80211_F_PSK | IEEE80211_F_RSNON);
     341           0 : }
     342             : 
     343             : int
     344           0 : ieee80211_add_ess(struct ieee80211com *ic, struct ieee80211_join *join)
     345             : {
     346             :         struct ieee80211_ess *ess;
     347             :         int new = 0, ness = 0;
     348             : 
     349             :         /* only valid for station (aka, client) mode */
     350           0 :         if (ic->ic_opmode != IEEE80211_M_STA)
     351           0 :                 return (0);
     352             : 
     353             :         /* Don't save an empty nwid */
     354           0 :         if (join->i_len == 0)
     355           0 :                 return (0);
     356             : 
     357           0 :         TAILQ_FOREACH(ess, &ic->ic_ess, ess_next) {
     358           0 :                 if (ess->esslen == join->i_len &&
     359           0 :                     memcmp(ess->essid, join->i_nwid, ess->esslen) == 0)
     360             :                         break;
     361           0 :                 ness++;
     362             :         }
     363             : 
     364           0 :         if (ess == NULL) {
     365             :                 /* if not found, and wpa/wep are set, then return */
     366           0 :                 if ((join->i_flags & IEEE80211_JOIN_WPA) &&
     367           0 :                     (join->i_flags & IEEE80211_JOIN_NWKEY)) {
     368           0 :                         return (EINVAL);
     369             :                 }
     370           0 :                 if (ness > IEEE80211_CACHE_SIZE)
     371           0 :                         return (ERANGE);
     372             :                 new = 1;
     373           0 :                 ess = malloc(sizeof(*ess), M_DEVBUF, M_NOWAIT|M_ZERO);
     374           0 :                 if (ess == NULL)
     375           0 :                         return (ENOMEM);
     376           0 :                 memcpy(ess->essid, join->i_nwid, join->i_len);
     377           0 :                 ess->esslen = join->i_len;
     378           0 :         }
     379             : 
     380           0 :         if (join->i_flags & IEEE80211_JOIN_WPA) {
     381           0 :                 if (join->i_wpaparams.i_enabled) {
     382           0 :                         if (!(ic->ic_caps & IEEE80211_C_RSN))
     383           0 :                                 return ENODEV;
     384           0 :                         ieee80211_ess_setwpaparms(ess,
     385             :                             &join->i_wpaparams);
     386           0 :                         if (join->i_flags & IEEE80211_JOIN_WPAPSK) {
     387           0 :                                 ess->flags |= IEEE80211_F_PSK;
     388           0 :                                 explicit_bzero(ess->psk, sizeof(ess->psk));
     389           0 :                                 memcpy(ess->psk, &join->i_wpapsk.i_psk,
     390             :                                     sizeof(ess->psk));
     391           0 :                         }
     392           0 :                         ieee80211_ess_clear_wep(ess);
     393           0 :                 } else {
     394           0 :                         ieee80211_ess_clear_wpa(ess);
     395             :                 }
     396           0 :         } else if (join->i_flags & IEEE80211_JOIN_NWKEY) {
     397           0 :                 if (join->i_nwkey.i_wepon) {
     398           0 :                         if (!(ic->ic_caps & IEEE80211_C_WEP))
     399           0 :                                 return ENODEV;
     400           0 :                         ieee80211_ess_setnwkeys(ess, &join->i_nwkey);
     401           0 :                         ieee80211_ess_clear_wpa(ess);
     402           0 :                 } else {
     403           0 :                         ieee80211_ess_clear_wep(ess);
     404             :                 }
     405             :         }
     406             : 
     407           0 :         if (new)
     408           0 :                 TAILQ_INSERT_TAIL(&ic->ic_ess, ess, ess_next);
     409             : 
     410           0 :         return (0);
     411           0 : }
     412             : 
     413             : uint8_t
     414           0 : ieee80211_ess_adjust_rssi(struct ieee80211com *ic, struct ieee80211_node *ni)
     415             : {
     416           0 :         uint8_t rssi = ni->ni_rssi;
     417             : 
     418             :         /*
     419             :          * Slightly punish 2 GHz RSSI values since they are usually
     420             :          * stronger than 5 GHz RSSI values.
     421             :          */
     422           0 :         if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
     423           0 :                 if (ic->ic_max_rssi) {
     424           0 :                         uint8_t p = (5 * ic->ic_max_rssi) / 100;
     425           0 :                         if (rssi >= p)
     426           0 :                                 rssi -= p; /* punish by 5% */
     427           0 :                 } else  {
     428           0 :                         if (rssi >= 8)
     429           0 :                                 rssi -= 8; /* punish by 8 dBm */
     430             :                 }
     431             :         }
     432             : 
     433           0 :         return rssi;
     434             : }
     435             : 
     436             : int
     437           0 : ieee80211_ess_calculate_score(struct ieee80211com *ic,
     438             :     struct ieee80211_node *ni)
     439             : {
     440             :         int score = 0;
     441             :         uint8_t min_5ghz_rssi;
     442             : 
     443           0 :         if (ic->ic_max_rssi)
     444           0 :                 min_5ghz_rssi = IEEE80211_RSSI_THRES_RATIO_5GHZ;
     445             :         else
     446             :                 min_5ghz_rssi = (uint8_t)IEEE80211_RSSI_THRES_5GHZ;
     447             : 
     448             :         /* Calculate the crypto score */
     449           0 :         if (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)
     450           0 :                 score += 16;
     451           0 :         if (ni->ni_rsnprotos & IEEE80211_PROTO_WPA)
     452           0 :                 score += 8;
     453           0 :         if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY)
     454           0 :                 score += 4;
     455             : 
     456             :         /* 5GHz with a good signal */
     457           0 :         if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) &&
     458           0 :             ni->ni_rssi > min_5ghz_rssi)
     459           0 :                 score += 2;
     460             : 
     461           0 :         return score;
     462             : }
     463             : 
     464             : /*
     465             :  * Given two APs, determine the "better" one of the two.
     466             :  * We compute a score based on the following attributes:
     467             :  *
     468             :  *  crypto: wpa2 > wpa1 > wep > open
     469             :  *  band: 5 GHz > 2 GHz provided 5 GHz rssi is above threshold
     470             :  *  rssi: rssi1 > rssi2 as a numeric comparison with a slight
     471             :  *         disadvantage for 2 GHz APs
     472             :  *
     473             :  * Crypto carries most weight, followed by band, followed by rssi.
     474             :  */
     475             : int
     476           0 : ieee80211_ess_is_better(struct ieee80211com *ic,
     477             :     struct ieee80211_node *nicur, struct ieee80211_node *nican)
     478             : {
     479           0 :         struct ifnet            *ifp = &ic->ic_if;
     480             :         int                      score_cur = 0, score_can = 0;
     481             :         int                      cur_rssi, can_rssi;
     482             : 
     483           0 :         score_cur = ieee80211_ess_calculate_score(ic, nicur);
     484           0 :         score_can = ieee80211_ess_calculate_score(ic, nican);
     485             : 
     486           0 :         cur_rssi = ieee80211_ess_adjust_rssi(ic, nicur);
     487           0 :         can_rssi = ieee80211_ess_adjust_rssi(ic, nican);
     488             : 
     489           0 :         if (can_rssi > cur_rssi)
     490           0 :                 score_can++;
     491             : 
     492           0 :         if ((ifp->if_flags & IFF_DEBUG) && (score_can <= score_cur)) {
     493           0 :                 printf("%s: AP %s ", ifp->if_xname,
     494           0 :                     ether_sprintf(nican->ni_bssid));
     495           0 :                 ieee80211_print_essid(nican->ni_essid, nican->ni_esslen);
     496           0 :                 printf(" score %d\n", score_can);
     497           0 :         }
     498             : 
     499           0 :         return score_can > score_cur;
     500             : }
     501             : 
     502             : /* Determine whether a candidate AP belongs to a given ESS. */
     503             : int
     504           0 : ieee80211_match_ess(struct ieee80211_ess *ess, struct ieee80211_node *ni)
     505             : {
     506           0 :         if (ess->esslen != ni->ni_esslen)
     507           0 :                 return 0;
     508           0 :         if (memcmp(ess->essid, ni->ni_essid, ess->esslen) != 0)
     509           0 :                 return 0;
     510             : 
     511           0 :         if (ess->flags & (IEEE80211_F_PSK | IEEE80211_F_RSNON)) {
     512             :                 /* Ensure same WPA version. */
     513           0 :                 if ((ni->ni_rsnprotos & IEEE80211_PROTO_RSN) &&
     514           0 :                     (ess->rsnprotos & IEEE80211_PROTO_RSN) == 0)
     515           0 :                         return 0;
     516           0 :                 if ((ni->ni_rsnprotos & IEEE80211_PROTO_WPA) &&
     517           0 :                     (ess->rsnprotos & IEEE80211_PROTO_WPA) == 0)
     518           0 :                         return 0;
     519           0 :         } else if (ess->flags & IEEE80211_F_WEPON) {
     520           0 :                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0)
     521           0 :                         return 0;
     522             :         }
     523             : 
     524           0 :         return 1;
     525           0 : }
     526             : 
     527             : void
     528           0 : ieee80211_switch_ess(struct ieee80211com *ic)
     529             : {
     530           0 :         struct ifnet            *ifp = &ic->ic_if;
     531             :         struct ieee80211_ess    *ess, *seless = NULL;
     532             :         struct ieee80211_node   *ni, *selni = NULL;
     533             : 
     534           0 :         if (!ISSET(ifp->if_flags, IFF_RUNNING))
     535           0 :                 return;
     536             : 
     537             :         /* Find the best AP matching an entry on our ESS join list. */
     538           0 :         RBT_FOREACH(ni, ieee80211_tree, &ic->ic_tree) {
     539           0 :                 if ((ic->ic_flags & IEEE80211_F_DESBSSID) &&
     540           0 :                     !IEEE80211_ADDR_EQ(ic->ic_des_bssid, ni->ni_bssid))
     541             :                         continue;
     542             : 
     543           0 :                 TAILQ_FOREACH(ess, &ic->ic_ess, ess_next) {
     544           0 :                         if (ieee80211_match_ess(ess, ni))
     545             :                                 break;
     546             :                 }
     547           0 :                 if (ess == NULL)
     548             :                         continue;
     549             : 
     550             :                 /*
     551             :                  * Operate only on ic_des_essid if auto-join is disabled.
     552             :                  * We might have a password stored for this network.
     553             :                  */
     554           0 :                 if (!ISSET(ic->ic_flags, IEEE80211_F_AUTO_JOIN)) {
     555           0 :                         if (ic->ic_des_esslen == ess->esslen &&
     556           0 :                             memcmp(ic->ic_des_essid, ess->essid,
     557           0 :                             ess->esslen) == 0) {
     558           0 :                                 ieee80211_set_ess(ic, ess->essid, ess->esslen);
     559           0 :                                 return;
     560             :                         }
     561             :                         continue;
     562             :                 }
     563             : 
     564           0 :                 if (selni == NULL) {
     565             :                         seless = ess;
     566             :                         selni = ni;
     567           0 :                         continue;
     568             :                 }
     569             : 
     570           0 :                 if (ieee80211_ess_is_better(ic, selni, ni)) {
     571             :                         seless = ess;
     572             :                         selni = ni;
     573           0 :                 }
     574             :         }
     575             : 
     576           0 :         if (seless && !(seless->esslen == ic->ic_des_esslen &&
     577           0 :             (memcmp(ic->ic_des_essid, seless->essid,
     578           0 :              IEEE80211_NWID_LEN) == 0))) {
     579           0 :                 if (ifp->if_flags & IFF_DEBUG) {
     580           0 :                         printf("%s: best AP %s ", ifp->if_xname,
     581           0 :                             ether_sprintf(selni->ni_bssid));
     582           0 :                         ieee80211_print_essid(selni->ni_essid,
     583           0 :                             selni->ni_esslen);
     584           0 :                         printf(" score %d\n",
     585           0 :                             ieee80211_ess_calculate_score(ic, selni));
     586           0 :                         printf("%s: switching to network ", ifp->if_xname);
     587           0 :                         ieee80211_print_essid(seless->essid, seless->esslen);
     588           0 :                         printf("\n");
     589             : 
     590           0 :                 }
     591           0 :                 ieee80211_set_ess(ic, seless->essid, seless->esslen);
     592           0 :         }
     593           0 : }
     594             : 
     595             : void
     596           0 : ieee80211_set_ess(struct ieee80211com *ic, char *nwid, int len)
     597             : {
     598             :         struct ieee80211_ess    *ess;
     599             : 
     600           0 :         ess = ieee80211_get_ess(ic, nwid, len);
     601           0 :         if (ess == NULL)
     602           0 :                 return;
     603             : 
     604           0 :         memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN);
     605           0 :         ic->ic_des_esslen = ess->esslen;
     606           0 :         memcpy(ic->ic_des_essid, ess->essid, ic->ic_des_esslen);
     607             : 
     608           0 :         ieee80211_disable_wep(ic);
     609           0 :         ieee80211_disable_rsn(ic);
     610           0 :         if (ess->flags & IEEE80211_F_RSNON) {
     611           0 :                 explicit_bzero(ic->ic_psk, sizeof(ic->ic_psk));
     612           0 :                 memcpy(ic->ic_psk, ess->psk, sizeof(ic->ic_psk));
     613             : 
     614           0 :                 ic->ic_rsnprotos = ess->rsnprotos;
     615           0 :                 ic->ic_rsnakms = ess->rsnakms;
     616           0 :                 ic->ic_rsngroupcipher = ess->rsngroupcipher;
     617           0 :                 ic->ic_rsnciphers = ess->rsnciphers;
     618           0 :                 ic->ic_flags |= IEEE80211_F_RSNON;
     619           0 :                 if (ess->flags & IEEE80211_F_PSK)
     620           0 :                         ic->ic_flags |= IEEE80211_F_PSK;
     621           0 :         } else if (ess->flags & IEEE80211_F_WEPON) {
     622             :                 struct ieee80211_key    *k;
     623             :                 int                      i;
     624             : 
     625           0 :                 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
     626           0 :                         k = &ic->ic_nw_keys[i];
     627           0 :                         if (k->k_cipher != IEEE80211_CIPHER_NONE)
     628           0 :                                 (*ic->ic_delete_key)(ic, NULL, k);
     629           0 :                         memcpy(&ic->ic_nw_keys[i], &ess->nw_keys[i],
     630             :                             sizeof(struct ieee80211_key));
     631           0 :                         (*ic->ic_set_key)(ic, NULL, k);
     632             :                 }
     633           0 :                 ic->ic_def_txkey = ess->def_txkey;
     634           0 :                 ic->ic_flags |= IEEE80211_F_WEPON;
     635           0 :         }
     636           0 : }
     637             : 
     638             : void
     639           0 : ieee80211_node_attach(struct ifnet *ifp)
     640             : {
     641           0 :         struct ieee80211com *ic = (void *)ifp;
     642             : #ifndef IEEE80211_STA_ONLY
     643             :         int size;
     644             : #endif
     645             : 
     646           0 :         RBT_INIT(ieee80211_tree, &ic->ic_tree);
     647           0 :         ic->ic_node_alloc = ieee80211_node_alloc;
     648           0 :         ic->ic_node_free = ieee80211_node_free;
     649           0 :         ic->ic_node_copy = ieee80211_node_copy;
     650           0 :         ic->ic_node_getrssi = ieee80211_node_getrssi;
     651           0 :         ic->ic_node_checkrssi = ieee80211_node_checkrssi;
     652           0 :         ic->ic_scangen = 1;
     653           0 :         ic->ic_max_nnodes = ieee80211_cache_size;
     654             : 
     655           0 :         if (ic->ic_max_aid == 0)
     656           0 :                 ic->ic_max_aid = IEEE80211_AID_DEF;
     657           0 :         else if (ic->ic_max_aid > IEEE80211_AID_MAX)
     658           0 :                 ic->ic_max_aid = IEEE80211_AID_MAX;
     659             : #ifndef IEEE80211_STA_ONLY
     660           0 :         size = howmany(ic->ic_max_aid, 32) * sizeof(u_int32_t);
     661           0 :         ic->ic_aid_bitmap = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
     662           0 :         if (ic->ic_aid_bitmap == NULL) {
     663             :                 /* XXX no way to recover */
     664           0 :                 printf("%s: no memory for AID bitmap!\n", __func__);
     665           0 :                 ic->ic_max_aid = 0;
     666           0 :         }
     667           0 :         if (ic->ic_caps & (IEEE80211_C_HOSTAP | IEEE80211_C_IBSS)) {
     668           0 :                 ic->ic_tim_len = howmany(ic->ic_max_aid, 8);
     669           0 :                 ic->ic_tim_bitmap = malloc(ic->ic_tim_len, M_DEVBUF,
     670             :                     M_NOWAIT | M_ZERO);
     671           0 :                 if (ic->ic_tim_bitmap == NULL) {
     672           0 :                         printf("%s: no memory for TIM bitmap!\n", __func__);
     673           0 :                         ic->ic_tim_len = 0;
     674           0 :                 } else
     675           0 :                         ic->ic_set_tim = ieee80211_set_tim;
     676           0 :                 timeout_set(&ic->ic_rsn_timeout,
     677             :                     ieee80211_gtk_rekey_timeout, ic);
     678           0 :                 timeout_set(&ic->ic_inact_timeout,
     679             :                     ieee80211_inact_timeout, ic);
     680           0 :                 timeout_set(&ic->ic_node_cache_timeout,
     681             :                     ieee80211_node_cache_timeout, ic);
     682           0 :         }
     683             : #endif
     684           0 :         TAILQ_INIT(&ic->ic_ess);
     685           0 : }
     686             : 
     687             : struct ieee80211_node *
     688           0 : ieee80211_alloc_node_helper(struct ieee80211com *ic)
     689             : {
     690             :         struct ieee80211_node *ni;
     691           0 :         if (ic->ic_nnodes >= ic->ic_max_nnodes)
     692           0 :                 ieee80211_clean_nodes(ic, 0);
     693           0 :         if (ic->ic_nnodes >= ic->ic_max_nnodes)
     694           0 :                 return NULL;
     695           0 :         ni = (*ic->ic_node_alloc)(ic);
     696           0 :         return ni;
     697           0 : }
     698             : 
     699             : void
     700           0 : ieee80211_node_lateattach(struct ifnet *ifp)
     701             : {
     702           0 :         struct ieee80211com *ic = (void *)ifp;
     703             :         struct ieee80211_node *ni;
     704             : 
     705           0 :         ni = ieee80211_alloc_node_helper(ic);
     706           0 :         if (ni == NULL)
     707           0 :                 panic("unable to setup inital BSS node");
     708           0 :         ni->ni_chan = IEEE80211_CHAN_ANYC;
     709           0 :         ic->ic_bss = ieee80211_ref_node(ni);
     710           0 :         ic->ic_txpower = IEEE80211_TXPOWER_MAX;
     711             : #ifndef IEEE80211_STA_ONLY
     712           0 :         mq_init(&ni->ni_savedq, IEEE80211_PS_MAX_QUEUE, IPL_NET);
     713             : #endif
     714           0 : }
     715             : 
     716             : void
     717           0 : ieee80211_node_detach(struct ifnet *ifp)
     718             : {
     719           0 :         struct ieee80211com *ic = (void *)ifp;
     720             : 
     721           0 :         if (ic->ic_bss != NULL) {
     722           0 :                 (*ic->ic_node_free)(ic, ic->ic_bss);
     723           0 :                 ic->ic_bss = NULL;
     724           0 :         }
     725           0 :         ieee80211_del_ess(ic, NULL, 1);
     726           0 :         ieee80211_free_allnodes(ic, 1);
     727             : #ifndef IEEE80211_STA_ONLY
     728           0 :         free(ic->ic_aid_bitmap, M_DEVBUF,
     729           0 :             howmany(ic->ic_max_aid, 32) * sizeof(u_int32_t));
     730           0 :         free(ic->ic_tim_bitmap, M_DEVBUF, ic->ic_tim_len);
     731           0 :         timeout_del(&ic->ic_inact_timeout);
     732           0 :         timeout_del(&ic->ic_node_cache_timeout);
     733           0 :         timeout_del(&ic->ic_tkip_micfail_timeout);
     734             : #endif
     735           0 :         timeout_del(&ic->ic_rsn_timeout);
     736           0 : }
     737             : 
     738             : /*
     739             :  * AP scanning support.
     740             :  */
     741             : 
     742             : /*
     743             :  * Initialize the active channel set based on the set
     744             :  * of available channels and the current PHY mode.
     745             :  */
     746             : void
     747           0 : ieee80211_reset_scan(struct ifnet *ifp)
     748             : {
     749           0 :         struct ieee80211com *ic = (void *)ifp;
     750             : 
     751           0 :         memcpy(ic->ic_chan_scan, ic->ic_chan_active,
     752             :                 sizeof(ic->ic_chan_active));
     753             :         /* NB: hack, setup so next_scan starts with the first channel */
     754           0 :         if (ic->ic_bss != NULL && ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC)
     755           0 :                 ic->ic_bss->ni_chan = &ic->ic_channels[IEEE80211_CHAN_MAX];
     756           0 : }
     757             : 
     758             : /*
     759             :  * Begin an active scan.
     760             :  */
     761             : void
     762           0 : ieee80211_begin_scan(struct ifnet *ifp)
     763             : {
     764           0 :         struct ieee80211com *ic = (void *)ifp;
     765             : 
     766             :         /*
     767             :          * In all but hostap mode scanning starts off in
     768             :          * an active mode before switching to passive.
     769             :          */
     770             : #ifndef IEEE80211_STA_ONLY
     771           0 :         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
     772             : #endif
     773             :         {
     774           0 :                 ic->ic_flags |= IEEE80211_F_ASCAN;
     775           0 :                 ic->ic_stats.is_scan_active++;
     776           0 :         }
     777             : #ifndef IEEE80211_STA_ONLY
     778             :         else
     779           0 :                 ic->ic_stats.is_scan_passive++;
     780             : #endif
     781           0 :         if (ifp->if_flags & IFF_DEBUG)
     782           0 :                 printf("%s: begin %s scan\n", ifp->if_xname,
     783           0 :                         (ic->ic_flags & IEEE80211_F_ASCAN) ?
     784             :                                 "active" : "passive");
     785             : 
     786             :         /*
     787             :          * Flush any previously seen AP's. Note that the latter 
     788             :          * assumes we don't act as both an AP and a station,
     789             :          * otherwise we'll potentially flush state of stations
     790             :          * associated with us.
     791             :          */
     792           0 :         ieee80211_free_allnodes(ic, 1);
     793             : 
     794             :         /*
     795             :          * Reset the current mode. Setting the current mode will also
     796             :          * reset scan state.
     797             :          */
     798           0 :         if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO ||
     799           0 :             (ic->ic_caps & IEEE80211_C_SCANALLBAND))
     800           0 :                 ic->ic_curmode = IEEE80211_MODE_AUTO;
     801           0 :         ieee80211_setmode(ic, ic->ic_curmode);
     802             : 
     803           0 :         ic->ic_scan_count = 0;
     804             : 
     805             :         /* Scan the next channel. */
     806           0 :         ieee80211_next_scan(ifp);
     807           0 : }
     808             : 
     809             : /*
     810             :  * Switch to the next channel marked for scanning.
     811             :  */
     812             : void
     813           0 : ieee80211_next_scan(struct ifnet *ifp)
     814             : {
     815           0 :         struct ieee80211com *ic = (void *)ifp;
     816             :         struct ieee80211_channel *chan;
     817             : 
     818           0 :         chan = ic->ic_bss->ni_chan;
     819           0 :         for (;;) {
     820           0 :                 if (++chan > &ic->ic_channels[IEEE80211_CHAN_MAX])
     821           0 :                         chan = &ic->ic_channels[0];
     822           0 :                 if (isset(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan))) {
     823             :                         /*
     824             :                          * Ignore channels marked passive-only
     825             :                          * during an active scan.
     826             :                          */
     827           0 :                         if ((ic->ic_flags & IEEE80211_F_ASCAN) == 0 ||
     828           0 :                             (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0)
     829             :                                 break;
     830             :                 }
     831           0 :                 if (chan == ic->ic_bss->ni_chan) {
     832           0 :                         ieee80211_end_scan(ifp);
     833           0 :                         return;
     834             :                 }
     835             :         }
     836           0 :         clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan));
     837             :         DPRINTF(("chan %d->%d\n",
     838             :             ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
     839             :             ieee80211_chan2ieee(ic, chan)));
     840           0 :         ic->ic_bss->ni_chan = chan;
     841           0 :         ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
     842           0 : }
     843             : 
     844             : #ifndef IEEE80211_STA_ONLY
     845             : void
     846           0 : ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
     847             : {
     848             :         struct ieee80211_node *ni;
     849           0 :         struct ifnet *ifp = &ic->ic_if;
     850             : 
     851           0 :         ni = ic->ic_bss;
     852           0 :         if (ifp->if_flags & IFF_DEBUG)
     853           0 :                 printf("%s: creating ibss\n", ifp->if_xname);
     854           0 :         ic->ic_flags |= IEEE80211_F_SIBSS;
     855           0 :         ni->ni_chan = chan;
     856           0 :         ni->ni_rates = ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
     857           0 :         ni->ni_txrate = 0;
     858           0 :         IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
     859           0 :         IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr);
     860           0 :         if (ic->ic_opmode == IEEE80211_M_IBSS) {
     861           0 :                 if ((ic->ic_flags & IEEE80211_F_DESBSSID) != 0)
     862           0 :                         IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_des_bssid);
     863             :                 else
     864           0 :                         ni->ni_bssid[0] |= 0x02;     /* local bit for IBSS */
     865             :         }
     866           0 :         ni->ni_esslen = ic->ic_des_esslen;
     867           0 :         memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
     868           0 :         ni->ni_rssi = 0;
     869           0 :         ni->ni_rstamp = 0;
     870           0 :         memset(ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
     871           0 :         ni->ni_intval = ic->ic_lintval;
     872           0 :         ni->ni_capinfo = IEEE80211_CAPINFO_IBSS;
     873           0 :         if (ic->ic_flags & IEEE80211_F_WEPON)
     874           0 :                 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
     875           0 :         if (ic->ic_flags & IEEE80211_F_HTON) {
     876             :                 const struct ieee80211_edca_ac_params *ac_qap;
     877             :                 struct ieee80211_edca_ac_params *ac;
     878             :                 int aci;
     879             : 
     880             :                 /* 
     881             :                  * Default to non-member HT protection. This will be updated
     882             :                  * later based on the number of non-HT nodes in the node cache.
     883             :                  */
     884           0 :                 ni->ni_htop1 = IEEE80211_HTPROT_NONMEMBER;
     885           0 :                 ic->ic_protmode = IEEE80211_PROT_RTSCTS;
     886             : 
     887             :                 /* Configure QoS EDCA parameters. */
     888           0 :                 for (aci = 0; aci < EDCA_NUM_AC; aci++) {
     889           0 :                         ac = &ic->ic_edca_ac[aci];
     890           0 :                         ac_qap = &ieee80211_qap_edca_table[ic->ic_curmode][aci];
     891           0 :                         ac->ac_acm       = ac_qap->ac_acm;
     892           0 :                         ac->ac_aifsn     = ac_qap->ac_aifsn;
     893           0 :                         ac->ac_ecwmin    = ac_qap->ac_ecwmin;
     894           0 :                         ac->ac_ecwmax    = ac_qap->ac_ecwmax;
     895           0 :                         ac->ac_txoplimit = ac_qap->ac_txoplimit;
     896             :                 }
     897           0 :                 if (ic->ic_updateedca)
     898           0 :                         (*ic->ic_updateedca)(ic);
     899           0 :         }
     900           0 :         if (ic->ic_flags & IEEE80211_F_RSNON) {
     901             :                 struct ieee80211_key *k;
     902             : 
     903             :                 /* initialize 256-bit global key counter to a random value */
     904           0 :                 arc4random_buf(ic->ic_globalcnt, EAPOL_KEY_NONCE_LEN);
     905             : 
     906           0 :                 ni->ni_rsnprotos = ic->ic_rsnprotos;
     907           0 :                 ni->ni_rsnakms = ic->ic_rsnakms;
     908           0 :                 ni->ni_rsnciphers = ic->ic_rsnciphers;
     909           0 :                 ni->ni_rsngroupcipher = ic->ic_rsngroupcipher;
     910           0 :                 ni->ni_rsngroupmgmtcipher = ic->ic_rsngroupmgmtcipher;
     911           0 :                 ni->ni_rsncaps = 0;
     912           0 :                 if (ic->ic_caps & IEEE80211_C_MFP) {
     913           0 :                         ni->ni_rsncaps |= IEEE80211_RSNCAP_MFPC;
     914           0 :                         if (ic->ic_flags & IEEE80211_F_MFPR)
     915           0 :                                 ni->ni_rsncaps |= IEEE80211_RSNCAP_MFPR;
     916             :                 }
     917             : 
     918           0 :                 ic->ic_def_txkey = 1;
     919           0 :                 ic->ic_flags &= ~IEEE80211_F_COUNTERM;
     920           0 :                 k = &ic->ic_nw_keys[ic->ic_def_txkey];
     921           0 :                 memset(k, 0, sizeof(*k));
     922           0 :                 k->k_id = ic->ic_def_txkey;
     923           0 :                 k->k_cipher = ni->ni_rsngroupcipher;
     924           0 :                 k->k_flags = IEEE80211_KEY_GROUP | IEEE80211_KEY_TX;
     925           0 :                 k->k_len = ieee80211_cipher_keylen(k->k_cipher);
     926           0 :                 arc4random_buf(k->k_key, k->k_len);
     927           0 :                 (*ic->ic_set_key)(ic, ni, k);        /* XXX */
     928             : 
     929           0 :                 if (ic->ic_caps & IEEE80211_C_MFP) {
     930           0 :                         ic->ic_igtk_kid = 4;
     931           0 :                         k = &ic->ic_nw_keys[ic->ic_igtk_kid];
     932           0 :                         memset(k, 0, sizeof(*k));
     933           0 :                         k->k_id = ic->ic_igtk_kid;
     934           0 :                         k->k_cipher = ni->ni_rsngroupmgmtcipher;
     935           0 :                         k->k_flags = IEEE80211_KEY_IGTK | IEEE80211_KEY_TX;
     936           0 :                         k->k_len = 16;
     937           0 :                         arc4random_buf(k->k_key, k->k_len);
     938           0 :                         (*ic->ic_set_key)(ic, ni, k);        /* XXX */
     939           0 :                 }
     940             :                 /*
     941             :                  * In HostAP mode, multicast traffic is sent using ic_bss
     942             :                  * as the Tx node, so mark our node as valid so we can send
     943             :                  * multicast frames using the group key we've just configured.
     944             :                  */
     945           0 :                 ni->ni_port_valid = 1;
     946           0 :                 ni->ni_flags |= IEEE80211_NODE_TXPROT;
     947             : 
     948             :                 /* schedule a GTK/IGTK rekeying after 3600s */
     949           0 :                 timeout_add_sec(&ic->ic_rsn_timeout, 3600);
     950           0 :         }
     951           0 :         timeout_add_sec(&ic->ic_inact_timeout, IEEE80211_INACT_WAIT);
     952           0 :         timeout_add_sec(&ic->ic_node_cache_timeout, IEEE80211_CACHE_WAIT);
     953           0 :         ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
     954           0 : }
     955             : #endif  /* IEEE80211_STA_ONLY */
     956             : 
     957             : int
     958           0 : ieee80211_match_bss(struct ieee80211com *ic, struct ieee80211_node *ni)
     959             : {
     960             :         u_int8_t rate;
     961             :         int fail;
     962             : 
     963             :         fail = 0;
     964           0 :         if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, ni->ni_chan)))
     965           0 :                 fail |= 0x01;
     966           0 :         if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
     967           0 :             ni->ni_chan != ic->ic_des_chan)
     968           0 :                 fail |= 0x01;
     969             : #ifndef IEEE80211_STA_ONLY
     970           0 :         if (ic->ic_opmode == IEEE80211_M_IBSS) {
     971           0 :                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
     972           0 :                         fail |= 0x02;
     973             :         } else
     974             : #endif
     975             :         {
     976           0 :                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_ESS) == 0)
     977           0 :                         fail |= 0x02;
     978             :         }
     979           0 :         if (ic->ic_flags & (IEEE80211_F_WEPON | IEEE80211_F_RSNON)) {
     980           0 :                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0)
     981           0 :                         fail |= 0x04;
     982             :         } else {
     983           0 :                 if (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY)
     984           0 :                         fail |= 0x04;
     985             :         }
     986             : 
     987           0 :         rate = ieee80211_fix_rate(ic, ni, IEEE80211_F_DONEGO);
     988           0 :         if (rate & IEEE80211_RATE_BASIC)
     989           0 :                 fail |= 0x08;
     990           0 :         if (ic->ic_des_esslen != 0 &&
     991           0 :             (ni->ni_esslen != ic->ic_des_esslen ||
     992           0 :              memcmp(ni->ni_essid, ic->ic_des_essid, ic->ic_des_esslen) != 0))
     993           0 :                 fail |= 0x10;
     994           0 :         if ((ic->ic_flags & IEEE80211_F_DESBSSID) &&
     995           0 :             !IEEE80211_ADDR_EQ(ic->ic_des_bssid, ni->ni_bssid))
     996           0 :                 fail |= 0x20;
     997             : 
     998           0 :         if (ic->ic_flags & IEEE80211_F_RSNON) {
     999             :                 /*
    1000             :                  * If at least one RSN IE field from the AP's RSN IE fails
    1001             :                  * to overlap with any value the STA supports, the STA shall
    1002             :                  * decline to associate with that AP.
    1003             :                  */
    1004           0 :                 if ((ni->ni_rsnprotos & ic->ic_rsnprotos) == 0)
    1005           0 :                         fail |= 0x40;
    1006           0 :                 if ((ni->ni_rsnakms & ic->ic_rsnakms) == 0)
    1007           0 :                         fail |= 0x40;
    1008           0 :                 if ((ni->ni_rsnakms & ic->ic_rsnakms &
    1009           0 :                      ~(IEEE80211_AKM_PSK | IEEE80211_AKM_SHA256_PSK)) == 0) {
    1010             :                         /* AP only supports PSK AKMPs */
    1011           0 :                         if (!(ic->ic_flags & IEEE80211_F_PSK))
    1012           0 :                                 fail |= 0x40;
    1013             :                 }
    1014           0 :                 if (ni->ni_rsngroupcipher != IEEE80211_CIPHER_WEP40 &&
    1015           0 :                     ni->ni_rsngroupcipher != IEEE80211_CIPHER_TKIP &&
    1016           0 :                     ni->ni_rsngroupcipher != IEEE80211_CIPHER_CCMP &&
    1017           0 :                     ni->ni_rsngroupcipher != IEEE80211_CIPHER_WEP104)
    1018           0 :                         fail |= 0x40;
    1019           0 :                 if ((ni->ni_rsnciphers & ic->ic_rsnciphers) == 0)
    1020           0 :                         fail |= 0x40;
    1021             : 
    1022             :                 /* we only support BIP as the IGTK cipher */
    1023           0 :                 if ((ni->ni_rsncaps & IEEE80211_RSNCAP_MFPC) &&
    1024           0 :                     ni->ni_rsngroupmgmtcipher != IEEE80211_CIPHER_BIP)
    1025           0 :                         fail |= 0x40;
    1026             : 
    1027             :                 /* we do not support MFP but AP requires it */
    1028           0 :                 if (!(ic->ic_caps & IEEE80211_C_MFP) &&
    1029           0 :                     (ni->ni_rsncaps & IEEE80211_RSNCAP_MFPR))
    1030           0 :                         fail |= 0x40;
    1031             : 
    1032             :                 /* we require MFP but AP does not support it */
    1033           0 :                 if ((ic->ic_caps & IEEE80211_C_MFP) &&
    1034           0 :                     (ic->ic_flags & IEEE80211_F_MFPR) &&
    1035           0 :                     !(ni->ni_rsncaps & IEEE80211_RSNCAP_MFPC))
    1036           0 :                         fail |= 0x40;
    1037             :         }
    1038             : 
    1039           0 :         if (ic->ic_if.if_flags & IFF_DEBUG) {
    1040           0 :                 printf(" %c %s%c", fail ? '-' : '+',
    1041           0 :                     ether_sprintf(ni->ni_bssid),
    1042           0 :                     fail & 0x20 ? '!' : ' ');
    1043           0 :                 printf(" %3d%c", ieee80211_chan2ieee(ic, ni->ni_chan),
    1044           0 :                         fail & 0x01 ? '!' : ' ');
    1045           0 :                 printf(" %+4d", ni->ni_rssi);
    1046           0 :                 printf(" %2dM%c", (rate & IEEE80211_RATE_VAL) / 2,
    1047           0 :                     fail & 0x08 ? '!' : ' ');
    1048           0 :                 printf(" %4s%c",
    1049           0 :                     (ni->ni_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" :
    1050           0 :                     (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" :
    1051             :                     "????",
    1052           0 :                     fail & 0x02 ? '!' : ' ');
    1053           0 :                 printf(" %7s%c ",
    1054           0 :                     (ni->ni_capinfo & IEEE80211_CAPINFO_PRIVACY) ?
    1055             :                     "privacy" : "no",
    1056           0 :                     fail & 0x04 ? '!' : ' ');
    1057           0 :                 printf(" %3s%c ",
    1058           0 :                     (ic->ic_flags & IEEE80211_F_RSNON) ?
    1059             :                     "rsn" : "no",
    1060           0 :                     fail & 0x40 ? '!' : ' ');
    1061           0 :                 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
    1062           0 :                 printf("%s\n", fail & 0x10 ? "!" : "");
    1063           0 :         }
    1064             : 
    1065           0 :         return fail;
    1066             : }
    1067             : 
    1068             : struct ieee80211_node_switch_bss_arg {
    1069             :         u_int8_t cur_macaddr[IEEE80211_ADDR_LEN];
    1070             :         u_int8_t sel_macaddr[IEEE80211_ADDR_LEN];
    1071             : };
    1072             : 
    1073             : /* Implements ni->ni_unref_cb(). */
    1074             : void
    1075           0 : ieee80211_node_switch_bss(struct ieee80211com *ic, struct ieee80211_node *ni)
    1076             : {
    1077           0 :         struct ifnet *ifp = &ic->ic_if;
    1078           0 :         struct ieee80211_node_switch_bss_arg *sba = ni->ni_unref_arg;
    1079             :         struct ieee80211_node *curbs, *selbs;
    1080             : 
    1081           0 :         splassert(IPL_NET);
    1082             : 
    1083           0 :         if ((ic->ic_flags & IEEE80211_F_BGSCAN) == 0) {
    1084           0 :                 free(sba, M_DEVBUF, sizeof(*sba));
    1085           0 :                 return;
    1086             :         }
    1087             : 
    1088           0 :         ic->ic_xflags &= ~IEEE80211_F_TX_MGMT_ONLY;
    1089             : 
    1090           0 :         selbs = ieee80211_find_node(ic, sba->sel_macaddr);
    1091           0 :         if (selbs == NULL) {
    1092           0 :                 free(sba, M_DEVBUF, sizeof(*sba));
    1093           0 :                 ic->ic_flags &= ~IEEE80211_F_BGSCAN;
    1094           0 :                 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
    1095           0 :                 return;
    1096             :         }
    1097             : 
    1098           0 :         curbs = ieee80211_find_node(ic, sba->cur_macaddr);
    1099           0 :         if (curbs == NULL) {
    1100           0 :                 free(sba, M_DEVBUF, sizeof(*sba));
    1101           0 :                 ic->ic_flags &= ~IEEE80211_F_BGSCAN;
    1102           0 :                 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
    1103           0 :                 return;
    1104             :         }
    1105             : 
    1106           0 :         if (ifp->if_flags & IFF_DEBUG) {
    1107           0 :                 printf("%s: roaming from %s chan %d ",
    1108           0 :                     ifp->if_xname, ether_sprintf(curbs->ni_macaddr),
    1109           0 :                     ieee80211_chan2ieee(ic, curbs->ni_chan));
    1110           0 :                 printf("to %s chan %d\n", ether_sprintf(selbs->ni_macaddr),
    1111           0 :                     ieee80211_chan2ieee(ic, selbs->ni_chan));
    1112           0 :         }
    1113           0 :         ieee80211_node_newstate(curbs, IEEE80211_STA_CACHE);
    1114           0 :         ieee80211_node_join_bss(ic, selbs); /* frees arg and ic->ic_bss */
    1115           0 : }
    1116             : 
    1117             : void
    1118           0 : ieee80211_node_join_bss(struct ieee80211com *ic, struct ieee80211_node *selbs)
    1119             : {
    1120             :         enum ieee80211_phymode mode;
    1121             :         struct ieee80211_node *ni;
    1122             : 
    1123             :         /* Reinitialize media mode and channels if needed. */
    1124           0 :         mode = ieee80211_chan2mode(ic, selbs->ni_chan);
    1125           0 :         if (mode != ic->ic_curmode)
    1126           0 :                 ieee80211_setmode(ic, mode);
    1127             : 
    1128           0 :         (*ic->ic_node_copy)(ic, ic->ic_bss, selbs);
    1129           0 :         ni = ic->ic_bss;
    1130             : 
    1131           0 :         ic->ic_curmode = ieee80211_chan2mode(ic, ni->ni_chan);
    1132             : 
    1133             :         /* Make sure we send valid rates in an association request. */
    1134           0 :         if (ic->ic_opmode == IEEE80211_M_STA)
    1135           0 :                 ieee80211_fix_rate(ic, ni,
    1136             :                     IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
    1137             :                     IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
    1138             : 
    1139           0 :         if (ic->ic_flags & IEEE80211_F_RSNON)
    1140           0 :                 ieee80211_choose_rsnparams(ic);
    1141           0 :         else if (ic->ic_flags & IEEE80211_F_WEPON)
    1142           0 :                 ni->ni_rsncipher = IEEE80211_CIPHER_USEGROUP;
    1143             : 
    1144           0 :         ieee80211_node_newstate(selbs, IEEE80211_STA_BSS);
    1145             : #ifndef IEEE80211_STA_ONLY
    1146           0 :         if (ic->ic_opmode == IEEE80211_M_IBSS) {
    1147           0 :                 ieee80211_fix_rate(ic, ni, IEEE80211_F_DOFRATE |
    1148             :                     IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
    1149           0 :                 if (ni->ni_rates.rs_nrates == 0) {
    1150           0 :                         ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
    1151           0 :                         return;
    1152             :                 }
    1153           0 :                 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
    1154           0 :         } else
    1155             : #endif
    1156             :         {
    1157           0 :                 int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
    1158           0 :                     ic->ic_opmode == IEEE80211_M_STA &&
    1159           0 :                     ic->ic_state == IEEE80211_S_RUN);
    1160           0 :                 int auth_next = (ic->ic_opmode == IEEE80211_M_STA &&
    1161           0 :                     ic->ic_state == IEEE80211_S_AUTH);
    1162             :                 int mgt = -1;
    1163             : 
    1164           0 :                 timeout_del(&ic->ic_bgscan_timeout);
    1165           0 :                 ic->ic_flags &= ~IEEE80211_F_BGSCAN;
    1166             : 
    1167             :                 /* 
    1168             :                  * After a background scan, we have now switched APs.
    1169             :                  * Pretend we were just de-authed, which makes
    1170             :                  * ieee80211_new_state() try to re-auth and thus send
    1171             :                  * an AUTH frame to our newly selected AP.
    1172             :                  */
    1173           0 :                 if (bgscan)
    1174           0 :                         mgt = IEEE80211_FC0_SUBTYPE_DEAUTH;
    1175             :                 /*
    1176             :                  * If we are trying another AP after the previous one
    1177             :                  * failed (state transition AUTH->AUTH), ensure that
    1178             :                  * ieee80211_new_state() tries to send another auth frame.
    1179             :                  */
    1180           0 :                 else if (auth_next)
    1181           0 :                         mgt = IEEE80211_FC0_SUBTYPE_AUTH;
    1182             : 
    1183           0 :                 ieee80211_new_state(ic, IEEE80211_S_AUTH, mgt);
    1184             :         }
    1185           0 : }
    1186             : 
    1187             : struct ieee80211_node *
    1188           0 : ieee80211_node_choose_bss(struct ieee80211com *ic, int bgscan,
    1189             :     struct ieee80211_node **curbs)
    1190             : {
    1191             :         struct ieee80211_node *ni, *nextbs, *selbs = NULL, 
    1192             :             *selbs2 = NULL, *selbs5 = NULL;
    1193             :         uint8_t min_5ghz_rssi;
    1194             : 
    1195           0 :         ni = RBT_MIN(ieee80211_tree, &ic->ic_tree);
    1196             : 
    1197           0 :         for (; ni != NULL; ni = nextbs) {
    1198           0 :                 nextbs = RBT_NEXT(ieee80211_tree, ni);
    1199           0 :                 if (ni->ni_fails) {
    1200             :                         /*
    1201             :                          * The configuration of the access points may change
    1202             :                          * during my scan.  So delete the entry for the AP
    1203             :                          * and retry to associate if there is another beacon.
    1204             :                          */
    1205           0 :                         if (ni->ni_fails++ > 2)
    1206           0 :                                 ieee80211_free_node(ic, ni);
    1207             :                         continue;
    1208             :                 }
    1209             : 
    1210           0 :                 if (curbs && ieee80211_node_cmp(ic->ic_bss, ni) == 0)
    1211           0 :                         *curbs = ni;
    1212             : 
    1213           0 :                 if (ieee80211_match_bss(ic, ni) != 0)
    1214             :                         continue;
    1215             : 
    1216           0 :                 if (ic->ic_caps & IEEE80211_C_SCANALLBAND) {
    1217           0 :                         if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) &&
    1218           0 :                             (selbs2 == NULL || ni->ni_rssi > selbs2->ni_rssi))
    1219           0 :                                 selbs2 = ni;
    1220           0 :                         else if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) &&
    1221           0 :                             (selbs5 == NULL || ni->ni_rssi > selbs5->ni_rssi))
    1222           0 :                                 selbs5 = ni;
    1223           0 :                 } else if (selbs == NULL || ni->ni_rssi > selbs->ni_rssi)
    1224           0 :                         selbs = ni;
    1225             :         }
    1226             : 
    1227           0 :         if (ic->ic_max_rssi)
    1228           0 :                 min_5ghz_rssi = IEEE80211_RSSI_THRES_RATIO_5GHZ;
    1229             :         else
    1230             :                 min_5ghz_rssi = (uint8_t)IEEE80211_RSSI_THRES_5GHZ;
    1231             : 
    1232             :         /*
    1233             :          * Prefer a 5Ghz AP even if its RSSI is weaker than the best 2Ghz AP
    1234             :          * (as long as it meets the minimum RSSI threshold) since the 5Ghz band
    1235             :          * is usually less saturated.
    1236             :          */
    1237           0 :         if (selbs5 && selbs5->ni_rssi > min_5ghz_rssi)
    1238           0 :                 selbs = selbs5;
    1239           0 :         else if (selbs5 && selbs2)
    1240           0 :                 selbs = (selbs5->ni_rssi >= selbs2->ni_rssi ? selbs5 : selbs2);
    1241           0 :         else if (selbs2)
    1242           0 :                 selbs = selbs2;
    1243           0 :         else if (selbs5)
    1244           0 :                 selbs = selbs5;
    1245             : 
    1246           0 :         return selbs;
    1247             : }
    1248             : 
    1249             : /*
    1250             :  * Complete a scan of potential channels.
    1251             :  */
    1252             : void
    1253           0 : ieee80211_end_scan(struct ifnet *ifp)
    1254             : {
    1255           0 :         struct ieee80211com *ic = (void *)ifp;
    1256           0 :         struct ieee80211_node *ni, *selbs = NULL, *curbs = NULL;
    1257           0 :         int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
    1258           0 :             ic->ic_opmode == IEEE80211_M_STA &&
    1259           0 :             ic->ic_state == IEEE80211_S_RUN);
    1260             : 
    1261           0 :         if (ifp->if_flags & IFF_DEBUG)
    1262           0 :                 printf("%s: end %s scan\n", ifp->if_xname,
    1263           0 :                     bgscan ? "background" :
    1264           0 :                     ((ic->ic_flags & IEEE80211_F_ASCAN) ?
    1265             :                     "active" : "passive"));
    1266             : 
    1267           0 :         if (ic->ic_scan_count)
    1268           0 :                 ic->ic_flags &= ~IEEE80211_F_ASCAN;
    1269             : 
    1270           0 :         ni = RBT_MIN(ieee80211_tree, &ic->ic_tree);
    1271             : 
    1272             : #ifndef IEEE80211_STA_ONLY
    1273           0 :         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
    1274             :                 /* XXX off stack? */
    1275           0 :                 u_char occupied[howmany(IEEE80211_CHAN_MAX, NBBY)];
    1276             :                 int i, fail;
    1277             : 
    1278             :                 /*
    1279             :                  * The passive scan to look for existing AP's completed,
    1280             :                  * select a channel to camp on.  Identify the channels
    1281             :                  * that already have one or more AP's and try to locate
    1282             :                  * an unoccupied one.  If that fails, pick a random
    1283             :                  * channel from the active set.
    1284             :                  */
    1285           0 :                 memset(occupied, 0, sizeof(occupied));
    1286           0 :                 RBT_FOREACH(ni, ieee80211_tree, &ic->ic_tree)
    1287           0 :                         setbit(occupied, ieee80211_chan2ieee(ic, ni->ni_chan));
    1288           0 :                 for (i = 0; i < IEEE80211_CHAN_MAX; i++)
    1289           0 :                         if (isset(ic->ic_chan_active, i) && isclr(occupied, i))
    1290             :                                 break;
    1291           0 :                 if (i == IEEE80211_CHAN_MAX) {
    1292           0 :                         fail = arc4random() & 3;    /* random 0-3 */
    1293           0 :                         for (i = 0; i < IEEE80211_CHAN_MAX; i++)
    1294           0 :                                 if (isset(ic->ic_chan_active, i) && fail-- == 0)
    1295             :                                         break;
    1296             :                 }
    1297           0 :                 ieee80211_create_ibss(ic, &ic->ic_channels[i]);
    1298             :                 return;
    1299           0 :         }
    1300             : #endif
    1301           0 :         if (ni == NULL) {
    1302             :                 DPRINTF(("no scan candidate\n"));
    1303             :  notfound:
    1304             : 
    1305             : #ifndef IEEE80211_STA_ONLY
    1306           0 :                 if (ic->ic_opmode == IEEE80211_M_IBSS &&
    1307           0 :                     (ic->ic_flags & IEEE80211_F_IBSSON) &&
    1308           0 :                     ic->ic_des_esslen != 0) {
    1309           0 :                         ieee80211_create_ibss(ic, ic->ic_ibss_chan);
    1310           0 :                         return;
    1311             :                 }
    1312             : #endif
    1313             :                 /*
    1314             :                  * Scan the next mode if nothing has been found. This
    1315             :                  * is necessary if the device supports different
    1316             :                  * incompatible modes in the same channel range, like
    1317             :                  * like 11b and "pure" 11G mode.
    1318             :                  * If the device scans all bands in one fell swoop, return
    1319             :                  * current scan results to userspace regardless of mode.
    1320             :                  * This will loop forever except for user-initiated scans.
    1321             :                  */
    1322           0 :                 if (ieee80211_next_mode(ifp) == IEEE80211_MODE_AUTO ||
    1323           0 :                     (ic->ic_caps & IEEE80211_C_SCANALLBAND))
    1324           0 :                         ic->ic_scan_count++;
    1325             : 
    1326             :                 /*
    1327             :                  * Reset the list of channels to scan and start again.
    1328             :                  */
    1329           0 :                 ieee80211_next_scan(ifp);
    1330           0 :                 return;
    1331             :         }
    1332             : 
    1333             :         /* Possibly switch which ssid we are associated with */
    1334           0 :         if (!bgscan && ic->ic_opmode == IEEE80211_M_STA)
    1335           0 :                 ieee80211_switch_ess(ic);
    1336             : 
    1337           0 :         selbs = ieee80211_node_choose_bss(ic, bgscan, &curbs);
    1338           0 :         if (bgscan) {
    1339             :                 struct ieee80211_node_switch_bss_arg *arg;
    1340             : 
    1341             :                 /* AP disappeared? Should not happen. */
    1342           0 :                 if (selbs == NULL || curbs == NULL) {
    1343           0 :                         ic->ic_flags &= ~IEEE80211_F_BGSCAN;
    1344           0 :                         goto notfound;
    1345             :                 }
    1346             : 
    1347             :                 /* 
    1348             :                  * After a background scan we might end up choosing the
    1349             :                  * same AP again. Do not change ic->ic_bss in this case,
    1350             :                  * and make background scans less frequent.
    1351             :                  */
    1352           0 :                 if (selbs == curbs) {
    1353           0 :                         if (ic->ic_bgscan_fail < IEEE80211_BGSCAN_FAIL_MAX)
    1354           0 :                                 ic->ic_bgscan_fail++;
    1355           0 :                         ic->ic_flags &= ~IEEE80211_F_BGSCAN;
    1356           0 :                         return;
    1357             :                 }
    1358             :         
    1359           0 :                 arg = malloc(sizeof(*arg), M_DEVBUF, M_NOWAIT | M_ZERO);
    1360           0 :                 if (arg == NULL) {
    1361           0 :                         ic->ic_flags &= ~IEEE80211_F_BGSCAN;
    1362           0 :                         return;
    1363             :                 }
    1364             : 
    1365           0 :                 ic->ic_bgscan_fail = 0;
    1366             : 
    1367             :                 /* 
    1368             :                  * We are going to switch APs.
    1369             :                  * Queue a de-auth frame addressed to our current AP.
    1370             :                  */
    1371           0 :                 if (IEEE80211_SEND_MGMT(ic, ic->ic_bss,
    1372             :                     IEEE80211_FC0_SUBTYPE_DEAUTH,
    1373           0 :                     IEEE80211_REASON_AUTH_LEAVE) != 0) {
    1374           0 :                         ic->ic_flags &= ~IEEE80211_F_BGSCAN;
    1375           0 :                         return;
    1376             :                 }
    1377             : 
    1378             :                 /* Prevent dispatch of additional data frames to hardware. */
    1379           0 :                 ic->ic_xflags |= IEEE80211_F_TX_MGMT_ONLY;
    1380             : 
    1381             :                 /* 
    1382             :                  * Install a callback which will switch us to the new AP once
    1383             :                  * all dispatched frames have been processed by hardware.
    1384             :                  */
    1385           0 :                 IEEE80211_ADDR_COPY(arg->cur_macaddr, curbs->ni_macaddr);
    1386           0 :                 IEEE80211_ADDR_COPY(arg->sel_macaddr, selbs->ni_macaddr);
    1387           0 :                 ic->ic_bss->ni_unref_arg = arg;
    1388           0 :                 ic->ic_bss->ni_unref_arg_size = sizeof(*arg);
    1389           0 :                 ic->ic_bss->ni_unref_cb = ieee80211_node_switch_bss;
    1390             :                 /* F_BGSCAN flag gets cleared in ieee80211_node_join_bss(). */
    1391           0 :                 return;
    1392           0 :         } else if (selbs == NULL)
    1393             :                 goto notfound;
    1394             : 
    1395           0 :         ieee80211_node_join_bss(ic, selbs);
    1396           0 : }
    1397             : 
    1398             : /*
    1399             :  * Autoselect the best RSN parameters (protocol, AKMP, pairwise cipher...)
    1400             :  * that are supported by both peers (STA mode only).
    1401             :  */
    1402             : void
    1403           0 : ieee80211_choose_rsnparams(struct ieee80211com *ic)
    1404             : {
    1405           0 :         struct ieee80211_node *ni = ic->ic_bss;
    1406             :         struct ieee80211_pmk *pmk;
    1407             : 
    1408             :         /* filter out unsupported protocol versions */
    1409           0 :         ni->ni_rsnprotos &= ic->ic_rsnprotos;
    1410             :         /* prefer RSN (aka WPA2) over WPA */
    1411           0 :         if (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)
    1412           0 :                 ni->ni_rsnprotos = IEEE80211_PROTO_RSN;
    1413             :         else
    1414           0 :                 ni->ni_rsnprotos = IEEE80211_PROTO_WPA;
    1415             : 
    1416             :         /* filter out unsupported AKMPs */
    1417           0 :         ni->ni_rsnakms &= ic->ic_rsnakms;
    1418             :         /* prefer SHA-256 based AKMPs */
    1419           0 :         if ((ic->ic_flags & IEEE80211_F_PSK) && (ni->ni_rsnakms &
    1420             :             (IEEE80211_AKM_PSK | IEEE80211_AKM_SHA256_PSK))) {
    1421             :                 /* AP supports PSK AKMP and a PSK is configured */
    1422           0 :                 if (ni->ni_rsnakms & IEEE80211_AKM_SHA256_PSK)
    1423           0 :                         ni->ni_rsnakms = IEEE80211_AKM_SHA256_PSK;
    1424             :                 else
    1425           0 :                         ni->ni_rsnakms = IEEE80211_AKM_PSK;
    1426             :         } else {
    1427           0 :                 if (ni->ni_rsnakms & IEEE80211_AKM_SHA256_8021X)
    1428           0 :                         ni->ni_rsnakms = IEEE80211_AKM_SHA256_8021X;
    1429             :                 else
    1430           0 :                         ni->ni_rsnakms = IEEE80211_AKM_8021X;
    1431             :                 /* check if we have a cached PMK for this AP */
    1432           0 :                 if (ni->ni_rsnprotos == IEEE80211_PROTO_RSN &&
    1433           0 :                     (pmk = ieee80211_pmksa_find(ic, ni, NULL)) != NULL) {
    1434           0 :                         memcpy(ni->ni_pmkid, pmk->pmk_pmkid,
    1435             :                             IEEE80211_PMKID_LEN);
    1436           0 :                         ni->ni_flags |= IEEE80211_NODE_PMKID;
    1437           0 :                 }
    1438             :         }
    1439             : 
    1440             :         /* filter out unsupported pairwise ciphers */
    1441           0 :         ni->ni_rsnciphers &= ic->ic_rsnciphers;
    1442             :         /* prefer CCMP over TKIP */
    1443           0 :         if (ni->ni_rsnciphers & IEEE80211_CIPHER_CCMP)
    1444           0 :                 ni->ni_rsnciphers = IEEE80211_CIPHER_CCMP;
    1445             :         else
    1446           0 :                 ni->ni_rsnciphers = IEEE80211_CIPHER_TKIP;
    1447           0 :         ni->ni_rsncipher = ni->ni_rsnciphers;
    1448             : 
    1449             :         /* use MFP if we both support it */
    1450           0 :         if ((ic->ic_caps & IEEE80211_C_MFP) &&
    1451           0 :             (ni->ni_rsncaps & IEEE80211_RSNCAP_MFPC))
    1452           0 :                 ni->ni_flags |= IEEE80211_NODE_MFP;
    1453           0 : }
    1454             : 
    1455             : int
    1456           0 : ieee80211_get_rate(struct ieee80211com *ic)
    1457             : {
    1458             :         u_int8_t (*rates)[IEEE80211_RATE_MAXSIZE];
    1459             :         int rate;
    1460             : 
    1461           0 :         rates = &ic->ic_bss->ni_rates.rs_rates;
    1462             : 
    1463           0 :         if (ic->ic_fixed_rate != -1)
    1464           0 :                 rate = (*rates)[ic->ic_fixed_rate];
    1465           0 :         else if (ic->ic_state == IEEE80211_S_RUN)
    1466           0 :                 rate = (*rates)[ic->ic_bss->ni_txrate];
    1467             :         else
    1468             :                 rate = 0;
    1469             : 
    1470           0 :         return rate & IEEE80211_RATE_VAL;
    1471             : }
    1472             : 
    1473             : struct ieee80211_node *
    1474           0 : ieee80211_node_alloc(struct ieee80211com *ic)
    1475             : {
    1476           0 :         return malloc(sizeof(struct ieee80211_node), M_DEVBUF,
    1477             :             M_NOWAIT | M_ZERO);
    1478             : }
    1479             : 
    1480             : void
    1481           0 : ieee80211_node_cleanup(struct ieee80211com *ic, struct ieee80211_node *ni)
    1482             : {
    1483           0 :         if (ni->ni_rsnie != NULL) {
    1484           0 :                 free(ni->ni_rsnie, M_DEVBUF, 2 + ni->ni_rsnie[1]);
    1485           0 :                 ni->ni_rsnie = NULL;
    1486           0 :         }
    1487           0 :         ieee80211_ba_del(ni);
    1488           0 :         free(ni->ni_unref_arg, M_DEVBUF, ni->ni_unref_arg_size);
    1489           0 :         ni->ni_unref_arg = NULL;
    1490           0 :         ni->ni_unref_arg_size = 0;
    1491           0 : }
    1492             : 
    1493             : void
    1494           0 : ieee80211_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
    1495             : {
    1496           0 :         ieee80211_node_cleanup(ic, ni);
    1497           0 :         free(ni, M_DEVBUF, 0);
    1498           0 : }
    1499             : 
    1500             : void
    1501           0 : ieee80211_node_copy(struct ieee80211com *ic,
    1502             :         struct ieee80211_node *dst, const struct ieee80211_node *src)
    1503             : {
    1504           0 :         ieee80211_node_cleanup(ic, dst);
    1505           0 :         *dst = *src;
    1506           0 :         dst->ni_rsnie = NULL;
    1507           0 :         if (src->ni_rsnie != NULL)
    1508           0 :                 ieee80211_save_ie(src->ni_rsnie, &dst->ni_rsnie);
    1509           0 : }
    1510             : 
    1511             : u_int8_t
    1512           0 : ieee80211_node_getrssi(struct ieee80211com *ic,
    1513             :     const struct ieee80211_node *ni)
    1514             : {
    1515           0 :         return ni->ni_rssi;
    1516             : }
    1517             : 
    1518             : int
    1519           0 : ieee80211_node_checkrssi(struct ieee80211com *ic,
    1520             :     const struct ieee80211_node *ni)
    1521             : {
    1522             :         uint8_t thres;
    1523             : 
    1524           0 :         if (ni->ni_chan == IEEE80211_CHAN_ANYC)
    1525           0 :                 return 0;
    1526             : 
    1527           0 :         if (ic->ic_max_rssi) {
    1528           0 :                 thres = (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) ?
    1529             :                     IEEE80211_RSSI_THRES_RATIO_2GHZ :
    1530             :                     IEEE80211_RSSI_THRES_RATIO_5GHZ;
    1531           0 :                 return ((ni->ni_rssi * 100) / ic->ic_max_rssi >= thres);
    1532             :         }
    1533             : 
    1534           0 :         thres = (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) ?
    1535             :             IEEE80211_RSSI_THRES_2GHZ :
    1536             :             IEEE80211_RSSI_THRES_5GHZ;
    1537           0 :         return (ni->ni_rssi >= (u_int8_t)thres);
    1538           0 : }
    1539             : 
    1540             : void
    1541           0 : ieee80211_setup_node(struct ieee80211com *ic,
    1542             :         struct ieee80211_node *ni, const u_int8_t *macaddr)
    1543             : {
    1544             :         int s;
    1545             : 
    1546             :         DPRINTF(("%s\n", ether_sprintf((u_int8_t *)macaddr)));
    1547           0 :         IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
    1548           0 :         ieee80211_node_newstate(ni, IEEE80211_STA_CACHE);
    1549             : 
    1550           0 :         ni->ni_ic = ic;      /* back-pointer */
    1551             : #ifndef IEEE80211_STA_ONLY
    1552           0 :         mq_init(&ni->ni_savedq, IEEE80211_PS_MAX_QUEUE, IPL_NET);
    1553           0 :         timeout_set(&ni->ni_eapol_to, ieee80211_eapol_timeout, ni);
    1554           0 :         timeout_set(&ni->ni_sa_query_to, ieee80211_sa_query_timeout, ni);
    1555             : #endif
    1556           0 :         s = splnet();
    1557           0 :         RBT_INSERT(ieee80211_tree, &ic->ic_tree, ni);
    1558           0 :         ic->ic_nnodes++;
    1559           0 :         splx(s);
    1560           0 : }
    1561             : 
    1562             : struct ieee80211_node *
    1563           0 : ieee80211_alloc_node(struct ieee80211com *ic, const u_int8_t *macaddr)
    1564             : {
    1565           0 :         struct ieee80211_node *ni = ieee80211_alloc_node_helper(ic);
    1566           0 :         if (ni != NULL)
    1567           0 :                 ieee80211_setup_node(ic, ni, macaddr);
    1568             :         else
    1569           0 :                 ic->ic_stats.is_rx_nodealloc++;
    1570           0 :         return ni;
    1571             : }
    1572             : 
    1573             : struct ieee80211_node *
    1574           0 : ieee80211_dup_bss(struct ieee80211com *ic, const u_int8_t *macaddr)
    1575             : {
    1576           0 :         struct ieee80211_node *ni = ieee80211_alloc_node_helper(ic);
    1577           0 :         if (ni != NULL) {
    1578           0 :                 ieee80211_setup_node(ic, ni, macaddr);
    1579             :                 /*
    1580             :                  * Inherit from ic_bss.
    1581             :                  */
    1582           0 :                 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
    1583           0 :                 ni->ni_chan = ic->ic_bss->ni_chan;
    1584           0 :         } else
    1585           0 :                 ic->ic_stats.is_rx_nodealloc++;
    1586           0 :         return ni;
    1587             : }
    1588             : 
    1589             : struct ieee80211_node *
    1590           0 : ieee80211_find_node(struct ieee80211com *ic, const u_int8_t *macaddr)
    1591             : {
    1592             :         struct ieee80211_node *ni;
    1593             :         int cmp;
    1594             : 
    1595             :         /* similar to RBT_FIND except we compare keys, not nodes */
    1596           0 :         ni = RBT_ROOT(ieee80211_tree, &ic->ic_tree);
    1597           0 :         while (ni != NULL) {
    1598           0 :                 cmp = memcmp(macaddr, ni->ni_macaddr, IEEE80211_ADDR_LEN);
    1599           0 :                 if (cmp < 0)
    1600           0 :                         ni = RBT_LEFT(ieee80211_tree, ni);
    1601           0 :                 else if (cmp > 0)
    1602           0 :                         ni = RBT_RIGHT(ieee80211_tree, ni);
    1603             :                 else
    1604             :                         break;
    1605             :         }
    1606           0 :         return ni;
    1607             : }
    1608             : 
    1609             : /*
    1610             :  * Return a reference to the appropriate node for sending
    1611             :  * a data frame.  This handles node discovery in adhoc networks.
    1612             :  *
    1613             :  * Drivers will call this, so increase the reference count before
    1614             :  * returning the node.
    1615             :  */
    1616             : struct ieee80211_node *
    1617           0 : ieee80211_find_txnode(struct ieee80211com *ic, const u_int8_t *macaddr)
    1618             : {
    1619             : #ifndef IEEE80211_STA_ONLY
    1620             :         struct ieee80211_node *ni;
    1621             :         int s;
    1622             : #endif
    1623             : 
    1624             :         /*
    1625             :          * The destination address should be in the node table
    1626             :          * unless we are operating in station mode or this is a
    1627             :          * multicast/broadcast frame.
    1628             :          */
    1629           0 :         if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(macaddr))
    1630           0 :                 return ieee80211_ref_node(ic->ic_bss);
    1631             : 
    1632             : #ifndef IEEE80211_STA_ONLY
    1633           0 :         s = splnet();
    1634           0 :         ni = ieee80211_find_node(ic, macaddr);
    1635           0 :         splx(s);
    1636           0 :         if (ni == NULL) {
    1637           0 :                 if (ic->ic_opmode != IEEE80211_M_IBSS &&
    1638           0 :                     ic->ic_opmode != IEEE80211_M_AHDEMO)
    1639           0 :                         return NULL;
    1640             : 
    1641             :                 /*
    1642             :                  * Fake up a node; this handles node discovery in
    1643             :                  * adhoc mode.  Note that for the driver's benefit
    1644             :                  * we we treat this like an association so the driver
    1645             :                  * has an opportunity to setup its private state.
    1646             :                  *
    1647             :                  * XXX need better way to handle this; issue probe
    1648             :                  *     request so we can deduce rate set, etc.
    1649             :                  */
    1650           0 :                 if ((ni = ieee80211_dup_bss(ic, macaddr)) == NULL)
    1651           0 :                         return NULL;
    1652             :                 /* XXX no rate negotiation; just dup */
    1653           0 :                 ni->ni_rates = ic->ic_bss->ni_rates;
    1654           0 :                 ni->ni_txrate = 0;
    1655           0 :                 if (ic->ic_newassoc)
    1656           0 :                         (*ic->ic_newassoc)(ic, ni, 1);
    1657             :         }
    1658           0 :         return ieee80211_ref_node(ni);
    1659             : #else
    1660             :         return NULL;    /* can't get there */
    1661             : #endif  /* IEEE80211_STA_ONLY */
    1662           0 : }
    1663             : 
    1664             : /*
    1665             :  * It is usually desirable to process a Rx packet using its sender's
    1666             :  * node-record instead of the BSS record.
    1667             :  *
    1668             :  * - AP mode: keep a node-record for every authenticated/associated
    1669             :  *   station *in the BSS*. For future use, we also track neighboring
    1670             :  *   APs, since they might belong to the same ESS.  APs in the same
    1671             :  *   ESS may bridge packets to each other, forming a Wireless
    1672             :  *   Distribution System (WDS).
    1673             :  *
    1674             :  * - IBSS mode: keep a node-record for every station *in the BSS*.
    1675             :  *   Also track neighboring stations by their beacons/probe responses.
    1676             :  *
    1677             :  * - monitor mode: keep a node-record for every sender, regardless
    1678             :  *   of BSS.
    1679             :  *
    1680             :  * - STA mode: the only available node-record is the BSS record,
    1681             :  *   ic->ic_bss.
    1682             :  *
    1683             :  * Of all the 802.11 Control packets, only the node-records for
    1684             :  * RTS packets node-record can be looked up.
    1685             :  *
    1686             :  * Return non-zero if the packet's node-record is kept, zero
    1687             :  * otherwise.
    1688             :  */
    1689             : static __inline int
    1690           0 : ieee80211_needs_rxnode(struct ieee80211com *ic,
    1691             :     const struct ieee80211_frame *wh, const u_int8_t **bssid)
    1692             : {
    1693             :         int monitor, rc = 0;
    1694             : 
    1695           0 :         monitor = (ic->ic_opmode == IEEE80211_M_MONITOR);
    1696             : 
    1697           0 :         *bssid = NULL;
    1698             : 
    1699           0 :         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
    1700             :         case IEEE80211_FC0_TYPE_CTL:
    1701           0 :                 if (!monitor)
    1702             :                         break;
    1703           0 :                 return (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
    1704             :                     IEEE80211_FC0_SUBTYPE_RTS;
    1705             :         case IEEE80211_FC0_TYPE_MGT:
    1706           0 :                 *bssid = wh->i_addr3;
    1707           0 :                 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
    1708             :                 case IEEE80211_FC0_SUBTYPE_BEACON:
    1709             :                 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
    1710             :                         break;
    1711             :                 default:
    1712             : #ifndef IEEE80211_STA_ONLY
    1713           0 :                         if (ic->ic_opmode == IEEE80211_M_STA)
    1714             :                                 break;
    1715           0 :                         rc = IEEE80211_ADDR_EQ(*bssid, ic->ic_bss->ni_bssid) ||
    1716           0 :                              IEEE80211_ADDR_EQ(*bssid, etherbroadcastaddr);
    1717             : #endif
    1718           0 :                         break;
    1719             :                 }
    1720             :                 break;
    1721             :         case IEEE80211_FC0_TYPE_DATA:
    1722           0 :                 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
    1723             :                 case IEEE80211_FC1_DIR_NODS:
    1724           0 :                         *bssid = wh->i_addr3;
    1725             : #ifndef IEEE80211_STA_ONLY
    1726           0 :                         if (ic->ic_opmode == IEEE80211_M_IBSS ||
    1727           0 :                             ic->ic_opmode == IEEE80211_M_AHDEMO)
    1728           0 :                                 rc = IEEE80211_ADDR_EQ(*bssid,
    1729             :                                     ic->ic_bss->ni_bssid);
    1730             : #endif
    1731             :                         break;
    1732             :                 case IEEE80211_FC1_DIR_TODS:
    1733           0 :                         *bssid = wh->i_addr1;
    1734             : #ifndef IEEE80211_STA_ONLY
    1735           0 :                         if (ic->ic_opmode == IEEE80211_M_HOSTAP)
    1736           0 :                                 rc = IEEE80211_ADDR_EQ(*bssid,
    1737             :                                     ic->ic_bss->ni_bssid);
    1738             : #endif
    1739             :                         break;
    1740             :                 case IEEE80211_FC1_DIR_FROMDS:
    1741             :                 case IEEE80211_FC1_DIR_DSTODS:
    1742           0 :                         *bssid = wh->i_addr2;
    1743             : #ifndef IEEE80211_STA_ONLY
    1744           0 :                         rc = (ic->ic_opmode == IEEE80211_M_HOSTAP);
    1745             : #endif
    1746           0 :                         break;
    1747             :                 }
    1748             :                 break;
    1749             :         }
    1750           0 :         return monitor || rc;
    1751           0 : }
    1752             : 
    1753             : /* 
    1754             :  * Drivers call this, so increase the reference count before returning
    1755             :  * the node.
    1756             :  */
    1757             : struct ieee80211_node *
    1758           0 : ieee80211_find_rxnode(struct ieee80211com *ic,
    1759             :     const struct ieee80211_frame *wh)
    1760             : {
    1761             :         static const u_int8_t zero[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    1762             :         struct ieee80211_node *ni;
    1763           0 :         const u_int8_t *bssid;
    1764             :         int s;
    1765             : 
    1766           0 :         if (!ieee80211_needs_rxnode(ic, wh, &bssid))
    1767           0 :                 return ieee80211_ref_node(ic->ic_bss);
    1768             : 
    1769           0 :         s = splnet();
    1770           0 :         ni = ieee80211_find_node(ic, wh->i_addr2);
    1771           0 :         splx(s);
    1772             : 
    1773           0 :         if (ni != NULL)
    1774           0 :                 return ieee80211_ref_node(ni);
    1775             : #ifndef IEEE80211_STA_ONLY
    1776           0 :         if (ic->ic_opmode == IEEE80211_M_HOSTAP)
    1777           0 :                 return ieee80211_ref_node(ic->ic_bss);
    1778             : #endif
    1779             :         /* XXX see remarks in ieee80211_find_txnode */
    1780             :         /* XXX no rate negotiation; just dup */
    1781           0 :         if ((ni = ieee80211_dup_bss(ic, wh->i_addr2)) == NULL)
    1782           0 :                 return ieee80211_ref_node(ic->ic_bss);
    1783             : 
    1784           0 :         IEEE80211_ADDR_COPY(ni->ni_bssid, (bssid != NULL) ? bssid : zero);
    1785             : 
    1786           0 :         ni->ni_rates = ic->ic_bss->ni_rates;
    1787           0 :         ni->ni_txrate = 0;
    1788           0 :         if (ic->ic_newassoc)
    1789           0 :                 (*ic->ic_newassoc)(ic, ni, 1);
    1790             : 
    1791             :         DPRINTF(("faked-up node %p for %s\n", ni,
    1792             :             ether_sprintf((u_int8_t *)wh->i_addr2)));
    1793             : 
    1794           0 :         return ieee80211_ref_node(ni);
    1795           0 : }
    1796             : 
    1797             : struct ieee80211_node *
    1798           0 : ieee80211_find_node_for_beacon(struct ieee80211com *ic,
    1799             :     const u_int8_t *macaddr, const struct ieee80211_channel *chan,
    1800             :     const char *ssid, u_int8_t rssi)
    1801             : {
    1802             :         struct ieee80211_node *ni, *keep = NULL;
    1803             :         int s, score = 0;
    1804             : 
    1805           0 :         if ((ni = ieee80211_find_node(ic, macaddr)) != NULL) {
    1806           0 :                 s = splnet();
    1807             : 
    1808           0 :                 if (ni->ni_chan != chan && ni->ni_rssi >= rssi)
    1809           0 :                         score++;
    1810           0 :                 if (ssid[1] == 0 && ni->ni_esslen != 0)
    1811           0 :                         score++;
    1812           0 :                 if (score > 0)
    1813           0 :                         keep = ni;
    1814             : 
    1815           0 :                 splx(s);
    1816           0 :         }
    1817             : 
    1818           0 :         return (keep);
    1819             : }
    1820             : 
    1821             : void
    1822           0 : ieee80211_ba_del(struct ieee80211_node *ni)
    1823             : {
    1824             :         int tid;
    1825             : 
    1826           0 :         for (tid = 0; tid < nitems(ni->ni_rx_ba); tid++) {
    1827           0 :                 struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
    1828           0 :                 if (ba->ba_state != IEEE80211_BA_INIT) {
    1829           0 :                         if (timeout_pending(&ba->ba_to))
    1830           0 :                                 timeout_del(&ba->ba_to);
    1831           0 :                         if (timeout_pending(&ba->ba_gap_to))
    1832           0 :                                 timeout_del(&ba->ba_gap_to);
    1833           0 :                         ba->ba_state = IEEE80211_BA_INIT;
    1834           0 :                 }
    1835             :         }
    1836             : 
    1837           0 :         for (tid = 0; tid < nitems(ni->ni_tx_ba); tid++) {
    1838           0 :                 struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
    1839           0 :                 if (ba->ba_state != IEEE80211_BA_INIT) {
    1840           0 :                         if (timeout_pending(&ba->ba_to))
    1841           0 :                                 timeout_del(&ba->ba_to);
    1842           0 :                         ba->ba_state = IEEE80211_BA_INIT;
    1843           0 :                 }
    1844             :         }
    1845           0 : }
    1846             : 
    1847             : void
    1848           0 : ieee80211_free_node(struct ieee80211com *ic, struct ieee80211_node *ni)
    1849             : {
    1850           0 :         if (ni == ic->ic_bss)
    1851           0 :                 panic("freeing bss node");
    1852             : 
    1853           0 :         splassert(IPL_NET);
    1854             : 
    1855             :         DPRINTF(("%s\n", ether_sprintf(ni->ni_macaddr)));
    1856             : #ifndef IEEE80211_STA_ONLY
    1857           0 :         timeout_del(&ni->ni_eapol_to);
    1858           0 :         timeout_del(&ni->ni_sa_query_to);
    1859           0 :         IEEE80211_AID_CLR(ni->ni_associd, ic->ic_aid_bitmap);
    1860             : #endif
    1861           0 :         ieee80211_ba_del(ni);
    1862           0 :         RBT_REMOVE(ieee80211_tree, &ic->ic_tree, ni);
    1863           0 :         ic->ic_nnodes--;
    1864             : #ifndef IEEE80211_STA_ONLY
    1865           0 :         if (mq_purge(&ni->ni_savedq) > 0) {
    1866           0 :                 if (ic->ic_set_tim != NULL)
    1867           0 :                         (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
    1868             :         }
    1869             : #endif
    1870           0 :         (*ic->ic_node_free)(ic, ni);
    1871             :         /* TBD indicate to drivers that a new node can be allocated */
    1872           0 : }
    1873             : 
    1874             : void
    1875           0 : ieee80211_release_node(struct ieee80211com *ic, struct ieee80211_node *ni)
    1876             : {
    1877             :         int s;
    1878             : 
    1879             :         DPRINTF(("%s refcnt %u\n", ether_sprintf(ni->ni_macaddr),
    1880             :             ni->ni_refcnt));
    1881           0 :         s = splnet();
    1882           0 :         if (ieee80211_node_decref(ni) == 0) {
    1883           0 :                 if (ni->ni_unref_cb) {
    1884           0 :                         (*ni->ni_unref_cb)(ic, ni);
    1885           0 :                         ni->ni_unref_cb = NULL;
    1886             :                         /* Freed by callback if necessary: */
    1887           0 :                         ni->ni_unref_arg = NULL;
    1888           0 :                         ni->ni_unref_arg_size = 0;
    1889           0 :                 }
    1890           0 :                 if (ni->ni_state == IEEE80211_STA_COLLECT)
    1891           0 :                         ieee80211_free_node(ic, ni);
    1892             :         }
    1893           0 :         splx(s);
    1894           0 : }
    1895             : 
    1896             : void
    1897           0 : ieee80211_free_allnodes(struct ieee80211com *ic, int clear_ic_bss)
    1898             : {
    1899             :         struct ieee80211_node *ni;
    1900             :         int s;
    1901             : 
    1902             :         DPRINTF(("freeing all nodes\n"));
    1903           0 :         s = splnet();
    1904           0 :         while ((ni = RBT_MIN(ieee80211_tree, &ic->ic_tree)) != NULL)
    1905           0 :                 ieee80211_free_node(ic, ni);
    1906           0 :         splx(s);
    1907             : 
    1908           0 :         if (clear_ic_bss && ic->ic_bss != NULL)
    1909           0 :                 ieee80211_node_cleanup(ic, ic->ic_bss);      /* for station mode */
    1910           0 : }
    1911             : 
    1912             : void
    1913           0 : ieee80211_clean_cached(struct ieee80211com *ic)
    1914             : {
    1915             :         struct ieee80211_node *ni, *next_ni;
    1916             :         int s;
    1917             : 
    1918           0 :         s = splnet();
    1919           0 :         for (ni = RBT_MIN(ieee80211_tree, &ic->ic_tree);
    1920           0 :             ni != NULL; ni = next_ni) {
    1921           0 :                 next_ni = RBT_NEXT(ieee80211_tree, ni);
    1922           0 :                 if (ni->ni_state == IEEE80211_STA_CACHE)
    1923           0 :                         ieee80211_free_node(ic, ni);
    1924             :         }
    1925           0 :         splx(s);
    1926           0 : }
    1927             : /*
    1928             :  * Timeout inactive nodes.
    1929             :  *
    1930             :  * If called because of a cache timeout, which happens only in hostap and ibss
    1931             :  * modes, clean all inactive cached or authenticated nodes but don't de-auth
    1932             :  * any associated nodes. Also update HT protection settings.
    1933             :  *
    1934             :  * Else, this function is called because a new node must be allocated but the
    1935             :  * node cache is full. In this case, return as soon as a free slot was made
    1936             :  * available. If acting as hostap, clean cached nodes regardless of their
    1937             :  * recent activity and also allow de-authing of authenticated nodes older
    1938             :  * than one cache wait interval, and de-authing of inactive associated nodes.
    1939             :  */
    1940             : void
    1941           0 : ieee80211_clean_nodes(struct ieee80211com *ic, int cache_timeout)
    1942             : {
    1943             :         struct ieee80211_node *ni, *next_ni;
    1944           0 :         u_int gen = ic->ic_scangen++;                /* NB: ok 'cuz single-threaded*/
    1945             :         int s;
    1946             : #ifndef IEEE80211_STA_ONLY
    1947             :         int nnodes = 0, nonht = 0, nonhtassoc = 0;
    1948           0 :         struct ifnet *ifp = &ic->ic_if;
    1949             :         enum ieee80211_htprot htprot = IEEE80211_HTPROT_NONE;
    1950             :         enum ieee80211_protmode protmode = IEEE80211_PROT_NONE;
    1951             : #endif
    1952             : 
    1953           0 :         s = splnet();
    1954           0 :         for (ni = RBT_MIN(ieee80211_tree, &ic->ic_tree);
    1955           0 :             ni != NULL; ni = next_ni) {
    1956           0 :                 next_ni = RBT_NEXT(ieee80211_tree, ni);
    1957           0 :                 if (!cache_timeout && ic->ic_nnodes < ic->ic_max_nnodes)
    1958             :                         break;
    1959           0 :                 if (ni->ni_scangen == gen)   /* previously handled */
    1960             :                         continue;
    1961             : #ifndef IEEE80211_STA_ONLY
    1962           0 :                 nnodes++;
    1963           0 :                 if ((ic->ic_flags & IEEE80211_F_HTON) && cache_timeout) {
    1964           0 :                         if (!ieee80211_node_supports_ht(ni)) {
    1965           0 :                                 nonht++;
    1966           0 :                                 if (ni->ni_state == IEEE80211_STA_ASSOC)
    1967           0 :                                         nonhtassoc++;
    1968             :                         }
    1969             :                 }
    1970             : #endif
    1971           0 :                 ni->ni_scangen = gen;
    1972           0 :                 if (ni->ni_refcnt > 0)
    1973             :                         continue;
    1974             : #ifndef IEEE80211_STA_ONLY
    1975           0 :                 if ((ic->ic_opmode == IEEE80211_M_HOSTAP ||
    1976           0 :                     ic->ic_opmode == IEEE80211_M_IBSS) &&
    1977           0 :                     ic->ic_state == IEEE80211_S_RUN) {
    1978           0 :                         if (cache_timeout) {
    1979           0 :                                 if (ni->ni_state != IEEE80211_STA_COLLECT &&
    1980           0 :                                     (ni->ni_state == IEEE80211_STA_ASSOC ||
    1981           0 :                                     ni->ni_inact < IEEE80211_INACT_MAX))
    1982             :                                         continue;
    1983             :                         } else {
    1984           0 :                                 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
    1985           0 :                                     ((ni->ni_state == IEEE80211_STA_ASSOC &&
    1986           0 :                                     ni->ni_inact < IEEE80211_INACT_MAX) ||
    1987           0 :                                     (ni->ni_state == IEEE80211_STA_AUTH &&
    1988           0 :                                      ni->ni_inact == 0)))
    1989             :                                         continue;
    1990             : 
    1991           0 :                                 if (ic->ic_opmode == IEEE80211_M_IBSS &&
    1992           0 :                                     ni->ni_state != IEEE80211_STA_COLLECT &&
    1993           0 :                                     ni->ni_state != IEEE80211_STA_CACHE &&
    1994           0 :                                     ni->ni_inact < IEEE80211_INACT_MAX)
    1995             :                                         continue;
    1996             :                         }
    1997             :                 }
    1998           0 :                 if (ifp->if_flags & IFF_DEBUG)
    1999           0 :                         printf("%s: station %s purged from node cache\n",
    2000           0 :                             ifp->if_xname, ether_sprintf(ni->ni_macaddr));
    2001             : #endif
    2002             :                 /*
    2003             :                  * If we're hostap and the node is authenticated, send
    2004             :                  * a deauthentication frame. The node will be freed when
    2005             :                  * the driver calls ieee80211_release_node().
    2006             :                  */
    2007             : #ifndef IEEE80211_STA_ONLY
    2008             :                 nnodes--;
    2009           0 :                 if ((ic->ic_flags & IEEE80211_F_HTON) && cache_timeout) {
    2010           0 :                         if (!ieee80211_node_supports_ht(ni)) {
    2011           0 :                                 nonht--;
    2012           0 :                                 if (ni->ni_state == IEEE80211_STA_ASSOC)
    2013           0 :                                         nonhtassoc--;
    2014             :                         }
    2015             :                 }
    2016           0 :                 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
    2017           0 :                     ni->ni_state >= IEEE80211_STA_AUTH &&
    2018           0 :                     ni->ni_state != IEEE80211_STA_COLLECT) {
    2019           0 :                         IEEE80211_SEND_MGMT(ic, ni,
    2020             :                             IEEE80211_FC0_SUBTYPE_DEAUTH,
    2021             :                             IEEE80211_REASON_AUTH_EXPIRE);
    2022           0 :                         ieee80211_node_leave(ic, ni);
    2023           0 :                 } else
    2024             : #endif
    2025           0 :                         ieee80211_free_node(ic, ni);
    2026           0 :                 ic->ic_stats.is_node_timeout++;
    2027           0 :         }
    2028             : 
    2029             : #ifndef IEEE80211_STA_ONLY
    2030           0 :         if ((ic->ic_flags & IEEE80211_F_HTON) && cache_timeout) {
    2031             :                 /* Update HT protection settings. */
    2032           0 :                 if (nonht) {
    2033             :                         protmode = IEEE80211_PROT_RTSCTS;
    2034           0 :                         if (nonhtassoc)
    2035           0 :                                 htprot = IEEE80211_HTPROT_NONHT_MIXED;
    2036             :                         else
    2037             :                                 htprot = IEEE80211_HTPROT_NONMEMBER;
    2038             :                 }
    2039           0 :                 if (ic->ic_bss->ni_htop1 != htprot) {
    2040           0 :                         ic->ic_bss->ni_htop1 = htprot;
    2041           0 :                         ic->ic_protmode = protmode;
    2042           0 :                         if (ic->ic_update_htprot)
    2043           0 :                                 ic->ic_update_htprot(ic, ic->ic_bss);
    2044             :                 }
    2045             :         }
    2046             : 
    2047             :         /* 
    2048             :          * During a cache timeout we iterate over all nodes.
    2049             :          * Check for node leaks by comparing the actual number of cached
    2050             :          * nodes with the ic_nnodes count, which is maintained while adding
    2051             :          * and removing nodes from the cache.
    2052             :          */
    2053           0 :         if ((ifp->if_flags & IFF_DEBUG) && cache_timeout &&
    2054           0 :             nnodes != ic->ic_nnodes)
    2055           0 :                 printf("%s: number of cached nodes is %d, expected %d,"
    2056           0 :                     "possible nodes leak\n", ifp->if_xname, nnodes,
    2057             :                     ic->ic_nnodes);
    2058             : #endif
    2059           0 :         splx(s);
    2060           0 : }
    2061             : 
    2062             : void
    2063           0 : ieee80211_iterate_nodes(struct ieee80211com *ic, ieee80211_iter_func *f,
    2064             :     void *arg)
    2065             : {
    2066             :         struct ieee80211_node *ni;
    2067             :         int s;
    2068             : 
    2069           0 :         s = splnet();
    2070           0 :         RBT_FOREACH(ni, ieee80211_tree, &ic->ic_tree)
    2071           0 :                 (*f)(arg, ni);
    2072           0 :         splx(s);
    2073           0 : }
    2074             : 
    2075             : 
    2076             : /*
    2077             :  * Install received HT caps information in the node's state block.
    2078             :  */
    2079             : void
    2080           0 : ieee80211_setup_htcaps(struct ieee80211_node *ni, const uint8_t *data,
    2081             :     uint8_t len)
    2082             : {
    2083             :         uint16_t rxrate;
    2084             : 
    2085           0 :         if (len != 26)
    2086           0 :                 return;
    2087             : 
    2088           0 :         ni->ni_htcaps = (data[0] | (data[1] << 8));
    2089           0 :         ni->ni_ampdu_param = data[2];
    2090             : 
    2091           0 :         memcpy(ni->ni_rxmcs, &data[3], sizeof(ni->ni_rxmcs));
    2092             :         /* clear reserved bits */
    2093           0 :         clrbit(ni->ni_rxmcs, 77);
    2094           0 :         clrbit(ni->ni_rxmcs, 78);
    2095           0 :         clrbit(ni->ni_rxmcs, 79);
    2096             : 
    2097             :         /* Max MCS Rx rate in 1Mb/s units (0 means "not specified"). */
    2098           0 :         rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH);
    2099           0 :         if (rxrate < 1024)
    2100           0 :                 ni->ni_max_rxrate = rxrate;
    2101             : 
    2102           0 :         ni->ni_tx_mcs_set = data[15];
    2103           0 :         ni->ni_htxcaps = (data[19] | (data[20] << 8));
    2104           0 :         ni->ni_txbfcaps = (data[21] | (data[22] << 8) | (data[23] << 16) |
    2105           0 :                 (data[24] << 24));
    2106           0 :         ni->ni_aselcaps = data[25];
    2107           0 : }
    2108             : 
    2109             : #ifndef IEEE80211_STA_ONLY
    2110             : /* 
    2111             :  * Handle nodes switching from 11n into legacy modes.
    2112             :  */
    2113             : void
    2114           0 : ieee80211_clear_htcaps(struct ieee80211_node *ni)
    2115             : {
    2116           0 :         ni->ni_htcaps = 0;
    2117           0 :         ni->ni_ampdu_param = 0;
    2118           0 :         memset(ni->ni_rxmcs, 0, sizeof(ni->ni_rxmcs));
    2119           0 :         ni->ni_max_rxrate = 0;
    2120           0 :         ni->ni_tx_mcs_set = 0;
    2121           0 :         ni->ni_htxcaps = 0;
    2122           0 :         ni->ni_txbfcaps = 0;
    2123           0 :         ni->ni_aselcaps = 0;
    2124             : 
    2125           0 :         ni->ni_flags &= ~IEEE80211_NODE_HT;
    2126             : 
    2127           0 : }
    2128             : #endif
    2129             : 
    2130             : /*
    2131             :  * Install received HT op information in the node's state block.
    2132             :  */
    2133             : int
    2134           0 : ieee80211_setup_htop(struct ieee80211_node *ni, const uint8_t *data,
    2135             :     uint8_t len, int isprobe)
    2136             : {
    2137           0 :         if (len != 22)
    2138           0 :                 return 0;
    2139             : 
    2140           0 :         ni->ni_primary_chan = data[0]; /* XXX corresponds to ni_chan */
    2141             : 
    2142           0 :         ni->ni_htop0 = data[1];
    2143           0 :         ni->ni_htop1 = (data[2] | (data[3] << 8));
    2144           0 :         ni->ni_htop2 = (data[3] | (data[4] << 8));
    2145             : 
    2146             :         /*
    2147             :          * According to 802.11-2012 Table 8-130 the Basic MCS set is
    2148             :          * only "present in Beacon, Probe Response, Mesh Peering Open
    2149             :          * and Mesh Peering Confirm frames. Otherwise reserved."
    2150             :          */
    2151           0 :         if (isprobe)
    2152           0 :                 memcpy(ni->ni_basic_mcs, &data[6], sizeof(ni->ni_basic_mcs));
    2153             : 
    2154           0 :         return 1;
    2155           0 : }
    2156             : 
    2157             : /*
    2158             :  * Install received rate set information in the node's state block.
    2159             :  */
    2160             : int
    2161           0 : ieee80211_setup_rates(struct ieee80211com *ic, struct ieee80211_node *ni,
    2162             :     const u_int8_t *rates, const u_int8_t *xrates, int flags)
    2163             : {
    2164           0 :         struct ieee80211_rateset *rs = &ni->ni_rates;
    2165             : 
    2166           0 :         memset(rs, 0, sizeof(*rs));
    2167           0 :         rs->rs_nrates = rates[1];
    2168           0 :         memcpy(rs->rs_rates, rates + 2, rs->rs_nrates);
    2169           0 :         if (xrates != NULL) {
    2170             :                 u_int8_t nxrates;
    2171             :                 /*
    2172             :                  * Tack on 11g extended supported rate element.
    2173             :                  */
    2174           0 :                 nxrates = xrates[1];
    2175           0 :                 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
    2176           0 :                         nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
    2177             :                         DPRINTF(("extended rate set too large; "
    2178             :                             "only using %u of %u rates\n",
    2179             :                             nxrates, xrates[1]));
    2180           0 :                         ic->ic_stats.is_rx_rstoobig++;
    2181           0 :                 }
    2182           0 :                 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
    2183           0 :                 rs->rs_nrates += nxrates;
    2184           0 :         }
    2185           0 :         return ieee80211_fix_rate(ic, ni, flags);
    2186             : }
    2187             : 
    2188             : #ifndef IEEE80211_STA_ONLY
    2189             : /*
    2190             :  * Check if the specified node supports ERP.
    2191             :  */
    2192             : int
    2193           0 : ieee80211_iserp_sta(const struct ieee80211_node *ni)
    2194             : {
    2195             :         static const u_int8_t rates[] = { 2, 4, 11, 22, 12, 24, 48 };
    2196           0 :         const struct ieee80211_rateset *rs = &ni->ni_rates;
    2197             :         int i, j;
    2198             : 
    2199             :         /*
    2200             :          * A STA supports ERP operation if it includes all the Clause 19
    2201             :          * mandatory rates in its supported rate set.
    2202             :          */
    2203           0 :         for (i = 0; i < nitems(rates); i++) {
    2204           0 :                 for (j = 0; j < rs->rs_nrates; j++) {
    2205           0 :                         if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == rates[i])
    2206             :                                 break;
    2207             :                 }
    2208           0 :                 if (j == rs->rs_nrates)
    2209           0 :                         return 0;
    2210             :         }
    2211           0 :         return 1;
    2212           0 : }
    2213             : 
    2214             : /*
    2215             :  * This function is called to notify the 802.1X PACP machine that a new
    2216             :  * 802.1X port is enabled and must be authenticated. For 802.11, a port
    2217             :  * becomes enabled whenever a STA successfully completes Open System
    2218             :  * authentication with an AP.
    2219             :  */
    2220             : void
    2221           0 : ieee80211_needs_auth(struct ieee80211com *ic, struct ieee80211_node *ni)
    2222             : {
    2223             :         /*
    2224             :          * XXX this could be done via the route socket of via a dedicated
    2225             :          * EAP socket or another kernel->userland notification mechanism.
    2226             :          * The notification should include the MAC address (ni_macaddr).
    2227             :          */
    2228           0 : }
    2229             : 
    2230             : /*
    2231             :  * Handle an HT STA joining an HT network.
    2232             :  */
    2233             : void
    2234           0 : ieee80211_node_join_ht(struct ieee80211com *ic, struct ieee80211_node *ni)
    2235             : {
    2236             :         enum ieee80211_htprot;
    2237             : 
    2238             :         /* Update HT protection setting. */
    2239           0 :         if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) {
    2240           0 :                 ic->ic_bss->ni_htop1 = IEEE80211_HTPROT_NONHT_MIXED;
    2241           0 :                 if (ic->ic_update_htprot)
    2242           0 :                         ic->ic_update_htprot(ic, ic->ic_bss);
    2243             :         }
    2244           0 : }
    2245             : 
    2246             : /*
    2247             :  * Handle a station joining an RSN network.
    2248             :  */
    2249             : void
    2250           0 : ieee80211_node_join_rsn(struct ieee80211com *ic, struct ieee80211_node *ni)
    2251             : {
    2252             :         DPRINTF(("station %s associated using proto %d akm 0x%x "
    2253             :             "cipher 0x%x groupcipher 0x%x\n", ether_sprintf(ni->ni_macaddr),
    2254             :             ni->ni_rsnprotos, ni->ni_rsnakms, ni->ni_rsnciphers,
    2255             :             ni->ni_rsngroupcipher));
    2256             : 
    2257           0 :         ni->ni_rsn_state = RSNA_AUTHENTICATION;
    2258             : 
    2259           0 :         ni->ni_key_count = 0;
    2260           0 :         ni->ni_port_valid = 0;
    2261           0 :         ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT;
    2262           0 :         ni->ni_flags &= ~IEEE80211_NODE_RSN_NEW_PTK;
    2263           0 :         ni->ni_replaycnt = -1;       /* XXX */
    2264           0 :         ni->ni_rsn_retries = 0;
    2265           0 :         ni->ni_rsncipher = ni->ni_rsnciphers;
    2266             : 
    2267           0 :         ni->ni_rsn_state = RSNA_AUTHENTICATION_2;
    2268             : 
    2269             :         /* generate a new authenticator nonce (ANonce) */
    2270           0 :         arc4random_buf(ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
    2271             : 
    2272           0 :         if (!ieee80211_is_8021x_akm(ni->ni_rsnakms)) {
    2273           0 :                 memcpy(ni->ni_pmk, ic->ic_psk, IEEE80211_PMK_LEN);
    2274           0 :                 ni->ni_flags |= IEEE80211_NODE_PMK;
    2275           0 :                 (void)ieee80211_send_4way_msg1(ic, ni);
    2276           0 :         } else if (ni->ni_flags & IEEE80211_NODE_PMK) {
    2277             :                 /* skip 802.1X auth if a cached PMK was found */
    2278           0 :                 (void)ieee80211_send_4way_msg1(ic, ni);
    2279           0 :         } else {
    2280             :                 /* no cached PMK found, needs full 802.1X auth */
    2281           0 :                 ieee80211_needs_auth(ic, ni);
    2282             :         }
    2283           0 : }
    2284             : 
    2285             : void
    2286           0 : ieee80211_count_longslotsta(void *arg, struct ieee80211_node *ni)
    2287             : {
    2288           0 :         int *longslotsta = arg;
    2289             : 
    2290           0 :         if (ni->ni_associd == 0 || ni->ni_state == IEEE80211_STA_COLLECT)
    2291           0 :                 return;
    2292             : 
    2293           0 :         if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME))
    2294           0 :                 (*longslotsta)++;
    2295           0 : }
    2296             : 
    2297             : void
    2298           0 : ieee80211_count_nonerpsta(void *arg, struct ieee80211_node *ni)
    2299             : {
    2300           0 :         int *nonerpsta = arg;
    2301             : 
    2302           0 :         if (ni->ni_associd == 0 || ni->ni_state == IEEE80211_STA_COLLECT)
    2303           0 :                 return;
    2304             : 
    2305           0 :         if (!ieee80211_iserp_sta(ni))
    2306           0 :                 (*nonerpsta)++;
    2307           0 : }
    2308             : 
    2309             : void
    2310           0 : ieee80211_count_pssta(void *arg, struct ieee80211_node *ni)
    2311             : {
    2312           0 :         int *pssta = arg;
    2313             : 
    2314           0 :         if (ni->ni_associd == 0 || ni->ni_state == IEEE80211_STA_COLLECT)
    2315           0 :                 return;
    2316             : 
    2317           0 :         if (ni->ni_pwrsave == IEEE80211_PS_DOZE)
    2318           0 :                 (*pssta)++;
    2319           0 : }
    2320             : 
    2321             : void
    2322           0 : ieee80211_count_rekeysta(void *arg, struct ieee80211_node *ni)
    2323             : {
    2324           0 :         int *rekeysta = arg;
    2325             : 
    2326           0 :         if (ni->ni_associd == 0 || ni->ni_state == IEEE80211_STA_COLLECT)
    2327           0 :                 return;
    2328             : 
    2329           0 :         if (ni->ni_flags & IEEE80211_NODE_REKEY)
    2330           0 :                 (*rekeysta)++;
    2331           0 : }
    2332             : 
    2333             : /*
    2334             :  * Handle a station joining an 11g network.
    2335             :  */
    2336             : void
    2337           0 : ieee80211_node_join_11g(struct ieee80211com *ic, struct ieee80211_node *ni)
    2338             : {
    2339           0 :         int longslotsta = 0, nonerpsta = 0;
    2340             : 
    2341           0 :         if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) {
    2342             :                 /*
    2343             :                  * Joining STA doesn't support short slot time.  We must
    2344             :                  * disable the use of short slot time for all other associated
    2345             :                  * STAs and give the driver a chance to reconfigure the
    2346             :                  * hardware.
    2347             :                  */
    2348           0 :                 ieee80211_iterate_nodes(ic,
    2349             :                     ieee80211_count_longslotsta, &longslotsta);
    2350           0 :                 if (longslotsta == 1) {
    2351           0 :                         if (ic->ic_caps & IEEE80211_C_SHSLOT)
    2352           0 :                                 ieee80211_set_shortslottime(ic, 0);
    2353             :                 }
    2354             :                 DPRINTF(("[%s] station needs long slot time, count %d\n",
    2355             :                     ether_sprintf(ni->ni_macaddr), longslotsta));
    2356             :         }
    2357             : 
    2358           0 :         if (!ieee80211_iserp_sta(ni)) {
    2359             :                 /*
    2360             :                  * Joining STA is non-ERP.
    2361             :                  */
    2362           0 :                 ieee80211_iterate_nodes(ic,
    2363             :                     ieee80211_count_nonerpsta, &nonerpsta);
    2364             :                 DPRINTF(("[%s] station is non-ERP, %d non-ERP "
    2365             :                     "stations associated\n", ether_sprintf(ni->ni_macaddr),
    2366             :                     nonerpsta));
    2367             :                 /* must enable the use of protection */
    2368           0 :                 if (ic->ic_protmode != IEEE80211_PROT_NONE) {
    2369             :                         DPRINTF(("enable use of protection\n"));
    2370           0 :                         ic->ic_flags |= IEEE80211_F_USEPROT;
    2371           0 :                 }
    2372             : 
    2373           0 :                 if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
    2374           0 :                         ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
    2375             :         } else
    2376           0 :                 ni->ni_flags |= IEEE80211_NODE_ERP;
    2377           0 : }
    2378             : 
    2379             : void
    2380           0 : ieee80211_node_join(struct ieee80211com *ic, struct ieee80211_node *ni,
    2381             :     int resp)
    2382             : {
    2383           0 :         int newassoc = (ni->ni_state != IEEE80211_STA_ASSOC);
    2384             : 
    2385           0 :         if (ni->ni_associd == 0) {
    2386             :                 u_int16_t aid;
    2387             : 
    2388             :                 /*
    2389             :                  * It would be clever to search the bitmap
    2390             :                  * more efficiently, but this will do for now.
    2391             :                  */
    2392           0 :                 for (aid = 1; aid < ic->ic_max_aid; aid++) {
    2393           0 :                         if (!IEEE80211_AID_ISSET(aid,
    2394             :                             ic->ic_aid_bitmap))
    2395             :                                 break;
    2396             :                 }
    2397           0 :                 if (aid >= ic->ic_max_aid) {
    2398           0 :                         IEEE80211_SEND_MGMT(ic, ni, resp,
    2399             :                             IEEE80211_REASON_ASSOC_TOOMANY);
    2400           0 :                         ieee80211_node_leave(ic, ni);
    2401           0 :                         return;
    2402             :                 }
    2403           0 :                 ni->ni_associd = aid | 0xc000;
    2404           0 :                 IEEE80211_AID_SET(ni->ni_associd, ic->ic_aid_bitmap);
    2405           0 :                 if (ic->ic_curmode == IEEE80211_MODE_11G ||
    2406           0 :                     (ic->ic_curmode == IEEE80211_MODE_11N &&
    2407           0 :                     IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan)))
    2408           0 :                         ieee80211_node_join_11g(ic, ni);
    2409           0 :         }
    2410             : 
    2411             :         DPRINTF(("station %s %s associated at aid %d\n",
    2412             :             ether_sprintf(ni->ni_macaddr), newassoc ? "newly" : "already",
    2413             :             ni->ni_associd & ~0xc000));
    2414             : 
    2415           0 :         ieee80211_ht_negotiate(ic, ni);
    2416           0 :         if (ic->ic_flags & IEEE80211_F_HTON)
    2417           0 :                 ieee80211_node_join_ht(ic, ni);
    2418             : 
    2419             :         /* give driver a chance to setup state like ni_txrate */
    2420           0 :         if (ic->ic_newassoc)
    2421           0 :                 (*ic->ic_newassoc)(ic, ni, newassoc);
    2422           0 :         IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
    2423           0 :         ieee80211_node_newstate(ni, IEEE80211_STA_ASSOC);
    2424             : 
    2425           0 :         if (!(ic->ic_flags & IEEE80211_F_RSNON)) {
    2426           0 :                 ni->ni_port_valid = 1;
    2427           0 :                 ni->ni_rsncipher = IEEE80211_CIPHER_USEGROUP;
    2428           0 :         } else
    2429           0 :                 ieee80211_node_join_rsn(ic, ni);
    2430             : 
    2431             : #if NBRIDGE > 0
    2432             :         /*
    2433             :          * If the parent interface is a bridgeport, learn
    2434             :          * the node's address dynamically on this interface.
    2435             :          */
    2436           0 :         if (ic->ic_if.if_bridgeport != NULL)
    2437           0 :                 bridge_update(&ic->ic_if,
    2438           0 :                     (struct ether_addr *)ni->ni_macaddr, 0);
    2439             : #endif
    2440           0 : }
    2441             : 
    2442             : /*
    2443             :  * Handle an HT STA leaving an HT network.
    2444             :  */
    2445             : void
    2446           0 : ieee80211_node_leave_ht(struct ieee80211com *ic, struct ieee80211_node *ni)
    2447             : {
    2448             :         struct ieee80211_rx_ba *ba;
    2449             :         u_int8_t tid;
    2450             :         int i;
    2451             : 
    2452             :         /* free all Block Ack records */
    2453           0 :         ieee80211_ba_del(ni);
    2454           0 :         for (tid = 0; tid < IEEE80211_NUM_TID; tid++) {
    2455           0 :                 ba = &ni->ni_rx_ba[tid];
    2456           0 :                 if (ba->ba_buf != NULL) {
    2457           0 :                         for (i = 0; i < IEEE80211_BA_MAX_WINSZ; i++)
    2458           0 :                                 m_freem(ba->ba_buf[i].m);
    2459           0 :                         free(ba->ba_buf, M_DEVBUF,
    2460             :                             IEEE80211_BA_MAX_WINSZ * sizeof(*ba->ba_buf));
    2461           0 :                         ba->ba_buf = NULL;
    2462           0 :                 }
    2463             :         }
    2464             : 
    2465           0 :         ieee80211_clear_htcaps(ni);
    2466           0 : }
    2467             : 
    2468             : /*
    2469             :  * Handle a station leaving an RSN network.
    2470             :  */
    2471             : void
    2472           0 : ieee80211_node_leave_rsn(struct ieee80211com *ic, struct ieee80211_node *ni)
    2473             : {
    2474           0 :         int rekeysta = 0;
    2475             : 
    2476           0 :         ni->ni_rsn_state = RSNA_DISCONNECTED;
    2477             : 
    2478           0 :         ni->ni_rsn_state = RSNA_INITIALIZE;
    2479           0 :         if (ni->ni_flags & IEEE80211_NODE_REKEY) {
    2480           0 :                 ni->ni_flags &= ~IEEE80211_NODE_REKEY;
    2481           0 :                 ieee80211_iterate_nodes(ic,
    2482             :                     ieee80211_count_rekeysta, &rekeysta);
    2483           0 :                 if (rekeysta == 0)
    2484           0 :                         ieee80211_setkeysdone(ic);
    2485             :         }
    2486           0 :         ni->ni_flags &= ~IEEE80211_NODE_PMK;
    2487           0 :         ni->ni_rsn_gstate = RSNA_IDLE;
    2488             : 
    2489           0 :         timeout_del(&ni->ni_eapol_to);
    2490           0 :         timeout_del(&ni->ni_sa_query_to);
    2491             : 
    2492           0 :         ni->ni_rsn_retries = 0;
    2493           0 :         ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT;
    2494           0 :         ni->ni_port_valid = 0;
    2495           0 :         (*ic->ic_delete_key)(ic, ni, &ni->ni_pairwise_key);
    2496           0 : }
    2497             : 
    2498             : /*
    2499             :  * Handle a station leaving an 11g network.
    2500             :  */
    2501             : void
    2502           0 : ieee80211_node_leave_11g(struct ieee80211com *ic, struct ieee80211_node *ni)
    2503             : {
    2504           0 :         int longslotsta = 0, nonerpsta = 0;
    2505             : 
    2506           0 :         if (!(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)) {
    2507             :                 /* leaving STA did not support short slot time */
    2508           0 :                 ieee80211_iterate_nodes(ic,
    2509             :                     ieee80211_count_longslotsta, &longslotsta);
    2510           0 :                 if (longslotsta == 1) {
    2511             :                         /*
    2512             :                          * All associated STAs now support short slot time, so
    2513             :                          * enable this feature and give the driver a chance to
    2514             :                          * reconfigure the hardware. Notice that IBSS always
    2515             :                          * use a long slot time.
    2516             :                          */
    2517           0 :                         if ((ic->ic_caps & IEEE80211_C_SHSLOT) &&
    2518           0 :                             ic->ic_opmode != IEEE80211_M_IBSS)
    2519           0 :                                 ieee80211_set_shortslottime(ic, 1);
    2520             :                 }
    2521             :                 DPRINTF(("[%s] long slot time station leaves, count %d\n",
    2522             :                     ether_sprintf(ni->ni_macaddr), longslotsta));
    2523             :         }
    2524             : 
    2525           0 :         if (!(ni->ni_flags & IEEE80211_NODE_ERP)) {
    2526             :                 /* leaving STA was non-ERP */
    2527           0 :                 ieee80211_iterate_nodes(ic,
    2528             :                     ieee80211_count_nonerpsta, &nonerpsta);
    2529           0 :                 if (nonerpsta == 1) {
    2530             :                         /*
    2531             :                          * All associated STAs are now ERP capable, disable use
    2532             :                          * of protection and re-enable short preamble support.
    2533             :                          */
    2534           0 :                         ic->ic_flags &= ~IEEE80211_F_USEPROT;
    2535           0 :                         if (ic->ic_caps & IEEE80211_C_SHPREAMBLE)
    2536           0 :                                 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
    2537             :                 }
    2538             :                 DPRINTF(("[%s] non-ERP station leaves, count %d\n",
    2539             :                     ether_sprintf(ni->ni_macaddr), nonerpsta));
    2540             :         }
    2541           0 : }
    2542             : 
    2543             : /*
    2544             :  * Handle bookkeeping for station deauthentication/disassociation
    2545             :  * when operating as an ap.
    2546             :  */
    2547             : void
    2548           0 : ieee80211_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni)
    2549             : {
    2550           0 :         if (ic->ic_opmode != IEEE80211_M_HOSTAP)
    2551           0 :                 panic("not in ap mode, mode %u", ic->ic_opmode);
    2552             : 
    2553           0 :         if (ni->ni_state == IEEE80211_STA_COLLECT)
    2554             :                 return;
    2555             :         /*
    2556             :          * If node wasn't previously associated all we need to do is
    2557             :          * reclaim the reference.
    2558             :          */
    2559           0 :         if (ni->ni_associd == 0) {
    2560           0 :                 ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT);
    2561           0 :                 return;
    2562             :         }
    2563             : 
    2564           0 :         if (ni->ni_pwrsave == IEEE80211_PS_DOZE)
    2565           0 :                 ni->ni_pwrsave = IEEE80211_PS_AWAKE;
    2566             : 
    2567           0 :         if (mq_purge(&ni->ni_savedq) > 0) {
    2568           0 :                 if (ic->ic_set_tim != NULL)
    2569           0 :                         (*ic->ic_set_tim)(ic, ni->ni_associd, 0);
    2570             :         }
    2571             : 
    2572           0 :         if (ic->ic_flags & IEEE80211_F_RSNON)
    2573           0 :                 ieee80211_node_leave_rsn(ic, ni);
    2574             : 
    2575           0 :         if (ic->ic_curmode == IEEE80211_MODE_11G ||
    2576           0 :             (ic->ic_curmode == IEEE80211_MODE_11N &&
    2577           0 :             IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan)))
    2578           0 :                 ieee80211_node_leave_11g(ic, ni);
    2579             : 
    2580           0 :         if (ni->ni_flags & IEEE80211_NODE_HT)
    2581           0 :                 ieee80211_node_leave_ht(ic, ni);
    2582             : 
    2583           0 :         if (ic->ic_node_leave != NULL)
    2584           0 :                 (*ic->ic_node_leave)(ic, ni);
    2585             : 
    2586           0 :         ieee80211_node_newstate(ni, IEEE80211_STA_COLLECT);
    2587             : 
    2588             : #if NBRIDGE > 0
    2589             :         /*
    2590             :          * If the parent interface is a bridgeport, delete
    2591             :          * any dynamically learned address for this node.
    2592             :          */
    2593           0 :         if (ic->ic_if.if_bridgeport != NULL)
    2594           0 :                 bridge_update(&ic->ic_if,
    2595           0 :                     (struct ether_addr *)ni->ni_macaddr, 1);
    2596             : #endif
    2597           0 : }
    2598             : 
    2599             : static int
    2600           0 : ieee80211_do_slow_print(struct ieee80211com *ic, int *did_print)
    2601             : {
    2602             :         static const struct timeval merge_print_intvl = {
    2603             :                 .tv_sec = 1, .tv_usec = 0
    2604             :         };
    2605           0 :         if ((ic->ic_if.if_flags & IFF_LINK0) == 0)
    2606           0 :                 return 0;
    2607           0 :         if (!*did_print && (ic->ic_if.if_flags & IFF_DEBUG) == 0 &&
    2608           0 :             !ratecheck(&ic->ic_last_merge_print, &merge_print_intvl))
    2609           0 :                 return 0;
    2610             : 
    2611           0 :         *did_print = 1;
    2612           0 :         return 1;
    2613           0 : }
    2614             : 
    2615             : /* ieee80211_ibss_merge helps merge 802.11 ad hoc networks.  The
    2616             :  * convention, set by the Wireless Ethernet Compatibility Alliance
    2617             :  * (WECA), is that an 802.11 station will change its BSSID to match
    2618             :  * the "oldest" 802.11 ad hoc network, on the same channel, that
    2619             :  * has the station's desired SSID.  The "oldest" 802.11 network
    2620             :  * sends beacons with the greatest TSF timestamp.
    2621             :  *
    2622             :  * Return ENETRESET if the BSSID changed, 0 otherwise.
    2623             :  *
    2624             :  * XXX Perhaps we should compensate for the time that elapses
    2625             :  * between the MAC receiving the beacon and the host processing it
    2626             :  * in ieee80211_ibss_merge.
    2627             :  */
    2628             : int
    2629           0 : ieee80211_ibss_merge(struct ieee80211com *ic, struct ieee80211_node *ni,
    2630             :     u_int64_t local_tsft)
    2631             : {
    2632             :         u_int64_t beacon_tsft;
    2633           0 :         int did_print = 0, sign;
    2634             :         union {
    2635             :                 u_int64_t       word;
    2636             :                 u_int8_t        tstamp[8];
    2637             :         } u;
    2638             : 
    2639             :         /* ensure alignment */
    2640           0 :         (void)memcpy(&u, &ni->ni_tstamp[0], sizeof(u));
    2641             :         beacon_tsft = letoh64(u.word);
    2642             : 
    2643             :         /* we are faster, let the other guy catch up */
    2644           0 :         if (beacon_tsft < local_tsft)
    2645           0 :                 sign = -1;
    2646             :         else
    2647             :                 sign = 1;
    2648             : 
    2649           0 :         if (IEEE80211_ADDR_EQ(ni->ni_bssid, ic->ic_bss->ni_bssid)) {
    2650           0 :                 if (!ieee80211_do_slow_print(ic, &did_print))
    2651           0 :                         return 0;
    2652           0 :                 printf("%s: tsft offset %s%llu\n", ic->ic_if.if_xname,
    2653           0 :                     (sign < 0) ? "-" : "",
    2654           0 :                     (sign < 0)
    2655           0 :                         ? (local_tsft - beacon_tsft)
    2656           0 :                         : (beacon_tsft - local_tsft));
    2657           0 :                 return 0;
    2658             :         }
    2659             : 
    2660           0 :         if (sign < 0)
    2661           0 :                 return 0;
    2662             : 
    2663           0 :         if (ieee80211_match_bss(ic, ni) != 0)
    2664           0 :                 return 0;
    2665             : 
    2666           0 :         if (ieee80211_do_slow_print(ic, &did_print)) {
    2667           0 :                 printf("%s: ieee80211_ibss_merge: bssid mismatch %s\n",
    2668           0 :                     ic->ic_if.if_xname, ether_sprintf(ni->ni_bssid));
    2669           0 :                 printf("%s: my tsft %llu beacon tsft %llu\n",
    2670             :                     ic->ic_if.if_xname, local_tsft, beacon_tsft);
    2671           0 :                 printf("%s: sync TSF with %s\n",
    2672           0 :                     ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr));
    2673           0 :         }
    2674             : 
    2675           0 :         ic->ic_flags &= ~IEEE80211_F_SIBSS;
    2676             : 
    2677             :         /* negotiate rates with new IBSS */
    2678           0 :         ieee80211_fix_rate(ic, ni, IEEE80211_F_DOFRATE |
    2679             :             IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
    2680           0 :         if (ni->ni_rates.rs_nrates == 0) {
    2681           0 :                 if (ieee80211_do_slow_print(ic, &did_print)) {
    2682           0 :                         printf("%s: rates mismatch, BSSID %s\n",
    2683           0 :                             ic->ic_if.if_xname, ether_sprintf(ni->ni_bssid));
    2684           0 :                 }
    2685           0 :                 return 0;
    2686             :         }
    2687             : 
    2688           0 :         if (ieee80211_do_slow_print(ic, &did_print)) {
    2689           0 :                 printf("%s: sync BSSID %s -> ",
    2690           0 :                     ic->ic_if.if_xname, ether_sprintf(ic->ic_bss->ni_bssid));
    2691           0 :                 printf("%s ", ether_sprintf(ni->ni_bssid));
    2692           0 :                 printf("(from %s)\n", ether_sprintf(ni->ni_macaddr));
    2693           0 :         }
    2694             : 
    2695           0 :         ieee80211_node_newstate(ni, IEEE80211_STA_BSS);
    2696           0 :         (*ic->ic_node_copy)(ic, ic->ic_bss, ni);
    2697             : 
    2698           0 :         return ENETRESET;
    2699           0 : }
    2700             : 
    2701             : void
    2702           0 : ieee80211_set_tim(struct ieee80211com *ic, int aid, int set)
    2703             : {
    2704           0 :         if (set)
    2705           0 :                 setbit(ic->ic_tim_bitmap, aid & ~0xc000);
    2706             :         else
    2707           0 :                 clrbit(ic->ic_tim_bitmap, aid & ~0xc000);
    2708           0 : }
    2709             : 
    2710             : /*
    2711             :  * This function shall be called by drivers immediately after every DTIM.
    2712             :  * Transmit all group addressed MSDUs buffered at the AP.
    2713             :  */
    2714             : void
    2715           0 : ieee80211_notify_dtim(struct ieee80211com *ic)
    2716             : {
    2717             :         /* NB: group addressed MSDUs are buffered in ic_bss */
    2718           0 :         struct ieee80211_node *ni = ic->ic_bss;
    2719           0 :         struct ifnet *ifp = &ic->ic_if;
    2720             :         struct ieee80211_frame *wh;
    2721             :         struct mbuf *m;
    2722             : 
    2723           0 :         KASSERT(ic->ic_opmode == IEEE80211_M_HOSTAP);
    2724             : 
    2725           0 :         while ((m = mq_dequeue(&ni->ni_savedq)) != NULL) {
    2726           0 :                 if (!mq_empty(&ni->ni_savedq)) {
    2727             :                         /* more queued frames, set the more data bit */
    2728           0 :                         wh = mtod(m, struct ieee80211_frame *);
    2729           0 :                         wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
    2730           0 :                 }
    2731           0 :                 mq_enqueue(&ic->ic_pwrsaveq, m);
    2732           0 :                 if_start(ifp);
    2733             :         }
    2734             :         /* XXX assumes everything has been sent */
    2735           0 :         ic->ic_tim_mcast_pending = 0;
    2736           0 : }
    2737             : #endif  /* IEEE80211_STA_ONLY */
    2738             : 
    2739             : /*
    2740             :  * Compare nodes in the tree by lladdr
    2741             :  */
    2742             : int
    2743           0 : ieee80211_node_cmp(const struct ieee80211_node *b1,
    2744             :     const struct ieee80211_node *b2)
    2745             : {
    2746           0 :         return (memcmp(b1->ni_macaddr, b2->ni_macaddr, IEEE80211_ADDR_LEN));
    2747             : }
    2748             : 
    2749             : /*
    2750             :  * Compare nodes in the tree by essid
    2751             :  */
    2752             : int
    2753           0 : ieee80211_ess_cmp(const struct ieee80211_ess_rbt *b1,
    2754             :     const struct ieee80211_ess_rbt *b2)
    2755             : {
    2756           0 :         return (memcmp(b1->essid, b2->essid, IEEE80211_NWID_LEN));
    2757             : }
    2758             : 
    2759             : /*
    2760             :  * Generate red-black tree function logic
    2761             :  */
    2762           0 : RBT_GENERATE(ieee80211_tree, ieee80211_node, ni_node, ieee80211_node_cmp);
    2763           0 : RBT_GENERATE(ieee80211_ess_tree, ieee80211_ess_rbt, ess_rbt, ieee80211_ess_cmp);

Generated by: LCOV version 1.13