From: phessler Date: Sun, 9 Sep 2018 20:32:55 +0000 (+0000) Subject: convert the things we save in 'join' into a single ioctl. mixing related X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=d6390b0875acf7df1eb7768b92f42a92c34e6ca6;p=openbsd convert the things we save in 'join' into a single ioctl. mixing related settings over multiple calls was risky and racy. Pass essid, wpa, and wep paramaters in a single ioctl and process it atomically. no change for 'nwid' users OK stsp@ benno@ --- diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 4ba1eb03d1c..79e6e2d2c27 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifconfig.c,v 1.377 2018/09/08 15:21:03 phessler Exp $ */ +/* $OpenBSD: ifconfig.c,v 1.378 2018/09/09 20:32:55 phessler Exp $ */ /* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */ /* @@ -173,6 +173,8 @@ int showclasses; struct ifencap; +struct ieee80211_join join; + const char *lacpmodeactive = "active"; const char *lacpmodepassive = "passive"; const char *lacptimeoutfast = "fast"; @@ -353,6 +355,7 @@ int actions; /* Actions performed */ #define A_MEDIAOPT (A_MEDIAOPTSET|A_MEDIAOPTCLR) #define A_MEDIAINST 0x0008 /* instance or inst command */ #define A_MEDIAMODE 0x0010 /* mode command */ +#define A_JOIN 0x0020 /* join */ #define A_SILENT 0x8000000 /* doing operation, do not print */ #define NEXTARG0 0xffffff @@ -384,7 +387,7 @@ const struct cmd { { "mtu", NEXTARG, 0, setifmtu }, { "nwid", NEXTARG, 0, setifnwid }, { "-nwid", -1, 0, setifnwid }, - { "join", NEXTARG, 0, setifjoin }, + { "join", NEXTARG, A_JOIN, setifjoin }, { "-join", NEXTARG, 0, delifjoin }, { "joinlist", NEXTARG0, 0, showjoin }, { "-joinlist", -1, 0, delifjoin }, @@ -635,6 +638,8 @@ void print_media_word(uint64_t, int, int); void process_media_commands(void); void init_current_media(void); +void process_join_commands(void); + unsigned long get_ts_map(int, int, int); void in_status(int); @@ -874,6 +879,8 @@ nextarg: return (0); } + process_join_commands(); + /* Process any media commands that may have been issued. */ process_media_commands(); @@ -1691,10 +1698,23 @@ setifnwid(const char *val, int d) warn("SIOCS80211NWID"); } + +void +process_join_commands(void) +{ + int len; + + if (!(actions & A_JOIN)) + return; + + ifr.ifr_data = (caddr_t)&join; + if (ioctl(s, SIOCS80211JOIN, (caddr_t)&ifr) < 0) + warn("SIOCS80211JOIN"); +} + void setifjoin(const char *val, int d) { - struct ieee80211_join join; int len; if (strlen(nwidname) != 0) { @@ -1713,9 +1733,8 @@ setifjoin(const char *val, int d) join.i_len = len; (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); (void)strlcpy(joinname, join.i_nwid, sizeof(joinname)); - ifr.ifr_data = (caddr_t)&join; - if (ioctl(s, SIOCS80211JOIN, (caddr_t)&ifr) < 0) - warn("SIOCS80211JOIN"); + + actions |= A_JOIN; } void @@ -1857,6 +1876,13 @@ setifnwkey(const char *val, int d) } } (void)strlcpy(nwkey.i_name, name, sizeof(nwkey.i_name)); + + if (actions & A_JOIN) { + memcpy(&join.i_nwkey, &nwkey, sizeof(join.i_nwkey)); + join.i_flags |= IEEE80211_JOIN_NWKEY; + return; + } + if (ioctl(s, SIOCS80211NWKEY, (caddr_t)&nwkey) == -1) warn("SIOCS80211NWKEY"); } @@ -1871,6 +1897,13 @@ setifwpa(const char *val, int d) (void)strlcpy(wpa.i_name, name, sizeof(wpa.i_name)); /* Don't read current values. The kernel will set defaults. */ wpa.i_enabled = d; + + if (actions & A_JOIN) { + memcpy(&join.i_wpaparams, &wpa, sizeof(join.i_wpaparams)); + join.i_flags |= IEEE80211_JOIN_WPA; + return; + } + if (ioctl(s, SIOCS80211WPAPARMS, (caddr_t)&wpa) < 0) err(1, "SIOCS80211WPAPARMS"); } @@ -1905,6 +1938,13 @@ setifwpaprotos(const char *val, int d) /* Let the kernel set up the appropriate default ciphers. */ wpa.i_ciphers = 0; wpa.i_groupcipher = 0; + + if (actions & A_JOIN) { + memcpy(&join.i_wpaparams, &wpa, sizeof(join.i_wpaparams)); + join.i_flags |= IEEE80211_JOIN_WPA; + return; + } + if (ioctl(s, SIOCS80211WPAPARMS, (caddr_t)&wpa) < 0) err(1, "SIOCS80211WPAPARMS"); } @@ -1938,6 +1978,13 @@ setifwpaakms(const char *val, int d) wpa.i_akms = rval; /* Enable WPA for 802.1x here. PSK case is handled in setifwpakey(). */ wpa.i_enabled = ((rval & IEEE80211_WPA_AKM_8021X) != 0); + + if (actions & A_JOIN) { + memcpy(&join.i_wpaparams, &wpa, sizeof(join.i_wpaparams)); + join.i_flags |= IEEE80211_JOIN_WPA; + return; + } + if (ioctl(s, SIOCS80211WPAPARMS, (caddr_t)&wpa) < 0) err(1, "SIOCS80211WPAPARMS"); } @@ -1990,6 +2037,13 @@ setifwpaciphers(const char *val, int d) if (ioctl(s, SIOCG80211WPAPARMS, (caddr_t)&wpa) < 0) err(1, "SIOCG80211WPAPARMS"); wpa.i_ciphers = rval; + + if (actions & A_JOIN) { + memcpy(&join.i_wpaparams, &wpa, sizeof(join.i_wpaparams)); + join.i_flags |= IEEE80211_JOIN_WPA; + return; + } + if (ioctl(s, SIOCS80211WPAPARMS, (caddr_t)&wpa) < 0) err(1, "SIOCS80211WPAPARMS"); } @@ -2010,6 +2064,13 @@ setifwpagroupcipher(const char *val, int d) if (ioctl(s, SIOCG80211WPAPARMS, (caddr_t)&wpa) < 0) err(1, "SIOCG80211WPAPARMS"); wpa.i_groupcipher = cipher; + + if (actions & A_JOIN) { + memcpy(&join.i_wpaparams, &wpa, sizeof(join.i_wpaparams)); + join.i_flags |= IEEE80211_JOIN_WPA; + return; + } + if (ioctl(s, SIOCS80211WPAPARMS, (caddr_t)&wpa) < 0) err(1, "SIOCS80211WPAPARMS"); } @@ -2066,6 +2127,15 @@ setifwpakey(const char *val, int d) psk.i_enabled = 0; (void)strlcpy(psk.i_name, name, sizeof(psk.i_name)); + + if (actions & A_JOIN) { + memcpy(&join.i_wpapsk, &psk, sizeof(join.i_wpapsk)); + join.i_flags |= IEEE80211_JOIN_WPAPSK; + if (!join.i_wpaparams.i_enabled) + setifwpa(NULL, join.i_wpapsk.i_enabled); + return; + } + if (ioctl(s, SIOCS80211WPAPSK, (caddr_t)&psk) < 0) err(1, "SIOCS80211WPAPSK"); diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index f144979e3a7..65c6948414e 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_ioctl.c,v 1.64 2018/09/01 08:20:56 stsp Exp $ */ +/* $OpenBSD: ieee80211_ioctl.c,v 1.65 2018/09/09 20:32:55 phessler Exp $ */ /* $NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung Exp $ */ /*- @@ -196,6 +196,7 @@ ieee80211_disable_rsn(struct ieee80211com *ic) ic->ic_rsnciphers = 0; } +/* Keep in sync with ieee80211_node.c:ieee80211_ess_setnwkeys() */ static int ieee80211_ioctl_setnwkeys(struct ieee80211com *ic, const struct ieee80211_nwkey *nwkey) @@ -270,6 +271,7 @@ ieee80211_ioctl_getnwkeys(struct ieee80211com *ic, return 0; } +/* Keep in sync with ieee80211_node.c:ieee80211_ess_setwpaparms() */ static int ieee80211_ioctl_setwpaparms(struct ieee80211com *ic, const struct ieee80211_wpaparams *wpa) @@ -467,15 +469,10 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } if (join.i_flags & IEEE80211_JOIN_DEL) ieee80211_del_ess(ic, join.i_nwid, join.i_len ? 0 : 1); - memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN); - ic->ic_des_esslen = join.i_len; - memcpy(ic->ic_des_essid, join.i_nwid, join.i_len); - /* disable WPA/WEP */ - ieee80211_disable_rsn(ic); - ieee80211_disable_wep(ic); + /* save nwid for auto-join */ if (!(join.i_flags & IEEE80211_JOIN_DEL)) { - if (ieee80211_add_ess(ic, 0, 0) == 0) + if (ieee80211_add_ess(ic, &join) == 0) ic->ic_flags |= IEEE80211_F_AUTO_JOIN; } ieee80211_set_ess(ic, ic->ic_des_essid); @@ -523,8 +520,6 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if ((error = suser(curproc)) != 0) break; error = ieee80211_ioctl_setnwkeys(ic, (void *)data); - if (error == ENETRESET) - ieee80211_add_ess(ic, 0, 1); break; case SIOCG80211NWKEY: error = ieee80211_ioctl_getnwkeys(ic, (void *)data); @@ -533,8 +528,6 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if ((error = suser(curproc)) != 0) break; error = ieee80211_ioctl_setwpaparms(ic, (void *)data); - if (error == ENETRESET) - ieee80211_add_ess(ic, 1, 0); break; case SIOCG80211WPAPARMS: error = ieee80211_ioctl_getwpaparms(ic, (void *)data); @@ -552,7 +545,6 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ic->ic_flags &= ~IEEE80211_F_PSK; memset(ic->ic_psk, 0, sizeof(ic->ic_psk)); } - ieee80211_add_ess(ic, 1, 0); error = ENETRESET; break; case SIOCG80211WPAPSK: diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h index 561ac0f038b..868ff95b835 100644 --- a/sys/net80211/ieee80211_ioctl.h +++ b/sys/net80211/ieee80211_ioctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_ioctl.h,v 1.33 2018/08/06 11:42:18 benno Exp $ */ +/* $OpenBSD: ieee80211_ioctl.h,v 1.34 2018/09/09 20:32:55 phessler Exp $ */ /* $NetBSD: ieee80211_ioctl.h,v 1.7 2004/04/30 22:51:04 dyoung Exp $ */ /*- @@ -285,8 +285,9 @@ struct ieee80211_join { u_int8_t i_nwid[IEEE80211_NWID_LEN]; u_int32_t i_flags; - struct ieee80211_wpapsk i_wpapsk; - struct ieee80211_nwkey i_nwkey; + struct ieee80211_wpaparams i_wpaparams; + struct ieee80211_wpapsk i_wpapsk; + struct ieee80211_nwkey i_nwkey; }; struct ieee80211_joinreq_all { @@ -302,6 +303,7 @@ struct ieee80211_joinreq_all { #define IEEE80211_JOIN_DEL 0x04 #define IEEE80211_JOIN_NWKEY 0x08 #define IEEE80211_JOIN_WPA 0x10 +#define IEEE80211_JOIN_WPAPSK 0x20 /* node and requests */ struct ieee80211_nodereq { diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index b35195b99c0..306b3616181 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.c,v 1.144 2018/09/06 11:50:54 jsg Exp $ */ +/* $OpenBSD: ieee80211_node.c,v 1.145 2018/09/09 20:32:55 phessler Exp $ */ /* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */ /*- @@ -176,6 +176,20 @@ ieee80211_print_ess_list(struct ieee80211com *ic) } } +struct ieee80211_ess * +ieee80211_get_ess(struct ieee80211com *ic, const char *nwid, int len) +{ + struct ieee80211_ess *ess; + + TAILQ_FOREACH(ess, &ic->ic_ess, ess_next) { + if (len == ess->esslen && + memcmp(ess->essid, nwid, ess->esslen) == 0) + return ess; + } + + return NULL; +} + void ieee80211_del_ess(struct ieee80211com *ic, char *nwid, int all) { @@ -193,8 +207,118 @@ ieee80211_del_ess(struct ieee80211com *ic, char *nwid, int all) } } +/* Keep in sync with ieee80211_ioctl.c:ieee80211_ioctl_setnwkeys() */ +static int +ieee80211_ess_setnwkeys(struct ieee80211_ess *ess, + const struct ieee80211_nwkey *nwkey) +{ + struct ieee80211_key *k; + int i; + + if (nwkey->i_wepon == IEEE80211_NWKEY_OPEN) { + if (!(ess->flags & IEEE80211_F_WEPON)) + return 0; + ess->flags &= ~IEEE80211_F_WEPON; + return ENETRESET; + } + if (nwkey->i_defkid < 1 || nwkey->i_defkid > IEEE80211_WEP_NKID) + return EINVAL; + + for (i = 0; i < IEEE80211_WEP_NKID; i++) { + if (nwkey->i_key[i].i_keylen == 0 || + nwkey->i_key[i].i_keydat == NULL) + continue; /* entry not set */ + if (nwkey->i_key[i].i_keylen > IEEE80211_KEYBUF_SIZE) + return EINVAL; + + /* map wep key to ieee80211_key */ + k = &ess->nw_keys[i]; + memset(k, 0, sizeof(*k)); + if (nwkey->i_key[i].i_keylen <= 5) + k->k_cipher = IEEE80211_CIPHER_WEP40; + else + k->k_cipher = IEEE80211_CIPHER_WEP104; + k->k_len = ieee80211_cipher_keylen(k->k_cipher); + k->k_flags = IEEE80211_KEY_GROUP | IEEE80211_KEY_TX; + } + ess->def_txkey = nwkey->i_defkid - 1; + ess->flags |= IEEE80211_F_WEPON; + + return ENETRESET; +} + + +/* Keep in sync with ieee80211_ioctl.c:ieee80211_ioctl_setwpaparms() */ +static int +ieee80211_ess_setwpaparms(struct ieee80211_ess *ess, + const struct ieee80211_wpaparams *wpa) +{ + if (!wpa->i_enabled) { + if (!(ess->flags & IEEE80211_F_RSNON)) + return 0; + ess->flags &= ~IEEE80211_F_RSNON; + ess->rsnprotos = 0; + ess->rsnakms = 0; + ess->rsngroupcipher = 0; + ess->rsnciphers = 0; + return ENETRESET; + } + + ess->rsnprotos = 0; + if (wpa->i_protos & IEEE80211_WPA_PROTO_WPA1) + ess->rsnprotos |= IEEE80211_PROTO_WPA; + if (wpa->i_protos & IEEE80211_WPA_PROTO_WPA2) + ess->rsnprotos |= IEEE80211_PROTO_RSN; + if (ess->rsnprotos == 0) /* set to default (RSN) */ + ess->rsnprotos = IEEE80211_PROTO_RSN; + + ess->rsnakms = 0; + if (wpa->i_akms & IEEE80211_WPA_AKM_PSK) + ess->rsnakms |= IEEE80211_AKM_PSK; + if (wpa->i_akms & IEEE80211_WPA_AKM_SHA256_PSK) + ess->rsnakms |= IEEE80211_AKM_SHA256_PSK; + if (wpa->i_akms & IEEE80211_WPA_AKM_8021X) + ess->rsnakms |= IEEE80211_AKM_8021X; + if (wpa->i_akms & IEEE80211_WPA_AKM_SHA256_8021X) + ess->rsnakms |= IEEE80211_AKM_SHA256_8021X; + if (ess->rsnakms == 0) /* set to default (PSK) */ + ess->rsnakms = IEEE80211_AKM_PSK; + + if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_WEP40) + ess->rsngroupcipher = IEEE80211_CIPHER_WEP40; + else if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_TKIP) + ess->rsngroupcipher = IEEE80211_CIPHER_TKIP; + else if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_CCMP) + ess->rsngroupcipher = IEEE80211_CIPHER_CCMP; + else if (wpa->i_groupcipher == IEEE80211_WPA_CIPHER_WEP104) + ess->rsngroupcipher = IEEE80211_CIPHER_WEP104; + else { /* set to default */ + if (ess->rsnprotos & IEEE80211_PROTO_WPA) + ess->rsngroupcipher = IEEE80211_CIPHER_TKIP; + else + ess->rsngroupcipher = IEEE80211_CIPHER_CCMP; + } + + ess->rsnciphers = 0; + if (wpa->i_ciphers & IEEE80211_WPA_CIPHER_TKIP) + ess->rsnciphers |= IEEE80211_CIPHER_TKIP; + if (wpa->i_ciphers & IEEE80211_WPA_CIPHER_CCMP) + ess->rsnciphers |= IEEE80211_CIPHER_CCMP; + if (wpa->i_ciphers & IEEE80211_WPA_CIPHER_USEGROUP) + ess->rsnciphers = IEEE80211_CIPHER_USEGROUP; + if (ess->rsnciphers == 0) { /* set to default (CCMP, TKIP if WPA1) */ + ess->rsnciphers = IEEE80211_CIPHER_CCMP; + if (ess->rsnprotos & IEEE80211_PROTO_WPA) + ess->rsnciphers |= IEEE80211_CIPHER_TKIP; + } + + ess->flags |= IEEE80211_F_RSNON; + + return ENETRESET; +} + int -ieee80211_add_ess(struct ieee80211com *ic, int wpa, int wep) +ieee80211_add_ess(struct ieee80211com *ic, struct ieee80211_join *join) { struct ieee80211_ess *ess; int i = 0, new = 0, ness = 0; @@ -204,23 +328,21 @@ ieee80211_add_ess(struct ieee80211com *ic, int wpa, int wep) return (0); /* Don't save an empty nwid */ - if (ic->ic_des_esslen == 0) + if (join->i_len == 0) return (0); TAILQ_FOREACH(ess, &ic->ic_ess, ess_next) { - if (ess->esslen == ic->ic_des_esslen && - memcmp(ess->essid, ic->ic_des_essid, ess->esslen) == 0) + if (ess->esslen == join->i_len && + memcmp(ess->essid, join->i_nwid, ess->esslen) == 0) break; ness++; } - KASSERTMSG(wpa == 0 || wep == 0, - "%s: both wpa and wep are configured", __func__); - if (ess == NULL) { /* if not found, and wpa/wep are set, then return */ - if (wpa != 0 || wep != 0) { - return (ENOENT); + if ((join->i_flags & IEEE80211_JOIN_WPA) && + (join->i_flags & IEEE80211_JOIN_NWKEY)) { + return (EINVAL); } if (ness > IEEE80211_CACHE_SIZE) return (ERANGE); @@ -228,22 +350,23 @@ ieee80211_add_ess(struct ieee80211com *ic, int wpa, int wep) ess = malloc(sizeof(*ess), M_DEVBUF, M_NOWAIT|M_ZERO); if (ess == NULL) return (ENOMEM); - memcpy(ess->essid, ic->ic_des_essid, ic->ic_des_esslen); - ess->esslen = ic->ic_des_esslen; + memcpy(ess->essid, join->i_nwid, join->i_len); + ess->esslen = join->i_len; } - if (wpa) { - if (ic->ic_flags & (IEEE80211_F_RSNON|IEEE80211_F_PSK)) { - ess->flags = IEEE80211_F_RSNON; - if (ic->ic_flags & IEEE80211_F_PSK) - ess->flags |= IEEE80211_F_PSK; - explicit_bzero(ess->psk, sizeof(ess->psk)); - memcpy(ess->psk, ic->ic_psk, IEEE80211_PMK_LEN); - ess->rsnprotos = ic->ic_rsnprotos; - ess->rsnakms = ic->ic_rsnakms; - ess->rsngroupcipher = ic->ic_rsngroupcipher; - ess->rsnciphers = ic->ic_rsnciphers; + if (join->i_flags & IEEE80211_JOIN_WPA) { + if (join->i_wpaparams.i_enabled) { + if (!(ic->ic_caps & IEEE80211_C_RSN)) + return ENODEV; + ieee80211_ess_setwpaparms(ess, + &join->i_wpaparams); + if (join->i_flags & IEEE80211_JOIN_WPAPSK) { + ess->flags |= IEEE80211_F_PSK; + explicit_bzero(ess->psk, sizeof(ess->psk)); + memcpy(ess->psk, &join->i_wpapsk.i_psk, + sizeof(ess->psk)); + } /* Disable WEP */ for (i = 0; i < IEEE80211_WEP_NKID; i++) { explicit_bzero(&ess->nw_keys[i], @@ -258,19 +381,12 @@ ieee80211_add_ess(struct ieee80211com *ic, int wpa, int wep) explicit_bzero(ess->psk, sizeof(ess->psk)); ess->flags &= ~(IEEE80211_F_PSK | IEEE80211_F_RSNON); } - } else if (wep) { - if (ic->ic_flags & IEEE80211_F_WEPON) { - struct ieee80211_key *k; - int i; + } else if (join->i_flags & IEEE80211_JOIN_NWKEY) { + if (join->i_nwkey.i_wepon) { + if (!(ic->ic_caps & IEEE80211_C_WEP)) + return ENODEV; - ess->flags = IEEE80211_F_WEPON; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - memcpy(&ess->nw_keys[i], &ic->ic_nw_keys[i], - sizeof(struct ieee80211_key)); - k = &ic->ic_nw_keys[i]; - k->k_priv = NULL; - } - ess->def_txkey = ic->ic_def_txkey; + ieee80211_ess_setnwkeys(ess, &join->i_nwkey); /* Disable WPA */ ess->rsnprotos = ess->rsnakms = diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index c5a1bd3b14a..686e31510ef 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_var.h,v 1.88 2018/09/01 08:20:56 stsp Exp $ */ +/* $OpenBSD: ieee80211_var.h,v 1.89 2018/09/09 20:32:55 phessler Exp $ */ /* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */ /*- @@ -452,9 +452,10 @@ enum ieee80211_phymode ieee80211_chan2mode(struct ieee80211com *, const struct ieee80211_channel *); void ieee80211_disable_wep(struct ieee80211com *); void ieee80211_disable_rsn(struct ieee80211com *); -int ieee80211_add_ess(struct ieee80211com *, int, int); +int ieee80211_add_ess(struct ieee80211com *, struct ieee80211_join *); void ieee80211_del_ess(struct ieee80211com *, char *, int); void ieee80211_set_ess(struct ieee80211com *, char *); +struct ieee80211_ess *ieee80211_get_ess(struct ieee80211com *, const char *, int); extern int ieee80211_cache_size;