1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
|
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ioctl.c 184205 2008-10-23 15:53:51Z des $");
| 28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ioctl.c 184210 2008-10-23 19:57:13Z des $");
|
29 30/* 31 * IEEE 802.11 ioctl support (FreeBSD-specific) 32 */ 33 34#include "opt_inet.h" 35#include "opt_ipx.h" 36#include "opt_wlan.h" 37 38#include <sys/endian.h> 39#include <sys/param.h> 40#include <sys/kernel.h> 41#include <sys/priv.h> 42#include <sys/socket.h> 43#include <sys/sockio.h> 44#include <sys/systm.h> 45 46#include <net/if.h> 47#include <net/if_dl.h> 48#include <net/if_media.h> 49#include <net/ethernet.h> 50 51#ifdef INET 52#include <netinet/in.h> 53#include <netinet/if_ether.h> 54#endif 55 56#ifdef IPX 57#include <netipx/ipx.h> 58#include <netipx/ipx_if.h> 59#endif 60 61#include <net80211/ieee80211_var.h> 62#include <net80211/ieee80211_ioctl.h> 63#include <net80211/ieee80211_regdomain.h> 64#include <net80211/ieee80211_input.h> 65 66#define IS_UP_AUTO(_vap) \ 67 (IFNET_IS_UP_RUNNING(vap->iv_ifp) && \ 68 (_vap)->iv_roaming == IEEE80211_ROAMING_AUTO) 69 70static const uint8_t zerobssid[IEEE80211_ADDR_LEN]; 71static struct ieee80211_channel *findchannel(struct ieee80211com *, 72 int ieee, int mode); 73 74static __noinline int 75ieee80211_ioctl_getkey(struct ieee80211vap *vap, struct ieee80211req *ireq) 76{ 77 struct ieee80211com *ic = vap->iv_ic; 78 struct ieee80211_node *ni; 79 struct ieee80211req_key ik; 80 struct ieee80211_key *wk; 81 const struct ieee80211_cipher *cip; 82 u_int kid; 83 int error; 84 85 if (ireq->i_len != sizeof(ik)) 86 return EINVAL; 87 error = copyin(ireq->i_data, &ik, sizeof(ik)); 88 if (error) 89 return error; 90 kid = ik.ik_keyix; 91 if (kid == IEEE80211_KEYIX_NONE) { 92 ni = ieee80211_find_vap_node(&ic->ic_sta, vap, ik.ik_macaddr); 93 if (ni == NULL) 94 return ENOENT; 95 wk = &ni->ni_ucastkey; 96 } else { 97 if (kid >= IEEE80211_WEP_NKID) 98 return EINVAL; 99 wk = &vap->iv_nw_keys[kid]; 100 IEEE80211_ADDR_COPY(&ik.ik_macaddr, vap->iv_bss->ni_macaddr); 101 ni = NULL; 102 } 103 cip = wk->wk_cipher; 104 ik.ik_type = cip->ic_cipher; 105 ik.ik_keylen = wk->wk_keylen; 106 ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV); 107 if (wk->wk_keyix == vap->iv_def_txkey) 108 ik.ik_flags |= IEEE80211_KEY_DEFAULT; 109 if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { 110 /* NB: only root can read key data */ 111 ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID]; 112 ik.ik_keytsc = wk->wk_keytsc; 113 memcpy(ik.ik_keydata, wk->wk_key, wk->wk_keylen); 114 if (cip->ic_cipher == IEEE80211_CIPHER_TKIP) { 115 memcpy(ik.ik_keydata+wk->wk_keylen, 116 wk->wk_key + IEEE80211_KEYBUF_SIZE, 117 IEEE80211_MICBUF_SIZE); 118 ik.ik_keylen += IEEE80211_MICBUF_SIZE; 119 } 120 } else { 121 ik.ik_keyrsc = 0; 122 ik.ik_keytsc = 0; 123 memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata)); 124 } 125 if (ni != NULL) 126 ieee80211_free_node(ni); 127 return copyout(&ik, ireq->i_data, sizeof(ik)); 128} 129 130static __noinline int 131ieee80211_ioctl_getchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq) 132{ 133 struct ieee80211com *ic = vap->iv_ic; 134 135 if (sizeof(ic->ic_chan_active) < ireq->i_len) 136 ireq->i_len = sizeof(ic->ic_chan_active); 137 return copyout(&ic->ic_chan_active, ireq->i_data, ireq->i_len); 138} 139 140static __noinline int 141ieee80211_ioctl_getchaninfo(struct ieee80211vap *vap, struct ieee80211req *ireq) 142{ 143 struct ieee80211com *ic = vap->iv_ic; 144 int space; 145 146 space = __offsetof(struct ieee80211req_chaninfo, 147 ic_chans[ic->ic_nchans]); 148 if (space > ireq->i_len) 149 space = ireq->i_len; 150 /* XXX assumes compatible layout */ 151 return copyout(&ic->ic_nchans, ireq->i_data, space); 152} 153 154static __noinline int 155ieee80211_ioctl_getwpaie(struct ieee80211vap *vap, 156 struct ieee80211req *ireq, int req) 157{ 158 struct ieee80211_node *ni; 159 struct ieee80211req_wpaie2 wpaie; 160 int error; 161 162 if (ireq->i_len < IEEE80211_ADDR_LEN) 163 return EINVAL; 164 error = copyin(ireq->i_data, wpaie.wpa_macaddr, IEEE80211_ADDR_LEN); 165 if (error != 0) 166 return error; 167 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, wpaie.wpa_macaddr); 168 if (ni == NULL) 169 return ENOENT; 170 memset(wpaie.wpa_ie, 0, sizeof(wpaie.wpa_ie)); 171 if (ni->ni_ies.wpa_ie != NULL) { 172 int ielen = ni->ni_ies.wpa_ie[1] + 2; 173 if (ielen > sizeof(wpaie.wpa_ie)) 174 ielen = sizeof(wpaie.wpa_ie); 175 memcpy(wpaie.wpa_ie, ni->ni_ies.wpa_ie, ielen); 176 } 177 if (req == IEEE80211_IOC_WPAIE2) { 178 memset(wpaie.rsn_ie, 0, sizeof(wpaie.rsn_ie)); 179 if (ni->ni_ies.rsn_ie != NULL) { 180 int ielen = ni->ni_ies.rsn_ie[1] + 2; 181 if (ielen > sizeof(wpaie.rsn_ie)) 182 ielen = sizeof(wpaie.rsn_ie); 183 memcpy(wpaie.rsn_ie, ni->ni_ies.rsn_ie, ielen); 184 } 185 if (ireq->i_len > sizeof(struct ieee80211req_wpaie2)) 186 ireq->i_len = sizeof(struct ieee80211req_wpaie2); 187 } else { 188 /* compatibility op, may overwrite wpa ie */ 189 /* XXX check ic_flags? */ 190 if (ni->ni_ies.rsn_ie != NULL) { 191 int ielen = ni->ni_ies.rsn_ie[1] + 2; 192 if (ielen > sizeof(wpaie.wpa_ie)) 193 ielen = sizeof(wpaie.wpa_ie); 194 memcpy(wpaie.wpa_ie, ni->ni_ies.rsn_ie, ielen); 195 } 196 if (ireq->i_len > sizeof(struct ieee80211req_wpaie)) 197 ireq->i_len = sizeof(struct ieee80211req_wpaie); 198 } 199 ieee80211_free_node(ni); 200 return copyout(&wpaie, ireq->i_data, ireq->i_len); 201} 202 203static __noinline int 204ieee80211_ioctl_getstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) 205{ 206 struct ieee80211_node *ni; 207 uint8_t macaddr[IEEE80211_ADDR_LEN]; 208 const int off = __offsetof(struct ieee80211req_sta_stats, is_stats); 209 int error; 210 211 if (ireq->i_len < off) 212 return EINVAL; 213 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 214 if (error != 0) 215 return error; 216 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 217 if (ni == NULL) 218 return ENOENT; 219 if (ireq->i_len > sizeof(struct ieee80211req_sta_stats)) 220 ireq->i_len = sizeof(struct ieee80211req_sta_stats); 221 /* NB: copy out only the statistics */ 222 error = copyout(&ni->ni_stats, (uint8_t *) ireq->i_data + off, 223 ireq->i_len - off); 224 ieee80211_free_node(ni); 225 return error; 226} 227 228struct scanreq { 229 struct ieee80211req_scan_result *sr; 230 size_t space; 231}; 232 233static size_t 234scan_space(const struct ieee80211_scan_entry *se, int *ielen) 235{ 236 size_t len; 237 238 *ielen = se->se_ies.len; 239 /* 240 * NB: ie's can be no more than 255 bytes and the max 802.11 241 * packet is <3Kbytes so we are sure this doesn't overflow 242 * 16-bits; if this is a concern we can drop the ie's. 243 */ 244 len = sizeof(struct ieee80211req_scan_result) + se->se_ssid[1] + *ielen; 245 return roundup(len, sizeof(uint32_t)); 246} 247 248static void 249get_scan_space(void *arg, const struct ieee80211_scan_entry *se) 250{ 251 struct scanreq *req = arg; 252 int ielen; 253 254 req->space += scan_space(se, &ielen); 255} 256 257static __noinline void 258get_scan_result(void *arg, const struct ieee80211_scan_entry *se) 259{ 260 struct scanreq *req = arg; 261 struct ieee80211req_scan_result *sr; 262 int ielen, len, nr, nxr; 263 uint8_t *cp; 264 265 len = scan_space(se, &ielen); 266 if (len > req->space) 267 return; 268 269 sr = req->sr; 270 KASSERT(len <= 65535 && ielen <= 65535, 271 ("len %u ssid %u ie %u", len, se->se_ssid[1], ielen)); 272 sr->isr_len = len; 273 sr->isr_ie_off = sizeof(struct ieee80211req_scan_result); 274 sr->isr_ie_len = ielen; 275 sr->isr_freq = se->se_chan->ic_freq; 276 sr->isr_flags = se->se_chan->ic_flags; 277 sr->isr_rssi = se->se_rssi; 278 sr->isr_noise = se->se_noise; 279 sr->isr_intval = se->se_intval; 280 sr->isr_capinfo = se->se_capinfo; 281 sr->isr_erp = se->se_erp; 282 IEEE80211_ADDR_COPY(sr->isr_bssid, se->se_bssid); 283 nr = min(se->se_rates[1], IEEE80211_RATE_MAXSIZE); 284 memcpy(sr->isr_rates, se->se_rates+2, nr); 285 nxr = min(se->se_xrates[1], IEEE80211_RATE_MAXSIZE - nr); 286 memcpy(sr->isr_rates+nr, se->se_xrates+2, nxr); 287 sr->isr_nrates = nr + nxr; 288 289 sr->isr_ssid_len = se->se_ssid[1]; 290 cp = ((uint8_t *)sr) + sr->isr_ie_off; 291 memcpy(cp, se->se_ssid+2, sr->isr_ssid_len); 292 293 if (ielen) { 294 cp += sr->isr_ssid_len; 295 memcpy(cp, se->se_ies.data, ielen); 296 } 297 298 req->space -= len; 299 req->sr = (struct ieee80211req_scan_result *)(((uint8_t *)sr) + len); 300} 301 302static __noinline int 303ieee80211_ioctl_getscanresults(struct ieee80211vap *vap, 304 struct ieee80211req *ireq) 305{ 306 struct scanreq req; 307 int error; 308 309 if (ireq->i_len < sizeof(struct scanreq)) 310 return EFAULT; 311 312 error = 0; 313 req.space = 0; 314 ieee80211_scan_iterate(vap, get_scan_space, &req); 315 if (req.space > ireq->i_len) 316 req.space = ireq->i_len; 317 if (req.space > 0) { 318 size_t space; 319 void *p; 320 321 space = req.space; 322 /* XXX M_WAITOK after driver lock released */
| 29 30/* 31 * IEEE 802.11 ioctl support (FreeBSD-specific) 32 */ 33 34#include "opt_inet.h" 35#include "opt_ipx.h" 36#include "opt_wlan.h" 37 38#include <sys/endian.h> 39#include <sys/param.h> 40#include <sys/kernel.h> 41#include <sys/priv.h> 42#include <sys/socket.h> 43#include <sys/sockio.h> 44#include <sys/systm.h> 45 46#include <net/if.h> 47#include <net/if_dl.h> 48#include <net/if_media.h> 49#include <net/ethernet.h> 50 51#ifdef INET 52#include <netinet/in.h> 53#include <netinet/if_ether.h> 54#endif 55 56#ifdef IPX 57#include <netipx/ipx.h> 58#include <netipx/ipx_if.h> 59#endif 60 61#include <net80211/ieee80211_var.h> 62#include <net80211/ieee80211_ioctl.h> 63#include <net80211/ieee80211_regdomain.h> 64#include <net80211/ieee80211_input.h> 65 66#define IS_UP_AUTO(_vap) \ 67 (IFNET_IS_UP_RUNNING(vap->iv_ifp) && \ 68 (_vap)->iv_roaming == IEEE80211_ROAMING_AUTO) 69 70static const uint8_t zerobssid[IEEE80211_ADDR_LEN]; 71static struct ieee80211_channel *findchannel(struct ieee80211com *, 72 int ieee, int mode); 73 74static __noinline int 75ieee80211_ioctl_getkey(struct ieee80211vap *vap, struct ieee80211req *ireq) 76{ 77 struct ieee80211com *ic = vap->iv_ic; 78 struct ieee80211_node *ni; 79 struct ieee80211req_key ik; 80 struct ieee80211_key *wk; 81 const struct ieee80211_cipher *cip; 82 u_int kid; 83 int error; 84 85 if (ireq->i_len != sizeof(ik)) 86 return EINVAL; 87 error = copyin(ireq->i_data, &ik, sizeof(ik)); 88 if (error) 89 return error; 90 kid = ik.ik_keyix; 91 if (kid == IEEE80211_KEYIX_NONE) { 92 ni = ieee80211_find_vap_node(&ic->ic_sta, vap, ik.ik_macaddr); 93 if (ni == NULL) 94 return ENOENT; 95 wk = &ni->ni_ucastkey; 96 } else { 97 if (kid >= IEEE80211_WEP_NKID) 98 return EINVAL; 99 wk = &vap->iv_nw_keys[kid]; 100 IEEE80211_ADDR_COPY(&ik.ik_macaddr, vap->iv_bss->ni_macaddr); 101 ni = NULL; 102 } 103 cip = wk->wk_cipher; 104 ik.ik_type = cip->ic_cipher; 105 ik.ik_keylen = wk->wk_keylen; 106 ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV); 107 if (wk->wk_keyix == vap->iv_def_txkey) 108 ik.ik_flags |= IEEE80211_KEY_DEFAULT; 109 if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { 110 /* NB: only root can read key data */ 111 ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID]; 112 ik.ik_keytsc = wk->wk_keytsc; 113 memcpy(ik.ik_keydata, wk->wk_key, wk->wk_keylen); 114 if (cip->ic_cipher == IEEE80211_CIPHER_TKIP) { 115 memcpy(ik.ik_keydata+wk->wk_keylen, 116 wk->wk_key + IEEE80211_KEYBUF_SIZE, 117 IEEE80211_MICBUF_SIZE); 118 ik.ik_keylen += IEEE80211_MICBUF_SIZE; 119 } 120 } else { 121 ik.ik_keyrsc = 0; 122 ik.ik_keytsc = 0; 123 memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata)); 124 } 125 if (ni != NULL) 126 ieee80211_free_node(ni); 127 return copyout(&ik, ireq->i_data, sizeof(ik)); 128} 129 130static __noinline int 131ieee80211_ioctl_getchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq) 132{ 133 struct ieee80211com *ic = vap->iv_ic; 134 135 if (sizeof(ic->ic_chan_active) < ireq->i_len) 136 ireq->i_len = sizeof(ic->ic_chan_active); 137 return copyout(&ic->ic_chan_active, ireq->i_data, ireq->i_len); 138} 139 140static __noinline int 141ieee80211_ioctl_getchaninfo(struct ieee80211vap *vap, struct ieee80211req *ireq) 142{ 143 struct ieee80211com *ic = vap->iv_ic; 144 int space; 145 146 space = __offsetof(struct ieee80211req_chaninfo, 147 ic_chans[ic->ic_nchans]); 148 if (space > ireq->i_len) 149 space = ireq->i_len; 150 /* XXX assumes compatible layout */ 151 return copyout(&ic->ic_nchans, ireq->i_data, space); 152} 153 154static __noinline int 155ieee80211_ioctl_getwpaie(struct ieee80211vap *vap, 156 struct ieee80211req *ireq, int req) 157{ 158 struct ieee80211_node *ni; 159 struct ieee80211req_wpaie2 wpaie; 160 int error; 161 162 if (ireq->i_len < IEEE80211_ADDR_LEN) 163 return EINVAL; 164 error = copyin(ireq->i_data, wpaie.wpa_macaddr, IEEE80211_ADDR_LEN); 165 if (error != 0) 166 return error; 167 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, wpaie.wpa_macaddr); 168 if (ni == NULL) 169 return ENOENT; 170 memset(wpaie.wpa_ie, 0, sizeof(wpaie.wpa_ie)); 171 if (ni->ni_ies.wpa_ie != NULL) { 172 int ielen = ni->ni_ies.wpa_ie[1] + 2; 173 if (ielen > sizeof(wpaie.wpa_ie)) 174 ielen = sizeof(wpaie.wpa_ie); 175 memcpy(wpaie.wpa_ie, ni->ni_ies.wpa_ie, ielen); 176 } 177 if (req == IEEE80211_IOC_WPAIE2) { 178 memset(wpaie.rsn_ie, 0, sizeof(wpaie.rsn_ie)); 179 if (ni->ni_ies.rsn_ie != NULL) { 180 int ielen = ni->ni_ies.rsn_ie[1] + 2; 181 if (ielen > sizeof(wpaie.rsn_ie)) 182 ielen = sizeof(wpaie.rsn_ie); 183 memcpy(wpaie.rsn_ie, ni->ni_ies.rsn_ie, ielen); 184 } 185 if (ireq->i_len > sizeof(struct ieee80211req_wpaie2)) 186 ireq->i_len = sizeof(struct ieee80211req_wpaie2); 187 } else { 188 /* compatibility op, may overwrite wpa ie */ 189 /* XXX check ic_flags? */ 190 if (ni->ni_ies.rsn_ie != NULL) { 191 int ielen = ni->ni_ies.rsn_ie[1] + 2; 192 if (ielen > sizeof(wpaie.wpa_ie)) 193 ielen = sizeof(wpaie.wpa_ie); 194 memcpy(wpaie.wpa_ie, ni->ni_ies.rsn_ie, ielen); 195 } 196 if (ireq->i_len > sizeof(struct ieee80211req_wpaie)) 197 ireq->i_len = sizeof(struct ieee80211req_wpaie); 198 } 199 ieee80211_free_node(ni); 200 return copyout(&wpaie, ireq->i_data, ireq->i_len); 201} 202 203static __noinline int 204ieee80211_ioctl_getstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) 205{ 206 struct ieee80211_node *ni; 207 uint8_t macaddr[IEEE80211_ADDR_LEN]; 208 const int off = __offsetof(struct ieee80211req_sta_stats, is_stats); 209 int error; 210 211 if (ireq->i_len < off) 212 return EINVAL; 213 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 214 if (error != 0) 215 return error; 216 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 217 if (ni == NULL) 218 return ENOENT; 219 if (ireq->i_len > sizeof(struct ieee80211req_sta_stats)) 220 ireq->i_len = sizeof(struct ieee80211req_sta_stats); 221 /* NB: copy out only the statistics */ 222 error = copyout(&ni->ni_stats, (uint8_t *) ireq->i_data + off, 223 ireq->i_len - off); 224 ieee80211_free_node(ni); 225 return error; 226} 227 228struct scanreq { 229 struct ieee80211req_scan_result *sr; 230 size_t space; 231}; 232 233static size_t 234scan_space(const struct ieee80211_scan_entry *se, int *ielen) 235{ 236 size_t len; 237 238 *ielen = se->se_ies.len; 239 /* 240 * NB: ie's can be no more than 255 bytes and the max 802.11 241 * packet is <3Kbytes so we are sure this doesn't overflow 242 * 16-bits; if this is a concern we can drop the ie's. 243 */ 244 len = sizeof(struct ieee80211req_scan_result) + se->se_ssid[1] + *ielen; 245 return roundup(len, sizeof(uint32_t)); 246} 247 248static void 249get_scan_space(void *arg, const struct ieee80211_scan_entry *se) 250{ 251 struct scanreq *req = arg; 252 int ielen; 253 254 req->space += scan_space(se, &ielen); 255} 256 257static __noinline void 258get_scan_result(void *arg, const struct ieee80211_scan_entry *se) 259{ 260 struct scanreq *req = arg; 261 struct ieee80211req_scan_result *sr; 262 int ielen, len, nr, nxr; 263 uint8_t *cp; 264 265 len = scan_space(se, &ielen); 266 if (len > req->space) 267 return; 268 269 sr = req->sr; 270 KASSERT(len <= 65535 && ielen <= 65535, 271 ("len %u ssid %u ie %u", len, se->se_ssid[1], ielen)); 272 sr->isr_len = len; 273 sr->isr_ie_off = sizeof(struct ieee80211req_scan_result); 274 sr->isr_ie_len = ielen; 275 sr->isr_freq = se->se_chan->ic_freq; 276 sr->isr_flags = se->se_chan->ic_flags; 277 sr->isr_rssi = se->se_rssi; 278 sr->isr_noise = se->se_noise; 279 sr->isr_intval = se->se_intval; 280 sr->isr_capinfo = se->se_capinfo; 281 sr->isr_erp = se->se_erp; 282 IEEE80211_ADDR_COPY(sr->isr_bssid, se->se_bssid); 283 nr = min(se->se_rates[1], IEEE80211_RATE_MAXSIZE); 284 memcpy(sr->isr_rates, se->se_rates+2, nr); 285 nxr = min(se->se_xrates[1], IEEE80211_RATE_MAXSIZE - nr); 286 memcpy(sr->isr_rates+nr, se->se_xrates+2, nxr); 287 sr->isr_nrates = nr + nxr; 288 289 sr->isr_ssid_len = se->se_ssid[1]; 290 cp = ((uint8_t *)sr) + sr->isr_ie_off; 291 memcpy(cp, se->se_ssid+2, sr->isr_ssid_len); 292 293 if (ielen) { 294 cp += sr->isr_ssid_len; 295 memcpy(cp, se->se_ies.data, ielen); 296 } 297 298 req->space -= len; 299 req->sr = (struct ieee80211req_scan_result *)(((uint8_t *)sr) + len); 300} 301 302static __noinline int 303ieee80211_ioctl_getscanresults(struct ieee80211vap *vap, 304 struct ieee80211req *ireq) 305{ 306 struct scanreq req; 307 int error; 308 309 if (ireq->i_len < sizeof(struct scanreq)) 310 return EFAULT; 311 312 error = 0; 313 req.space = 0; 314 ieee80211_scan_iterate(vap, get_scan_space, &req); 315 if (req.space > ireq->i_len) 316 req.space = ireq->i_len; 317 if (req.space > 0) { 318 size_t space; 319 void *p; 320 321 space = req.space; 322 /* XXX M_WAITOK after driver lock released */
|
323 p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO);
| 323 MALLOC(p, void *, space, M_TEMP, M_NOWAIT | M_ZERO);
|
324 if (p == NULL) 325 return ENOMEM; 326 req.sr = p; 327 ieee80211_scan_iterate(vap, get_scan_result, &req); 328 ireq->i_len = space - req.space; 329 error = copyout(p, ireq->i_data, ireq->i_len);
| 324 if (p == NULL) 325 return ENOMEM; 326 req.sr = p; 327 ieee80211_scan_iterate(vap, get_scan_result, &req); 328 ireq->i_len = space - req.space; 329 error = copyout(p, ireq->i_data, ireq->i_len);
|
330 free(p, M_TEMP);
| 330 FREE(p, M_TEMP);
|
331 } else 332 ireq->i_len = 0; 333 334 return error; 335} 336 337struct stainforeq { 338 struct ieee80211vap *vap; 339 struct ieee80211req_sta_info *si; 340 size_t space; 341}; 342 343static size_t 344sta_space(const struct ieee80211_node *ni, size_t *ielen) 345{ 346 *ielen = ni->ni_ies.len; 347 return roundup(sizeof(struct ieee80211req_sta_info) + *ielen, 348 sizeof(uint32_t)); 349} 350 351static void 352get_sta_space(void *arg, struct ieee80211_node *ni) 353{ 354 struct stainforeq *req = arg; 355 size_t ielen; 356 357 if (req->vap != ni->ni_vap) 358 return; 359 if (ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP && 360 ni->ni_associd == 0) /* only associated stations */ 361 return; 362 req->space += sta_space(ni, &ielen); 363} 364 365static __noinline void 366get_sta_info(void *arg, struct ieee80211_node *ni) 367{ 368 struct stainforeq *req = arg; 369 struct ieee80211vap *vap = ni->ni_vap; 370 struct ieee80211req_sta_info *si; 371 size_t ielen, len; 372 uint8_t *cp; 373 374 if (req->vap != ni->ni_vap) 375 return; 376 if (vap->iv_opmode == IEEE80211_M_HOSTAP && 377 ni->ni_associd == 0) /* only associated stations */ 378 return; 379 if (ni->ni_chan == IEEE80211_CHAN_ANYC) /* XXX bogus entry */ 380 return; 381 len = sta_space(ni, &ielen); 382 if (len > req->space) 383 return; 384 si = req->si; 385 si->isi_len = len; 386 si->isi_ie_off = sizeof(struct ieee80211req_sta_info); 387 si->isi_ie_len = ielen; 388 si->isi_freq = ni->ni_chan->ic_freq; 389 si->isi_flags = ni->ni_chan->ic_flags; 390 si->isi_state = ni->ni_flags; 391 si->isi_authmode = ni->ni_authmode; 392 vap->iv_ic->ic_node_getsignal(ni, &si->isi_rssi, &si->isi_noise); 393 vap->iv_ic->ic_node_getmimoinfo(ni, &si->isi_mimo); 394 si->isi_capinfo = ni->ni_capinfo; 395 si->isi_erp = ni->ni_erp; 396 IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); 397 si->isi_nrates = ni->ni_rates.rs_nrates; 398 if (si->isi_nrates > 15) 399 si->isi_nrates = 15; 400 memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates); 401 si->isi_txrate = ni->ni_txrate; 402 if (si->isi_txrate & IEEE80211_RATE_MCS) { 403 const struct ieee80211_mcs_rates *mcs = 404 &ieee80211_htrates[ni->ni_txrate &~ IEEE80211_RATE_MCS]; 405 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { 406 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) 407 si->isi_txmbps = mcs->ht40_rate_800ns; 408 else 409 si->isi_txmbps = mcs->ht40_rate_400ns; 410 } else { 411 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) 412 si->isi_txmbps = mcs->ht20_rate_800ns; 413 else 414 si->isi_txmbps = mcs->ht20_rate_400ns; 415 } 416 } else 417 si->isi_txmbps = si->isi_txrate; 418 si->isi_associd = ni->ni_associd; 419 si->isi_txpower = ni->ni_txpower; 420 si->isi_vlan = ni->ni_vlan; 421 if (ni->ni_flags & IEEE80211_NODE_QOS) { 422 memcpy(si->isi_txseqs, ni->ni_txseqs, sizeof(ni->ni_txseqs)); 423 memcpy(si->isi_rxseqs, ni->ni_rxseqs, sizeof(ni->ni_rxseqs)); 424 } else { 425 si->isi_txseqs[0] = ni->ni_txseqs[IEEE80211_NONQOS_TID]; 426 si->isi_rxseqs[0] = ni->ni_rxseqs[IEEE80211_NONQOS_TID]; 427 } 428 /* NB: leave all cases in case we relax ni_associd == 0 check */ 429 if (ieee80211_node_is_authorized(ni)) 430 si->isi_inact = vap->iv_inact_run; 431 else if (ni->ni_associd != 0 || 432 (vap->iv_opmode == IEEE80211_M_WDS && 433 (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY))) 434 si->isi_inact = vap->iv_inact_auth; 435 else 436 si->isi_inact = vap->iv_inact_init; 437 si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT; 438 439 if (ielen) { 440 cp = ((uint8_t *)si) + si->isi_ie_off; 441 memcpy(cp, ni->ni_ies.data, ielen); 442 } 443 444 req->si = (struct ieee80211req_sta_info *)(((uint8_t *)si) + len); 445 req->space -= len; 446} 447 448static __noinline int 449getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq, 450 struct ieee80211_node *ni, int off) 451{ 452 struct ieee80211com *ic = vap->iv_ic; 453 struct stainforeq req; 454 size_t space; 455 void *p; 456 int error; 457 458 error = 0; 459 req.space = 0; 460 req.vap = vap; 461 if (ni == NULL) 462 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); 463 else 464 get_sta_space(&req, ni); 465 if (req.space > ireq->i_len) 466 req.space = ireq->i_len; 467 if (req.space > 0) { 468 space = req.space; 469 /* XXX M_WAITOK after driver lock released */
| 331 } else 332 ireq->i_len = 0; 333 334 return error; 335} 336 337struct stainforeq { 338 struct ieee80211vap *vap; 339 struct ieee80211req_sta_info *si; 340 size_t space; 341}; 342 343static size_t 344sta_space(const struct ieee80211_node *ni, size_t *ielen) 345{ 346 *ielen = ni->ni_ies.len; 347 return roundup(sizeof(struct ieee80211req_sta_info) + *ielen, 348 sizeof(uint32_t)); 349} 350 351static void 352get_sta_space(void *arg, struct ieee80211_node *ni) 353{ 354 struct stainforeq *req = arg; 355 size_t ielen; 356 357 if (req->vap != ni->ni_vap) 358 return; 359 if (ni->ni_vap->iv_opmode == IEEE80211_M_HOSTAP && 360 ni->ni_associd == 0) /* only associated stations */ 361 return; 362 req->space += sta_space(ni, &ielen); 363} 364 365static __noinline void 366get_sta_info(void *arg, struct ieee80211_node *ni) 367{ 368 struct stainforeq *req = arg; 369 struct ieee80211vap *vap = ni->ni_vap; 370 struct ieee80211req_sta_info *si; 371 size_t ielen, len; 372 uint8_t *cp; 373 374 if (req->vap != ni->ni_vap) 375 return; 376 if (vap->iv_opmode == IEEE80211_M_HOSTAP && 377 ni->ni_associd == 0) /* only associated stations */ 378 return; 379 if (ni->ni_chan == IEEE80211_CHAN_ANYC) /* XXX bogus entry */ 380 return; 381 len = sta_space(ni, &ielen); 382 if (len > req->space) 383 return; 384 si = req->si; 385 si->isi_len = len; 386 si->isi_ie_off = sizeof(struct ieee80211req_sta_info); 387 si->isi_ie_len = ielen; 388 si->isi_freq = ni->ni_chan->ic_freq; 389 si->isi_flags = ni->ni_chan->ic_flags; 390 si->isi_state = ni->ni_flags; 391 si->isi_authmode = ni->ni_authmode; 392 vap->iv_ic->ic_node_getsignal(ni, &si->isi_rssi, &si->isi_noise); 393 vap->iv_ic->ic_node_getmimoinfo(ni, &si->isi_mimo); 394 si->isi_capinfo = ni->ni_capinfo; 395 si->isi_erp = ni->ni_erp; 396 IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); 397 si->isi_nrates = ni->ni_rates.rs_nrates; 398 if (si->isi_nrates > 15) 399 si->isi_nrates = 15; 400 memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates); 401 si->isi_txrate = ni->ni_txrate; 402 if (si->isi_txrate & IEEE80211_RATE_MCS) { 403 const struct ieee80211_mcs_rates *mcs = 404 &ieee80211_htrates[ni->ni_txrate &~ IEEE80211_RATE_MCS]; 405 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { 406 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) 407 si->isi_txmbps = mcs->ht40_rate_800ns; 408 else 409 si->isi_txmbps = mcs->ht40_rate_400ns; 410 } else { 411 if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) 412 si->isi_txmbps = mcs->ht20_rate_800ns; 413 else 414 si->isi_txmbps = mcs->ht20_rate_400ns; 415 } 416 } else 417 si->isi_txmbps = si->isi_txrate; 418 si->isi_associd = ni->ni_associd; 419 si->isi_txpower = ni->ni_txpower; 420 si->isi_vlan = ni->ni_vlan; 421 if (ni->ni_flags & IEEE80211_NODE_QOS) { 422 memcpy(si->isi_txseqs, ni->ni_txseqs, sizeof(ni->ni_txseqs)); 423 memcpy(si->isi_rxseqs, ni->ni_rxseqs, sizeof(ni->ni_rxseqs)); 424 } else { 425 si->isi_txseqs[0] = ni->ni_txseqs[IEEE80211_NONQOS_TID]; 426 si->isi_rxseqs[0] = ni->ni_rxseqs[IEEE80211_NONQOS_TID]; 427 } 428 /* NB: leave all cases in case we relax ni_associd == 0 check */ 429 if (ieee80211_node_is_authorized(ni)) 430 si->isi_inact = vap->iv_inact_run; 431 else if (ni->ni_associd != 0 || 432 (vap->iv_opmode == IEEE80211_M_WDS && 433 (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY))) 434 si->isi_inact = vap->iv_inact_auth; 435 else 436 si->isi_inact = vap->iv_inact_init; 437 si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT; 438 439 if (ielen) { 440 cp = ((uint8_t *)si) + si->isi_ie_off; 441 memcpy(cp, ni->ni_ies.data, ielen); 442 } 443 444 req->si = (struct ieee80211req_sta_info *)(((uint8_t *)si) + len); 445 req->space -= len; 446} 447 448static __noinline int 449getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq, 450 struct ieee80211_node *ni, int off) 451{ 452 struct ieee80211com *ic = vap->iv_ic; 453 struct stainforeq req; 454 size_t space; 455 void *p; 456 int error; 457 458 error = 0; 459 req.space = 0; 460 req.vap = vap; 461 if (ni == NULL) 462 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); 463 else 464 get_sta_space(&req, ni); 465 if (req.space > ireq->i_len) 466 req.space = ireq->i_len; 467 if (req.space > 0) { 468 space = req.space; 469 /* XXX M_WAITOK after driver lock released */
|
470 p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO);
| 470 MALLOC(p, void *, space, M_TEMP, M_NOWAIT | M_ZERO);
|
471 if (p == NULL) { 472 error = ENOMEM; 473 goto bad; 474 } 475 req.si = p; 476 if (ni == NULL) 477 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); 478 else 479 get_sta_info(&req, ni); 480 ireq->i_len = space - req.space; 481 error = copyout(p, (uint8_t *) ireq->i_data+off, ireq->i_len);
| 471 if (p == NULL) { 472 error = ENOMEM; 473 goto bad; 474 } 475 req.si = p; 476 if (ni == NULL) 477 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); 478 else 479 get_sta_info(&req, ni); 480 ireq->i_len = space - req.space; 481 error = copyout(p, (uint8_t *) ireq->i_data+off, ireq->i_len);
|
482 free(p, M_TEMP);
| 482 FREE(p, M_TEMP);
|
483 } else 484 ireq->i_len = 0; 485bad: 486 if (ni != NULL) 487 ieee80211_free_node(ni); 488 return error; 489} 490 491static __noinline int 492ieee80211_ioctl_getstainfo(struct ieee80211vap *vap, struct ieee80211req *ireq) 493{ 494 uint8_t macaddr[IEEE80211_ADDR_LEN]; 495 const int off = __offsetof(struct ieee80211req_sta_req, info); 496 struct ieee80211_node *ni; 497 int error; 498 499 if (ireq->i_len < sizeof(struct ieee80211req_sta_req)) 500 return EFAULT; 501 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 502 if (error != 0) 503 return error; 504 if (IEEE80211_ADDR_EQ(macaddr, vap->iv_ifp->if_broadcastaddr)) { 505 ni = NULL; 506 } else { 507 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 508 if (ni == NULL) 509 return ENOENT; 510 } 511 return getstainfo_common(vap, ireq, ni, off); 512} 513 514static __noinline int 515ieee80211_ioctl_getstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) 516{ 517 struct ieee80211_node *ni; 518 struct ieee80211req_sta_txpow txpow; 519 int error; 520 521 if (ireq->i_len != sizeof(txpow)) 522 return EINVAL; 523 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 524 if (error != 0) 525 return error; 526 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); 527 if (ni == NULL) 528 return ENOENT; 529 txpow.it_txpow = ni->ni_txpower; 530 error = copyout(&txpow, ireq->i_data, sizeof(txpow)); 531 ieee80211_free_node(ni); 532 return error; 533} 534 535static __noinline int 536ieee80211_ioctl_getwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) 537{ 538 struct ieee80211com *ic = vap->iv_ic; 539 struct ieee80211_wme_state *wme = &ic->ic_wme; 540 struct wmeParams *wmep; 541 int ac; 542 543 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 544 return EINVAL; 545 546 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 547 if (ac >= WME_NUM_AC) 548 ac = WME_AC_BE; 549 if (ireq->i_len & IEEE80211_WMEPARAM_BSS) 550 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 551 else 552 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 553 switch (ireq->i_type) { 554 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 555 ireq->i_val = wmep->wmep_logcwmin; 556 break; 557 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 558 ireq->i_val = wmep->wmep_logcwmax; 559 break; 560 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 561 ireq->i_val = wmep->wmep_aifsn; 562 break; 563 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 564 ireq->i_val = wmep->wmep_txopLimit; 565 break; 566 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 567 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 568 ireq->i_val = wmep->wmep_acm; 569 break; 570 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 571 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 572 ireq->i_val = !wmep->wmep_noackPolicy; 573 break; 574 } 575 return 0; 576} 577 578static __noinline int 579ieee80211_ioctl_getmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq) 580{ 581 const struct ieee80211_aclator *acl = vap->iv_acl; 582 583 return (acl == NULL ? EINVAL : acl->iac_getioctl(vap, ireq)); 584} 585 586/* 587 * Return the current ``state'' of an Atheros capbility. 588 * If associated in station mode report the negotiated 589 * setting. Otherwise report the current setting. 590 */ 591static int 592getathcap(struct ieee80211vap *vap, int cap) 593{ 594 if (vap->iv_opmode == IEEE80211_M_STA && 595 vap->iv_state == IEEE80211_S_RUN) 596 return IEEE80211_ATH_CAP(vap, vap->iv_bss, cap) != 0; 597 else 598 return (vap->iv_flags & cap) != 0; 599} 600 601static __noinline int 602ieee80211_ioctl_getcurchan(struct ieee80211vap *vap, struct ieee80211req *ireq) 603{ 604 struct ieee80211com *ic = vap->iv_ic; 605 struct ieee80211_channel *c; 606 607 if (ireq->i_len != sizeof(struct ieee80211_channel)) 608 return EINVAL; 609 /* 610 * vap's may have different operating channels when HT is 611 * in use. When in RUN state report the vap-specific channel. 612 * Otherwise return curchan. 613 */ 614 if (vap->iv_state == IEEE80211_S_RUN) 615 c = vap->iv_bss->ni_chan; 616 else 617 c = ic->ic_curchan; 618 return copyout(c, ireq->i_data, sizeof(*c)); 619} 620 621static int 622getappie(const struct ieee80211_appie *aie, struct ieee80211req *ireq) 623{ 624 if (aie == NULL) 625 return EINVAL; 626 /* NB: truncate, caller can check length */ 627 if (ireq->i_len > aie->ie_len) 628 ireq->i_len = aie->ie_len; 629 return copyout(aie->ie_data, ireq->i_data, ireq->i_len); 630} 631 632static int 633ieee80211_ioctl_getappie(struct ieee80211vap *vap, struct ieee80211req *ireq) 634{ 635 uint8_t fc0; 636 637 fc0 = ireq->i_val & 0xff; 638 if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) 639 return EINVAL; 640 /* NB: could check iv_opmode and reject but hardly worth the effort */ 641 switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { 642 case IEEE80211_FC0_SUBTYPE_BEACON: 643 return getappie(vap->iv_appie_beacon, ireq); 644 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 645 return getappie(vap->iv_appie_proberesp, ireq); 646 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 647 return getappie(vap->iv_appie_assocresp, ireq); 648 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 649 return getappie(vap->iv_appie_probereq, ireq); 650 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 651 return getappie(vap->iv_appie_assocreq, ireq); 652 case IEEE80211_FC0_SUBTYPE_BEACON|IEEE80211_FC0_SUBTYPE_PROBE_RESP: 653 return getappie(vap->iv_appie_wpa, ireq); 654 } 655 return EINVAL; 656} 657 658static __noinline int 659ieee80211_ioctl_getregdomain(struct ieee80211vap *vap, 660 const struct ieee80211req *ireq) 661{ 662 struct ieee80211com *ic = vap->iv_ic; 663 664 if (ireq->i_len != sizeof(ic->ic_regdomain)) 665 return EINVAL; 666 return copyout(&ic->ic_regdomain, ireq->i_data, 667 sizeof(ic->ic_regdomain)); 668} 669 670static __noinline int 671ieee80211_ioctl_getroam(struct ieee80211vap *vap, 672 const struct ieee80211req *ireq) 673{ 674 if (ireq->i_len != sizeof(vap->iv_roamparms)) 675 return EINVAL; 676 return copyout(vap->iv_roamparms, ireq->i_data, 677 sizeof(vap->iv_roamparms)); 678} 679 680static __noinline int 681ieee80211_ioctl_gettxparams(struct ieee80211vap *vap, 682 const struct ieee80211req *ireq) 683{ 684 if (ireq->i_len != sizeof(vap->iv_txparms)) 685 return EINVAL; 686 return copyout(vap->iv_txparms, ireq->i_data, sizeof(vap->iv_txparms)); 687} 688 689static __noinline int 690ieee80211_ioctl_getdevcaps(struct ieee80211com *ic, 691 const struct ieee80211req *ireq) 692{ 693 struct ieee80211_devcaps_req *dc; 694 struct ieee80211req_chaninfo *ci; 695 int error; 696 697 if (ireq->i_len != sizeof(struct ieee80211_devcaps_req)) 698 return EINVAL;
| 483 } else 484 ireq->i_len = 0; 485bad: 486 if (ni != NULL) 487 ieee80211_free_node(ni); 488 return error; 489} 490 491static __noinline int 492ieee80211_ioctl_getstainfo(struct ieee80211vap *vap, struct ieee80211req *ireq) 493{ 494 uint8_t macaddr[IEEE80211_ADDR_LEN]; 495 const int off = __offsetof(struct ieee80211req_sta_req, info); 496 struct ieee80211_node *ni; 497 int error; 498 499 if (ireq->i_len < sizeof(struct ieee80211req_sta_req)) 500 return EFAULT; 501 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 502 if (error != 0) 503 return error; 504 if (IEEE80211_ADDR_EQ(macaddr, vap->iv_ifp->if_broadcastaddr)) { 505 ni = NULL; 506 } else { 507 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 508 if (ni == NULL) 509 return ENOENT; 510 } 511 return getstainfo_common(vap, ireq, ni, off); 512} 513 514static __noinline int 515ieee80211_ioctl_getstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) 516{ 517 struct ieee80211_node *ni; 518 struct ieee80211req_sta_txpow txpow; 519 int error; 520 521 if (ireq->i_len != sizeof(txpow)) 522 return EINVAL; 523 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 524 if (error != 0) 525 return error; 526 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); 527 if (ni == NULL) 528 return ENOENT; 529 txpow.it_txpow = ni->ni_txpower; 530 error = copyout(&txpow, ireq->i_data, sizeof(txpow)); 531 ieee80211_free_node(ni); 532 return error; 533} 534 535static __noinline int 536ieee80211_ioctl_getwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) 537{ 538 struct ieee80211com *ic = vap->iv_ic; 539 struct ieee80211_wme_state *wme = &ic->ic_wme; 540 struct wmeParams *wmep; 541 int ac; 542 543 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 544 return EINVAL; 545 546 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 547 if (ac >= WME_NUM_AC) 548 ac = WME_AC_BE; 549 if (ireq->i_len & IEEE80211_WMEPARAM_BSS) 550 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 551 else 552 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 553 switch (ireq->i_type) { 554 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 555 ireq->i_val = wmep->wmep_logcwmin; 556 break; 557 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 558 ireq->i_val = wmep->wmep_logcwmax; 559 break; 560 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 561 ireq->i_val = wmep->wmep_aifsn; 562 break; 563 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 564 ireq->i_val = wmep->wmep_txopLimit; 565 break; 566 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 567 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 568 ireq->i_val = wmep->wmep_acm; 569 break; 570 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 571 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 572 ireq->i_val = !wmep->wmep_noackPolicy; 573 break; 574 } 575 return 0; 576} 577 578static __noinline int 579ieee80211_ioctl_getmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq) 580{ 581 const struct ieee80211_aclator *acl = vap->iv_acl; 582 583 return (acl == NULL ? EINVAL : acl->iac_getioctl(vap, ireq)); 584} 585 586/* 587 * Return the current ``state'' of an Atheros capbility. 588 * If associated in station mode report the negotiated 589 * setting. Otherwise report the current setting. 590 */ 591static int 592getathcap(struct ieee80211vap *vap, int cap) 593{ 594 if (vap->iv_opmode == IEEE80211_M_STA && 595 vap->iv_state == IEEE80211_S_RUN) 596 return IEEE80211_ATH_CAP(vap, vap->iv_bss, cap) != 0; 597 else 598 return (vap->iv_flags & cap) != 0; 599} 600 601static __noinline int 602ieee80211_ioctl_getcurchan(struct ieee80211vap *vap, struct ieee80211req *ireq) 603{ 604 struct ieee80211com *ic = vap->iv_ic; 605 struct ieee80211_channel *c; 606 607 if (ireq->i_len != sizeof(struct ieee80211_channel)) 608 return EINVAL; 609 /* 610 * vap's may have different operating channels when HT is 611 * in use. When in RUN state report the vap-specific channel. 612 * Otherwise return curchan. 613 */ 614 if (vap->iv_state == IEEE80211_S_RUN) 615 c = vap->iv_bss->ni_chan; 616 else 617 c = ic->ic_curchan; 618 return copyout(c, ireq->i_data, sizeof(*c)); 619} 620 621static int 622getappie(const struct ieee80211_appie *aie, struct ieee80211req *ireq) 623{ 624 if (aie == NULL) 625 return EINVAL; 626 /* NB: truncate, caller can check length */ 627 if (ireq->i_len > aie->ie_len) 628 ireq->i_len = aie->ie_len; 629 return copyout(aie->ie_data, ireq->i_data, ireq->i_len); 630} 631 632static int 633ieee80211_ioctl_getappie(struct ieee80211vap *vap, struct ieee80211req *ireq) 634{ 635 uint8_t fc0; 636 637 fc0 = ireq->i_val & 0xff; 638 if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) 639 return EINVAL; 640 /* NB: could check iv_opmode and reject but hardly worth the effort */ 641 switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { 642 case IEEE80211_FC0_SUBTYPE_BEACON: 643 return getappie(vap->iv_appie_beacon, ireq); 644 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 645 return getappie(vap->iv_appie_proberesp, ireq); 646 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 647 return getappie(vap->iv_appie_assocresp, ireq); 648 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 649 return getappie(vap->iv_appie_probereq, ireq); 650 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 651 return getappie(vap->iv_appie_assocreq, ireq); 652 case IEEE80211_FC0_SUBTYPE_BEACON|IEEE80211_FC0_SUBTYPE_PROBE_RESP: 653 return getappie(vap->iv_appie_wpa, ireq); 654 } 655 return EINVAL; 656} 657 658static __noinline int 659ieee80211_ioctl_getregdomain(struct ieee80211vap *vap, 660 const struct ieee80211req *ireq) 661{ 662 struct ieee80211com *ic = vap->iv_ic; 663 664 if (ireq->i_len != sizeof(ic->ic_regdomain)) 665 return EINVAL; 666 return copyout(&ic->ic_regdomain, ireq->i_data, 667 sizeof(ic->ic_regdomain)); 668} 669 670static __noinline int 671ieee80211_ioctl_getroam(struct ieee80211vap *vap, 672 const struct ieee80211req *ireq) 673{ 674 if (ireq->i_len != sizeof(vap->iv_roamparms)) 675 return EINVAL; 676 return copyout(vap->iv_roamparms, ireq->i_data, 677 sizeof(vap->iv_roamparms)); 678} 679 680static __noinline int 681ieee80211_ioctl_gettxparams(struct ieee80211vap *vap, 682 const struct ieee80211req *ireq) 683{ 684 if (ireq->i_len != sizeof(vap->iv_txparms)) 685 return EINVAL; 686 return copyout(vap->iv_txparms, ireq->i_data, sizeof(vap->iv_txparms)); 687} 688 689static __noinline int 690ieee80211_ioctl_getdevcaps(struct ieee80211com *ic, 691 const struct ieee80211req *ireq) 692{ 693 struct ieee80211_devcaps_req *dc; 694 struct ieee80211req_chaninfo *ci; 695 int error; 696 697 if (ireq->i_len != sizeof(struct ieee80211_devcaps_req)) 698 return EINVAL;
|
699 dc = malloc( sizeof(struct ieee80211_devcaps_req), M_TEMP, M_NOWAIT | M_ZERO);
| 699 MALLOC(dc, struct ieee80211_devcaps_req *, 700 sizeof(struct ieee80211_devcaps_req), M_TEMP, M_NOWAIT | M_ZERO);
|
700 if (dc == NULL) 701 return ENOMEM; 702 dc->dc_drivercaps = ic->ic_caps; 703 dc->dc_cryptocaps = ic->ic_cryptocaps; 704 dc->dc_htcaps = ic->ic_htcaps; 705 ci = &dc->dc_chaninfo; 706 ic->ic_getradiocaps(ic, &ci->ic_nchans, ci->ic_chans); 707 ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans); 708 error = copyout(dc, ireq->i_data, sizeof(*dc));
| 701 if (dc == NULL) 702 return ENOMEM; 703 dc->dc_drivercaps = ic->ic_caps; 704 dc->dc_cryptocaps = ic->ic_cryptocaps; 705 dc->dc_htcaps = ic->ic_htcaps; 706 ci = &dc->dc_chaninfo; 707 ic->ic_getradiocaps(ic, &ci->ic_nchans, ci->ic_chans); 708 ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans); 709 error = copyout(dc, ireq->i_data, sizeof(*dc));
|
709 free(dc, M_TEMP);
| 710 FREE(dc, M_TEMP);
|
710 return error; 711} 712 713static __noinline int 714ieee80211_ioctl_getstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) 715{ 716 struct ieee80211_node *ni; 717 struct ieee80211req_sta_vlan vlan; 718 int error; 719 720 if (ireq->i_len != sizeof(vlan)) 721 return EINVAL; 722 error = copyin(ireq->i_data, &vlan, sizeof(vlan)); 723 if (error != 0) 724 return error; 725 if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { 726 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 727 vlan.sv_macaddr); 728 if (ni == NULL) 729 return ENOENT; 730 } else 731 ni = ieee80211_ref_node(vap->iv_bss); 732 vlan.sv_vlan = ni->ni_vlan; 733 error = copyout(&vlan, ireq->i_data, sizeof(vlan)); 734 ieee80211_free_node(ni); 735 return error; 736} 737 738/* 739 * When building the kernel with -O2 on the i386 architecture, gcc 740 * seems to want to inline this function into ieee80211_ioctl() 741 * (which is the only routine that calls it). When this happens, 742 * ieee80211_ioctl() ends up consuming an additional 2K of stack 743 * space. (Exactly why it needs so much is unclear.) The problem 744 * is that it's possible for ieee80211_ioctl() to invoke other 745 * routines (including driver init functions) which could then find 746 * themselves perilously close to exhausting the stack. 747 * 748 * To avoid this, we deliberately prevent gcc from inlining this 749 * routine. Another way to avoid this is to use less agressive 750 * optimization when compiling this file (i.e. -O instead of -O2) 751 * but special-casing the compilation of this one module in the 752 * build system would be awkward. 753 */ 754static __noinline int 755ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, 756 struct ieee80211req *ireq) 757{ 758#define MS(_v, _f) (((_v) & _f) >> _f##_S) 759 struct ieee80211com *ic = vap->iv_ic; 760 u_int kid, len; 761 uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 762 char tmpssid[IEEE80211_NWID_LEN]; 763 int error = 0; 764 765 switch (ireq->i_type) { 766 case IEEE80211_IOC_SSID: 767 switch (vap->iv_state) { 768 case IEEE80211_S_INIT: 769 case IEEE80211_S_SCAN: 770 ireq->i_len = vap->iv_des_ssid[0].len; 771 memcpy(tmpssid, vap->iv_des_ssid[0].ssid, ireq->i_len); 772 break; 773 default: 774 ireq->i_len = vap->iv_bss->ni_esslen; 775 memcpy(tmpssid, vap->iv_bss->ni_essid, ireq->i_len); 776 break; 777 } 778 error = copyout(tmpssid, ireq->i_data, ireq->i_len); 779 break; 780 case IEEE80211_IOC_NUMSSIDS: 781 ireq->i_val = 1; 782 break; 783 case IEEE80211_IOC_WEP: 784 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) 785 ireq->i_val = IEEE80211_WEP_OFF; 786 else if (vap->iv_flags & IEEE80211_F_DROPUNENC) 787 ireq->i_val = IEEE80211_WEP_ON; 788 else 789 ireq->i_val = IEEE80211_WEP_MIXED; 790 break; 791 case IEEE80211_IOC_WEPKEY: 792 kid = (u_int) ireq->i_val; 793 if (kid >= IEEE80211_WEP_NKID) 794 return EINVAL; 795 len = (u_int) vap->iv_nw_keys[kid].wk_keylen; 796 /* NB: only root can read WEP keys */ 797 if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { 798 bcopy(vap->iv_nw_keys[kid].wk_key, tmpkey, len); 799 } else { 800 bzero(tmpkey, len); 801 } 802 ireq->i_len = len; 803 error = copyout(tmpkey, ireq->i_data, len); 804 break; 805 case IEEE80211_IOC_NUMWEPKEYS: 806 ireq->i_val = IEEE80211_WEP_NKID; 807 break; 808 case IEEE80211_IOC_WEPTXKEY: 809 ireq->i_val = vap->iv_def_txkey; 810 break; 811 case IEEE80211_IOC_AUTHMODE: 812 if (vap->iv_flags & IEEE80211_F_WPA) 813 ireq->i_val = IEEE80211_AUTH_WPA; 814 else 815 ireq->i_val = vap->iv_bss->ni_authmode; 816 break; 817 case IEEE80211_IOC_CHANNEL: 818 ireq->i_val = ieee80211_chan2ieee(ic, ic->ic_curchan); 819 break; 820 case IEEE80211_IOC_POWERSAVE: 821 if (vap->iv_flags & IEEE80211_F_PMGTON) 822 ireq->i_val = IEEE80211_POWERSAVE_ON; 823 else 824 ireq->i_val = IEEE80211_POWERSAVE_OFF; 825 break; 826 case IEEE80211_IOC_POWERSAVESLEEP: 827 ireq->i_val = ic->ic_lintval; 828 break; 829 case IEEE80211_IOC_RTSTHRESHOLD: 830 ireq->i_val = vap->iv_rtsthreshold; 831 break; 832 case IEEE80211_IOC_PROTMODE: 833 ireq->i_val = ic->ic_protmode; 834 break; 835 case IEEE80211_IOC_TXPOWER: 836 /* 837 * Tx power limit is the min of max regulatory 838 * power, any user-set limit, and the max the 839 * radio can do. 840 */ 841 ireq->i_val = 2*ic->ic_curchan->ic_maxregpower; 842 if (ireq->i_val > ic->ic_txpowlimit) 843 ireq->i_val = ic->ic_txpowlimit; 844 if (ireq->i_val > ic->ic_curchan->ic_maxpower) 845 ireq->i_val = ic->ic_curchan->ic_maxpower; 846 break; 847 case IEEE80211_IOC_WPA: 848 switch (vap->iv_flags & IEEE80211_F_WPA) { 849 case IEEE80211_F_WPA1: 850 ireq->i_val = 1; 851 break; 852 case IEEE80211_F_WPA2: 853 ireq->i_val = 2; 854 break; 855 case IEEE80211_F_WPA1 | IEEE80211_F_WPA2: 856 ireq->i_val = 3; 857 break; 858 default: 859 ireq->i_val = 0; 860 break; 861 } 862 break; 863 case IEEE80211_IOC_CHANLIST: 864 error = ieee80211_ioctl_getchanlist(vap, ireq); 865 break; 866 case IEEE80211_IOC_ROAMING: 867 ireq->i_val = vap->iv_roaming; 868 break; 869 case IEEE80211_IOC_PRIVACY: 870 ireq->i_val = (vap->iv_flags & IEEE80211_F_PRIVACY) != 0; 871 break; 872 case IEEE80211_IOC_DROPUNENCRYPTED: 873 ireq->i_val = (vap->iv_flags & IEEE80211_F_DROPUNENC) != 0; 874 break; 875 case IEEE80211_IOC_COUNTERMEASURES: 876 ireq->i_val = (vap->iv_flags & IEEE80211_F_COUNTERM) != 0; 877 break; 878 case IEEE80211_IOC_WME: 879 ireq->i_val = (vap->iv_flags & IEEE80211_F_WME) != 0; 880 break; 881 case IEEE80211_IOC_HIDESSID: 882 ireq->i_val = (vap->iv_flags & IEEE80211_F_HIDESSID) != 0; 883 break; 884 case IEEE80211_IOC_APBRIDGE: 885 ireq->i_val = (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0; 886 break; 887 case IEEE80211_IOC_WPAKEY: 888 error = ieee80211_ioctl_getkey(vap, ireq); 889 break; 890 case IEEE80211_IOC_CHANINFO: 891 error = ieee80211_ioctl_getchaninfo(vap, ireq); 892 break; 893 case IEEE80211_IOC_BSSID: 894 if (ireq->i_len != IEEE80211_ADDR_LEN) 895 return EINVAL; 896 error = copyout(vap->iv_state == IEEE80211_S_RUN ? 897 vap->iv_bss->ni_bssid : 898 vap->iv_des_bssid, 899 ireq->i_data, ireq->i_len); 900 break; 901 case IEEE80211_IOC_WPAIE: 902 error = ieee80211_ioctl_getwpaie(vap, ireq, ireq->i_type); 903 break; 904 case IEEE80211_IOC_WPAIE2: 905 error = ieee80211_ioctl_getwpaie(vap, ireq, ireq->i_type); 906 break; 907 case IEEE80211_IOC_SCAN_RESULTS: 908 error = ieee80211_ioctl_getscanresults(vap, ireq); 909 break; 910 case IEEE80211_IOC_STA_STATS: 911 error = ieee80211_ioctl_getstastats(vap, ireq); 912 break; 913 case IEEE80211_IOC_TXPOWMAX: 914 ireq->i_val = vap->iv_bss->ni_txpower; 915 break; 916 case IEEE80211_IOC_STA_TXPOW: 917 error = ieee80211_ioctl_getstatxpow(vap, ireq); 918 break; 919 case IEEE80211_IOC_STA_INFO: 920 error = ieee80211_ioctl_getstainfo(vap, ireq); 921 break; 922 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 923 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 924 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 925 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 926 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 927 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 928 error = ieee80211_ioctl_getwmeparam(vap, ireq); 929 break; 930 case IEEE80211_IOC_DTIM_PERIOD: 931 ireq->i_val = vap->iv_dtim_period; 932 break; 933 case IEEE80211_IOC_BEACON_INTERVAL: 934 /* NB: get from ic_bss for station mode */ 935 ireq->i_val = vap->iv_bss->ni_intval; 936 break; 937 case IEEE80211_IOC_PUREG: 938 ireq->i_val = (vap->iv_flags & IEEE80211_F_PUREG) != 0; 939 break; 940 case IEEE80211_IOC_FF: 941 ireq->i_val = getathcap(vap, IEEE80211_F_FF); 942 break; 943 case IEEE80211_IOC_TURBOP: 944 ireq->i_val = getathcap(vap, IEEE80211_F_TURBOP); 945 break; 946 case IEEE80211_IOC_BGSCAN: 947 ireq->i_val = (vap->iv_flags & IEEE80211_F_BGSCAN) != 0; 948 break; 949 case IEEE80211_IOC_BGSCAN_IDLE: 950 ireq->i_val = vap->iv_bgscanidle*hz/1000; /* ms */ 951 break; 952 case IEEE80211_IOC_BGSCAN_INTERVAL: 953 ireq->i_val = vap->iv_bgscanintvl/hz; /* seconds */ 954 break; 955 case IEEE80211_IOC_SCANVALID: 956 ireq->i_val = vap->iv_scanvalid/hz; /* seconds */ 957 break; 958 case IEEE80211_IOC_FRAGTHRESHOLD: 959 ireq->i_val = vap->iv_fragthreshold; 960 break; 961 case IEEE80211_IOC_MACCMD: 962 error = ieee80211_ioctl_getmaccmd(vap, ireq); 963 break; 964 case IEEE80211_IOC_BURST: 965 ireq->i_val = (vap->iv_flags & IEEE80211_F_BURST) != 0; 966 break; 967 case IEEE80211_IOC_BMISSTHRESHOLD: 968 ireq->i_val = vap->iv_bmissthreshold; 969 break; 970 case IEEE80211_IOC_CURCHAN: 971 error = ieee80211_ioctl_getcurchan(vap, ireq); 972 break; 973 case IEEE80211_IOC_SHORTGI: 974 ireq->i_val = 0; 975 if (vap->iv_flags_ext & IEEE80211_FEXT_SHORTGI20) 976 ireq->i_val |= IEEE80211_HTCAP_SHORTGI20; 977 if (vap->iv_flags_ext & IEEE80211_FEXT_SHORTGI40) 978 ireq->i_val |= IEEE80211_HTCAP_SHORTGI40; 979 break; 980 case IEEE80211_IOC_AMPDU: 981 ireq->i_val = 0; 982 if (vap->iv_flags_ext & IEEE80211_FEXT_AMPDU_TX) 983 ireq->i_val |= 1; 984 if (vap->iv_flags_ext & IEEE80211_FEXT_AMPDU_RX) 985 ireq->i_val |= 2; 986 break; 987 case IEEE80211_IOC_AMPDU_LIMIT: 988 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 989 ireq->i_val = vap->iv_ampdu_rxmax; 990 else if (vap->iv_state == IEEE80211_S_RUN) 991 ireq->i_val = MS(vap->iv_bss->ni_htparam, 992 IEEE80211_HTCAP_MAXRXAMPDU); 993 else 994 ireq->i_val = vap->iv_ampdu_limit; 995 break; 996 case IEEE80211_IOC_AMPDU_DENSITY: 997 if (vap->iv_opmode == IEEE80211_M_STA && 998 vap->iv_state == IEEE80211_S_RUN) 999 ireq->i_val = MS(vap->iv_bss->ni_htparam, 1000 IEEE80211_HTCAP_MPDUDENSITY); 1001 else 1002 ireq->i_val = vap->iv_ampdu_density; 1003 break; 1004 case IEEE80211_IOC_AMSDU: 1005 ireq->i_val = 0; 1006 if (vap->iv_flags_ext & IEEE80211_FEXT_AMSDU_TX) 1007 ireq->i_val |= 1; 1008 if (vap->iv_flags_ext & IEEE80211_FEXT_AMSDU_RX) 1009 ireq->i_val |= 2; 1010 break; 1011 case IEEE80211_IOC_AMSDU_LIMIT: 1012 ireq->i_val = vap->iv_amsdu_limit; /* XXX truncation? */ 1013 break; 1014 case IEEE80211_IOC_PUREN: 1015 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_PUREN) != 0; 1016 break; 1017 case IEEE80211_IOC_DOTH: 1018 ireq->i_val = (vap->iv_flags & IEEE80211_F_DOTH) != 0; 1019 break; 1020 case IEEE80211_IOC_REGDOMAIN: 1021 error = ieee80211_ioctl_getregdomain(vap, ireq); 1022 break; 1023 case IEEE80211_IOC_ROAM: 1024 error = ieee80211_ioctl_getroam(vap, ireq); 1025 break; 1026 case IEEE80211_IOC_TXPARAMS: 1027 error = ieee80211_ioctl_gettxparams(vap, ireq); 1028 break; 1029 case IEEE80211_IOC_HTCOMPAT: 1030 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) != 0; 1031 break; 1032 case IEEE80211_IOC_DWDS: 1033 ireq->i_val = (vap->iv_flags & IEEE80211_F_DWDS) != 0; 1034 break; 1035 case IEEE80211_IOC_INACTIVITY: 1036 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_INACT) != 0; 1037 break; 1038 case IEEE80211_IOC_APPIE: 1039 error = ieee80211_ioctl_getappie(vap, ireq); 1040 break; 1041 case IEEE80211_IOC_WPS: 1042 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_WPS) != 0; 1043 break; 1044 case IEEE80211_IOC_TSN: 1045 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_TSN) != 0; 1046 break; 1047 case IEEE80211_IOC_DFS: 1048 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DFS) != 0; 1049 break; 1050 case IEEE80211_IOC_DOTD: 1051 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DOTD) != 0; 1052 break; 1053 case IEEE80211_IOC_DEVCAPS: 1054 error = ieee80211_ioctl_getdevcaps(ic, ireq); 1055 break; 1056 case IEEE80211_IOC_HTPROTMODE: 1057 ireq->i_val = ic->ic_htprotmode; 1058 break; 1059 case IEEE80211_IOC_HTCONF: 1060 if (vap->iv_flags_ext & IEEE80211_FEXT_HT) { 1061 ireq->i_val = 1; 1062 if (vap->iv_flags_ext & IEEE80211_FEXT_USEHT40) 1063 ireq->i_val |= 2; 1064 } else 1065 ireq->i_val = 0; 1066 break; 1067 case IEEE80211_IOC_STA_VLAN: 1068 error = ieee80211_ioctl_getstavlan(vap, ireq); 1069 break; 1070 case IEEE80211_IOC_SMPS: 1071 if (vap->iv_opmode == IEEE80211_M_STA && 1072 vap->iv_state == IEEE80211_S_RUN) { 1073 if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_RTS) 1074 ireq->i_val = IEEE80211_HTCAP_SMPS_DYNAMIC; 1075 else if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_PS) 1076 ireq->i_val = IEEE80211_HTCAP_SMPS_ENA; 1077 else 1078 ireq->i_val = IEEE80211_HTCAP_SMPS_OFF; 1079 } else 1080 ireq->i_val = vap->iv_htcaps & IEEE80211_HTCAP_SMPS; 1081 break; 1082 case IEEE80211_IOC_RIFS: 1083 if (vap->iv_opmode == IEEE80211_M_STA && 1084 vap->iv_state == IEEE80211_S_RUN) 1085 ireq->i_val = 1086 (vap->iv_bss->ni_flags & IEEE80211_NODE_RIFS) != 0; 1087 else 1088 ireq->i_val = 1089 (vap->iv_flags_ext & IEEE80211_FEXT_RIFS) != 0; 1090 break; 1091 default: 1092 error = EINVAL; 1093 break; 1094 } 1095 return error; 1096#undef MS 1097} 1098 1099static __noinline int 1100ieee80211_ioctl_setkey(struct ieee80211vap *vap, struct ieee80211req *ireq) 1101{ 1102 struct ieee80211req_key ik; 1103 struct ieee80211_node *ni; 1104 struct ieee80211_key *wk; 1105 uint16_t kid; 1106 int error, i; 1107 1108 if (ireq->i_len != sizeof(ik)) 1109 return EINVAL; 1110 error = copyin(ireq->i_data, &ik, sizeof(ik)); 1111 if (error) 1112 return error; 1113 /* NB: cipher support is verified by ieee80211_crypt_newkey */ 1114 /* NB: this also checks ik->ik_keylen > sizeof(wk->wk_key) */ 1115 if (ik.ik_keylen > sizeof(ik.ik_keydata)) 1116 return E2BIG; 1117 kid = ik.ik_keyix; 1118 if (kid == IEEE80211_KEYIX_NONE) { 1119 /* XXX unicast keys currently must be tx/rx */ 1120 if (ik.ik_flags != (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV)) 1121 return EINVAL; 1122 if (vap->iv_opmode == IEEE80211_M_STA) { 1123 ni = ieee80211_ref_node(vap->iv_bss); 1124 if (!IEEE80211_ADDR_EQ(ik.ik_macaddr, ni->ni_bssid)) { 1125 ieee80211_free_node(ni); 1126 return EADDRNOTAVAIL; 1127 } 1128 } else { 1129 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 1130 ik.ik_macaddr); 1131 if (ni == NULL) 1132 return ENOENT; 1133 } 1134 wk = &ni->ni_ucastkey; 1135 } else { 1136 if (kid >= IEEE80211_WEP_NKID) 1137 return EINVAL; 1138 wk = &vap->iv_nw_keys[kid]; 1139 /* 1140 * Global slots start off w/o any assigned key index. 1141 * Force one here for consistency with IEEE80211_IOC_WEPKEY. 1142 */ 1143 if (wk->wk_keyix == IEEE80211_KEYIX_NONE) 1144 wk->wk_keyix = kid; 1145 ni = NULL; 1146 } 1147 error = 0; 1148 ieee80211_key_update_begin(vap); 1149 if (ieee80211_crypto_newkey(vap, ik.ik_type, ik.ik_flags, wk)) { 1150 wk->wk_keylen = ik.ik_keylen; 1151 /* NB: MIC presence is implied by cipher type */ 1152 if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE) 1153 wk->wk_keylen = IEEE80211_KEYBUF_SIZE; 1154 for (i = 0; i < IEEE80211_TID_SIZE; i++) 1155 wk->wk_keyrsc[i] = ik.ik_keyrsc; 1156 wk->wk_keytsc = 0; /* new key, reset */ 1157 memset(wk->wk_key, 0, sizeof(wk->wk_key)); 1158 memcpy(wk->wk_key, ik.ik_keydata, ik.ik_keylen); 1159 IEEE80211_ADDR_COPY(wk->wk_macaddr, 1160 ni != NULL ? ni->ni_macaddr : ik.ik_macaddr); 1161 if (!ieee80211_crypto_setkey(vap, wk)) 1162 error = EIO; 1163 else if ((ik.ik_flags & IEEE80211_KEY_DEFAULT)) 1164 vap->iv_def_txkey = kid; 1165 } else 1166 error = ENXIO; 1167 ieee80211_key_update_end(vap); 1168 if (ni != NULL) 1169 ieee80211_free_node(ni); 1170 return error; 1171} 1172 1173static __noinline int 1174ieee80211_ioctl_delkey(struct ieee80211vap *vap, struct ieee80211req *ireq) 1175{ 1176 struct ieee80211req_del_key dk; 1177 int kid, error; 1178 1179 if (ireq->i_len != sizeof(dk)) 1180 return EINVAL; 1181 error = copyin(ireq->i_data, &dk, sizeof(dk)); 1182 if (error) 1183 return error; 1184 kid = dk.idk_keyix; 1185 /* XXX uint8_t -> uint16_t */ 1186 if (dk.idk_keyix == (uint8_t) IEEE80211_KEYIX_NONE) { 1187 struct ieee80211_node *ni; 1188 1189 if (vap->iv_opmode == IEEE80211_M_STA) { 1190 ni = ieee80211_ref_node(vap->iv_bss); 1191 if (!IEEE80211_ADDR_EQ(dk.idk_macaddr, ni->ni_bssid)) { 1192 ieee80211_free_node(ni); 1193 return EADDRNOTAVAIL; 1194 } 1195 } else { 1196 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 1197 dk.idk_macaddr); 1198 if (ni == NULL) 1199 return ENOENT; 1200 } 1201 /* XXX error return */ 1202 ieee80211_node_delucastkey(ni); 1203 ieee80211_free_node(ni); 1204 } else { 1205 if (kid >= IEEE80211_WEP_NKID) 1206 return EINVAL; 1207 /* XXX error return */ 1208 ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[kid]); 1209 } 1210 return 0; 1211} 1212 1213struct mlmeop { 1214 struct ieee80211vap *vap; 1215 int op; 1216 int reason; 1217}; 1218 1219static void 1220mlmedebug(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], 1221 int op, int reason) 1222{ 1223#ifdef IEEE80211_DEBUG 1224 static const struct { 1225 int mask; 1226 const char *opstr; 1227 } ops[] = { 1228 { 0, "op#0" }, 1229 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1230 IEEE80211_MSG_ASSOC, "assoc" }, 1231 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1232 IEEE80211_MSG_ASSOC, "disassoc" }, 1233 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1234 IEEE80211_MSG_AUTH, "deauth" }, 1235 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1236 IEEE80211_MSG_AUTH, "authorize" }, 1237 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1238 IEEE80211_MSG_AUTH, "unauthorize" }, 1239 }; 1240 1241 if (op == IEEE80211_MLME_AUTH) { 1242 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_IOCTL | 1243 IEEE80211_MSG_STATE | IEEE80211_MSG_AUTH, mac, 1244 "station authenticate %s via MLME (reason %d)", 1245 reason == IEEE80211_STATUS_SUCCESS ? "ACCEPT" : "REJECT", 1246 reason); 1247 } else if (!(IEEE80211_MLME_ASSOC <= op && op <= IEEE80211_MLME_AUTH)) { 1248 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, mac, 1249 "unknown MLME request %d (reason %d)", op, reason); 1250 } else if (reason == IEEE80211_STATUS_SUCCESS) { 1251 IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, 1252 "station %s via MLME", ops[op].opstr); 1253 } else { 1254 IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, 1255 "station %s via MLME (reason %d)", ops[op].opstr, reason); 1256 } 1257#endif /* IEEE80211_DEBUG */ 1258} 1259 1260static void 1261domlme(void *arg, struct ieee80211_node *ni) 1262{ 1263 struct mlmeop *mop = arg; 1264 struct ieee80211vap *vap = ni->ni_vap; 1265 1266 if (vap != mop->vap) 1267 return; 1268 /* 1269 * NB: if ni_associd is zero then the node is already cleaned 1270 * up and we don't need to do this (we're safely holding a 1271 * reference but should otherwise not modify it's state). 1272 */ 1273 if (ni->ni_associd == 0) 1274 return; 1275 mlmedebug(vap, ni->ni_macaddr, mop->op, mop->reason); 1276 if (mop->op == IEEE80211_MLME_DEAUTH) { 1277 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 1278 mop->reason); 1279 } else { 1280 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DISASSOC, 1281 mop->reason); 1282 } 1283 ieee80211_node_leave(ni); 1284} 1285 1286static int 1287setmlme_dropsta(struct ieee80211vap *vap, 1288 const uint8_t mac[IEEE80211_ADDR_LEN], struct mlmeop *mlmeop) 1289{ 1290 struct ieee80211com *ic = vap->iv_ic; 1291 struct ieee80211_node_table *nt = &ic->ic_sta; 1292 struct ieee80211_node *ni; 1293 int error = 0; 1294 1295 /* NB: the broadcast address means do 'em all */ 1296 if (!IEEE80211_ADDR_EQ(mac, ic->ic_ifp->if_broadcastaddr)) { 1297 IEEE80211_NODE_LOCK(nt); 1298 ni = ieee80211_find_node_locked(nt, mac); 1299 if (ni != NULL) { 1300 domlme(mlmeop, ni); 1301 ieee80211_free_node(ni); 1302 } else 1303 error = ENOENT; 1304 IEEE80211_NODE_UNLOCK(nt); 1305 } else { 1306 ieee80211_iterate_nodes(nt, domlme, mlmeop); 1307 } 1308 return error; 1309} 1310 1311static __noinline int 1312setmlme_common(struct ieee80211vap *vap, int op, 1313 const uint8_t mac[IEEE80211_ADDR_LEN], int reason) 1314{ 1315 struct ieee80211com *ic = vap->iv_ic; 1316 struct ieee80211_node_table *nt = &ic->ic_sta; 1317 struct ieee80211_node *ni; 1318 struct mlmeop mlmeop; 1319 int error; 1320 1321 error = 0; 1322 switch (op) { 1323 case IEEE80211_MLME_DISASSOC: 1324 case IEEE80211_MLME_DEAUTH: 1325 switch (vap->iv_opmode) { 1326 case IEEE80211_M_STA: 1327 mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason); 1328 /* XXX not quite right */ 1329 ieee80211_new_state(vap, IEEE80211_S_INIT, reason); 1330 break; 1331 case IEEE80211_M_HOSTAP: 1332 mlmeop.vap = vap; 1333 mlmeop.op = op; 1334 mlmeop.reason = reason; 1335 error = setmlme_dropsta(vap, mac, &mlmeop); 1336 break; 1337 case IEEE80211_M_WDS: 1338 /* XXX user app should send raw frame? */ 1339 if (op != IEEE80211_MLME_DEAUTH) { 1340 error = EINVAL; 1341 break; 1342 } 1343#if 0 1344 /* XXX accept any address, simplifies user code */ 1345 if (!IEEE80211_ADDR_EQ(mac, vap->iv_bss->ni_macaddr)) { 1346 error = EINVAL; 1347 break; 1348 } 1349#endif 1350 mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason); 1351 ni = ieee80211_ref_node(vap->iv_bss); 1352 IEEE80211_SEND_MGMT(ni, 1353 IEEE80211_FC0_SUBTYPE_DEAUTH, reason); 1354 ieee80211_free_node(ni); 1355 break; 1356 default: 1357 error = EINVAL; 1358 break; 1359 } 1360 break; 1361 case IEEE80211_MLME_AUTHORIZE: 1362 case IEEE80211_MLME_UNAUTHORIZE: 1363 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 1364 vap->iv_opmode != IEEE80211_M_WDS) { 1365 error = EINVAL; 1366 break; 1367 } 1368 IEEE80211_NODE_LOCK(nt); 1369 ni = ieee80211_find_vap_node_locked(nt, vap, mac); 1370 if (ni != NULL) { 1371 mlmedebug(vap, mac, op, reason); 1372 if (op == IEEE80211_MLME_AUTHORIZE) 1373 ieee80211_node_authorize(ni); 1374 else 1375 ieee80211_node_unauthorize(ni); 1376 ieee80211_free_node(ni); 1377 } else 1378 error = ENOENT; 1379 IEEE80211_NODE_UNLOCK(nt); 1380 break; 1381 case IEEE80211_MLME_AUTH: 1382 if (vap->iv_opmode != IEEE80211_M_HOSTAP) { 1383 error = EINVAL; 1384 break; 1385 } 1386 IEEE80211_NODE_LOCK(nt); 1387 ni = ieee80211_find_vap_node_locked(nt, vap, mac); 1388 if (ni != NULL) { 1389 mlmedebug(vap, mac, op, reason); 1390 if (reason == IEEE80211_STATUS_SUCCESS) { 1391 IEEE80211_SEND_MGMT(ni, 1392 IEEE80211_FC0_SUBTYPE_AUTH, 2); 1393 /* 1394 * For shared key auth, just continue the 1395 * exchange. Otherwise when 802.1x is not in 1396 * use mark the port authorized at this point 1397 * so traffic can flow. 1398 */ 1399 if (ni->ni_authmode != IEEE80211_AUTH_8021X && 1400 ni->ni_challenge == NULL) 1401 ieee80211_node_authorize(ni); 1402 } else { 1403 vap->iv_stats.is_rx_acl++; 1404 ieee80211_send_error(ni, ni->ni_macaddr, 1405 IEEE80211_FC0_SUBTYPE_AUTH, 2|(reason<<16)); 1406 ieee80211_node_leave(ni); 1407 } 1408 ieee80211_free_node(ni); 1409 } else 1410 error = ENOENT; 1411 IEEE80211_NODE_UNLOCK(nt); 1412 break; 1413 default: 1414 error = EINVAL; 1415 break; 1416 } 1417 return error; 1418} 1419 1420struct scanlookup { 1421 const uint8_t *mac; 1422 int esslen; 1423 const uint8_t *essid; 1424 const struct ieee80211_scan_entry *se; 1425}; 1426 1427/* 1428 * Match mac address and any ssid. 1429 */ 1430static void 1431mlmelookup(void *arg, const struct ieee80211_scan_entry *se) 1432{ 1433 struct scanlookup *look = arg; 1434 1435 if (!IEEE80211_ADDR_EQ(look->mac, se->se_macaddr)) 1436 return; 1437 if (look->esslen != 0) { 1438 if (se->se_ssid[1] != look->esslen) 1439 return; 1440 if (memcmp(look->essid, se->se_ssid+2, look->esslen)) 1441 return; 1442 } 1443 look->se = se; 1444} 1445 1446static __noinline int 1447setmlme_assoc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], 1448 int ssid_len, const uint8_t ssid[IEEE80211_NWID_LEN]) 1449{ 1450 struct scanlookup lookup; 1451 1452 /* XXX ibss/ahdemo */ 1453 if (vap->iv_opmode != IEEE80211_M_STA) 1454 return EINVAL; 1455 1456 /* NB: this is racey if roaming is !manual */ 1457 lookup.se = NULL; 1458 lookup.mac = mac; 1459 lookup.esslen = ssid_len; 1460 lookup.essid = ssid; 1461 ieee80211_scan_iterate(vap, mlmelookup, &lookup); 1462 if (lookup.se == NULL) 1463 return ENOENT; 1464 mlmedebug(vap, mac, IEEE80211_MLME_ASSOC, 0); 1465 if (!ieee80211_sta_join(vap, lookup.se)) 1466 return EIO; /* XXX unique but could be better */ 1467 return 0; 1468} 1469 1470static __noinline int 1471ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct ieee80211req *ireq) 1472{ 1473 struct ieee80211req_mlme mlme; 1474 int error; 1475 1476 if (ireq->i_len != sizeof(mlme)) 1477 return EINVAL; 1478 error = copyin(ireq->i_data, &mlme, sizeof(mlme)); 1479 if (error) 1480 return error; 1481 if (mlme.im_op == IEEE80211_MLME_ASSOC) 1482 return setmlme_assoc(vap, mlme.im_macaddr, 1483 vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid); 1484 else 1485 return setmlme_common(vap, mlme.im_op, 1486 mlme.im_macaddr, mlme.im_reason); 1487} 1488 1489static __noinline int 1490ieee80211_ioctl_macmac(struct ieee80211vap *vap, struct ieee80211req *ireq) 1491{ 1492 uint8_t mac[IEEE80211_ADDR_LEN]; 1493 const struct ieee80211_aclator *acl = vap->iv_acl; 1494 int error; 1495 1496 if (ireq->i_len != sizeof(mac)) 1497 return EINVAL; 1498 error = copyin(ireq->i_data, mac, ireq->i_len); 1499 if (error) 1500 return error; 1501 if (acl == NULL) { 1502 acl = ieee80211_aclator_get("mac"); 1503 if (acl == NULL || !acl->iac_attach(vap)) 1504 return EINVAL; 1505 vap->iv_acl = acl; 1506 } 1507 if (ireq->i_type == IEEE80211_IOC_ADDMAC) 1508 acl->iac_add(vap, mac); 1509 else 1510 acl->iac_remove(vap, mac); 1511 return 0; 1512} 1513 1514static __noinline int 1515ieee80211_ioctl_setmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq) 1516{ 1517 const struct ieee80211_aclator *acl = vap->iv_acl; 1518 1519 switch (ireq->i_val) { 1520 case IEEE80211_MACCMD_POLICY_OPEN: 1521 case IEEE80211_MACCMD_POLICY_ALLOW: 1522 case IEEE80211_MACCMD_POLICY_DENY: 1523 case IEEE80211_MACCMD_POLICY_RADIUS: 1524 if (acl == NULL) { 1525 acl = ieee80211_aclator_get("mac"); 1526 if (acl == NULL || !acl->iac_attach(vap)) 1527 return EINVAL; 1528 vap->iv_acl = acl; 1529 } 1530 acl->iac_setpolicy(vap, ireq->i_val); 1531 break; 1532 case IEEE80211_MACCMD_FLUSH: 1533 if (acl != NULL) 1534 acl->iac_flush(vap); 1535 /* NB: silently ignore when not in use */ 1536 break; 1537 case IEEE80211_MACCMD_DETACH: 1538 if (acl != NULL) { 1539 vap->iv_acl = NULL; 1540 acl->iac_detach(vap); 1541 } 1542 break; 1543 default: 1544 if (acl == NULL) 1545 return EINVAL; 1546 else 1547 return acl->iac_setioctl(vap, ireq); 1548 } 1549 return 0; 1550} 1551 1552static __noinline int 1553ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq) 1554{ 1555 struct ieee80211com *ic = vap->iv_ic; 1556 struct ieee80211req_chanlist list; 1557 u_char chanlist[IEEE80211_CHAN_BYTES]; 1558 int i, j, nchan, error; 1559 1560 if (ireq->i_len != sizeof(list)) 1561 return EINVAL; 1562 error = copyin(ireq->i_data, &list, sizeof(list)); 1563 if (error) 1564 return error; 1565 memset(chanlist, 0, sizeof(chanlist)); 1566 /* 1567 * Since channel 0 is not available for DS, channel 1 1568 * is assigned to LSB on WaveLAN. 1569 */ 1570 if (ic->ic_phytype == IEEE80211_T_DS) 1571 i = 1; 1572 else 1573 i = 0; 1574 nchan = 0; 1575 for (j = 0; i <= IEEE80211_CHAN_MAX; i++, j++) { 1576 /* 1577 * NB: silently discard unavailable channels so users 1578 * can specify 1-255 to get all available channels. 1579 */ 1580 if (isset(list.ic_channels, j) && isset(ic->ic_chan_avail, i)) { 1581 setbit(chanlist, i); 1582 nchan++; 1583 } 1584 } 1585 if (nchan == 0) 1586 return EINVAL; 1587 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */ 1588 isclr(chanlist, ic->ic_bsschan->ic_ieee)) 1589 ic->ic_bsschan = IEEE80211_CHAN_ANYC; 1590 memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); 1591 ieee80211_scan_flush(vap); 1592 return ENETRESET; 1593} 1594 1595static __noinline int 1596ieee80211_ioctl_setstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) 1597{ 1598 struct ieee80211_node *ni; 1599 uint8_t macaddr[IEEE80211_ADDR_LEN]; 1600 int error; 1601 1602 /* 1603 * NB: we could copyin ieee80211req_sta_stats so apps 1604 * could make selective changes but that's overkill; 1605 * just clear all stats for now. 1606 */ 1607 if (ireq->i_len < IEEE80211_ADDR_LEN) 1608 return EINVAL; 1609 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 1610 if (error != 0) 1611 return error; 1612 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 1613 if (ni == NULL) 1614 return ENOENT; 1615 /* XXX require ni_vap == vap? */ 1616 memset(&ni->ni_stats, 0, sizeof(ni->ni_stats)); 1617 ieee80211_free_node(ni); 1618 return 0; 1619} 1620 1621static __noinline int 1622ieee80211_ioctl_setstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) 1623{ 1624 struct ieee80211_node *ni; 1625 struct ieee80211req_sta_txpow txpow; 1626 int error; 1627 1628 if (ireq->i_len != sizeof(txpow)) 1629 return EINVAL; 1630 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 1631 if (error != 0) 1632 return error; 1633 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); 1634 if (ni == NULL) 1635 return ENOENT; 1636 ni->ni_txpower = txpow.it_txpow; 1637 ieee80211_free_node(ni); 1638 return error; 1639} 1640 1641static __noinline int 1642ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) 1643{ 1644 struct ieee80211com *ic = vap->iv_ic; 1645 struct ieee80211_wme_state *wme = &ic->ic_wme; 1646 struct wmeParams *wmep, *chanp; 1647 int isbss, ac; 1648 1649 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 1650 return EOPNOTSUPP; 1651 1652 isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); 1653 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 1654 if (ac >= WME_NUM_AC) 1655 ac = WME_AC_BE; 1656 if (isbss) { 1657 chanp = &wme->wme_bssChanParams.cap_wmeParams[ac]; 1658 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 1659 } else { 1660 chanp = &wme->wme_chanParams.cap_wmeParams[ac]; 1661 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 1662 } 1663 switch (ireq->i_type) { 1664 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1665 if (isbss) { 1666 wmep->wmep_logcwmin = ireq->i_val; 1667 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1668 chanp->wmep_logcwmin = ireq->i_val; 1669 } else { 1670 wmep->wmep_logcwmin = chanp->wmep_logcwmin = 1671 ireq->i_val; 1672 } 1673 break; 1674 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1675 if (isbss) { 1676 wmep->wmep_logcwmax = ireq->i_val; 1677 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1678 chanp->wmep_logcwmax = ireq->i_val; 1679 } else { 1680 wmep->wmep_logcwmax = chanp->wmep_logcwmax = 1681 ireq->i_val; 1682 } 1683 break; 1684 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1685 if (isbss) { 1686 wmep->wmep_aifsn = ireq->i_val; 1687 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1688 chanp->wmep_aifsn = ireq->i_val; 1689 } else { 1690 wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; 1691 } 1692 break; 1693 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1694 if (isbss) { 1695 wmep->wmep_txopLimit = ireq->i_val; 1696 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1697 chanp->wmep_txopLimit = ireq->i_val; 1698 } else { 1699 wmep->wmep_txopLimit = chanp->wmep_txopLimit = 1700 ireq->i_val; 1701 } 1702 break; 1703 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 1704 wmep->wmep_acm = ireq->i_val; 1705 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1706 chanp->wmep_acm = ireq->i_val; 1707 break; 1708 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 1709 wmep->wmep_noackPolicy = chanp->wmep_noackPolicy = 1710 (ireq->i_val) == 0; 1711 break; 1712 } 1713 ieee80211_wme_updateparams(vap); 1714 return 0; 1715} 1716 1717static int 1718find11gchannel(struct ieee80211com *ic, int start, int freq) 1719{ 1720 const struct ieee80211_channel *c; 1721 int i; 1722 1723 for (i = start+1; i < ic->ic_nchans; i++) { 1724 c = &ic->ic_channels[i]; 1725 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1726 return 1; 1727 } 1728 /* NB: should not be needed but in case things are mis-sorted */ 1729 for (i = 0; i < start; i++) { 1730 c = &ic->ic_channels[i]; 1731 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1732 return 1; 1733 } 1734 return 0; 1735} 1736 1737static struct ieee80211_channel * 1738findchannel(struct ieee80211com *ic, int ieee, int mode) 1739{ 1740 static const u_int chanflags[IEEE80211_MODE_MAX] = { 1741 0, /* IEEE80211_MODE_AUTO */ 1742 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ 1743 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ 1744 IEEE80211_CHAN_G, /* IEEE80211_MODE_11G */ 1745 IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ 1746 IEEE80211_CHAN_108A, /* IEEE80211_MODE_TURBO_A */ 1747 IEEE80211_CHAN_108G, /* IEEE80211_MODE_TURBO_G */ 1748 IEEE80211_CHAN_STURBO, /* IEEE80211_MODE_STURBO_A */ 1749 /* NB: handled specially below */ 1750 IEEE80211_CHAN_A, /* IEEE80211_MODE_11NA */ 1751 IEEE80211_CHAN_G, /* IEEE80211_MODE_11NG */ 1752 }; 1753 u_int modeflags; 1754 int i; 1755 1756 modeflags = chanflags[mode]; 1757 for (i = 0; i < ic->ic_nchans; i++) { 1758 struct ieee80211_channel *c = &ic->ic_channels[i]; 1759 1760 if (c->ic_ieee != ieee) 1761 continue; 1762 if (mode == IEEE80211_MODE_AUTO) { 1763 /* ignore turbo channels for autoselect */ 1764 if (IEEE80211_IS_CHAN_TURBO(c)) 1765 continue; 1766 /* 1767 * XXX special-case 11b/g channels so we 1768 * always select the g channel if both 1769 * are present. 1770 * XXX prefer HT to non-HT? 1771 */ 1772 if (!IEEE80211_IS_CHAN_B(c) || 1773 !find11gchannel(ic, i, c->ic_freq)) 1774 return c; 1775 } else { 1776 /* must check HT specially */ 1777 if ((mode == IEEE80211_MODE_11NA || 1778 mode == IEEE80211_MODE_11NG) && 1779 !IEEE80211_IS_CHAN_HT(c)) 1780 continue; 1781 if ((c->ic_flags & modeflags) == modeflags) 1782 return c; 1783 } 1784 } 1785 return NULL; 1786} 1787 1788/* 1789 * Check the specified against any desired mode (aka netband). 1790 * This is only used (presently) when operating in hostap mode 1791 * to enforce consistency. 1792 */ 1793static int 1794check_mode_consistency(const struct ieee80211_channel *c, int mode) 1795{ 1796 KASSERT(c != IEEE80211_CHAN_ANYC, ("oops, no channel")); 1797 1798 switch (mode) { 1799 case IEEE80211_MODE_11B: 1800 return (IEEE80211_IS_CHAN_B(c)); 1801 case IEEE80211_MODE_11G: 1802 return (IEEE80211_IS_CHAN_ANYG(c) && !IEEE80211_IS_CHAN_HT(c)); 1803 case IEEE80211_MODE_11A: 1804 return (IEEE80211_IS_CHAN_A(c) && !IEEE80211_IS_CHAN_HT(c)); 1805 case IEEE80211_MODE_STURBO_A: 1806 return (IEEE80211_IS_CHAN_STURBO(c)); 1807 case IEEE80211_MODE_11NA: 1808 return (IEEE80211_IS_CHAN_HTA(c)); 1809 case IEEE80211_MODE_11NG: 1810 return (IEEE80211_IS_CHAN_HTG(c)); 1811 } 1812 return 1; 1813 1814} 1815 1816/* 1817 * Common code to set the current channel. If the device 1818 * is up and running this may result in an immediate channel 1819 * change or a kick of the state machine. 1820 */ 1821static int 1822setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c) 1823{ 1824 struct ieee80211com *ic = vap->iv_ic; 1825 int error; 1826 1827 if (c != IEEE80211_CHAN_ANYC) { 1828 if (IEEE80211_IS_CHAN_RADAR(c)) 1829 return EBUSY; /* XXX better code? */ 1830 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 1831 if (IEEE80211_IS_CHAN_NOHOSTAP(c)) 1832 return EINVAL; 1833 if (!check_mode_consistency(c, vap->iv_des_mode)) 1834 return EINVAL; 1835 } else if (vap->iv_opmode == IEEE80211_M_IBSS) { 1836 if (IEEE80211_IS_CHAN_NOADHOC(c)) 1837 return EINVAL; 1838 } 1839 if (vap->iv_state == IEEE80211_S_RUN && 1840 vap->iv_bss->ni_chan == c) 1841 return 0; /* NB: nothing to do */ 1842 } 1843 vap->iv_des_chan = c; 1844 1845 error = 0; 1846 if (vap->iv_opmode == IEEE80211_M_MONITOR && 1847 vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1848 /* 1849 * Monitor mode can switch directly. 1850 */ 1851 if (IFNET_IS_UP_RUNNING(vap->iv_ifp)) { 1852 /* XXX need state machine for other vap's to follow */ 1853 ieee80211_setcurchan(ic, vap->iv_des_chan); 1854 vap->iv_bss->ni_chan = ic->ic_curchan; 1855 } else 1856 ic->ic_curchan = vap->iv_des_chan; 1857 } else { 1858 /* 1859 * Need to go through the state machine in case we 1860 * need to reassociate or the like. The state machine 1861 * will pickup the desired channel and avoid scanning. 1862 */ 1863 if (IS_UP_AUTO(vap)) 1864 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 1865 else if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1866 /* 1867 * When not up+running and a real channel has 1868 * been specified fix the current channel so 1869 * there is immediate feedback; e.g. via ifconfig. 1870 */ 1871 ic->ic_curchan = vap->iv_des_chan; 1872 } 1873 } 1874 return error; 1875} 1876 1877/* 1878 * Old api for setting the current channel; this is 1879 * deprecated because channel numbers are ambiguous. 1880 */ 1881static __noinline int 1882ieee80211_ioctl_setchannel(struct ieee80211vap *vap, 1883 const struct ieee80211req *ireq) 1884{ 1885 struct ieee80211com *ic = vap->iv_ic; 1886 struct ieee80211_channel *c; 1887 1888 /* XXX 0xffff overflows 16-bit signed */ 1889 if (ireq->i_val == 0 || 1890 ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) { 1891 c = IEEE80211_CHAN_ANYC; 1892 } else if ((u_int) ireq->i_val > IEEE80211_CHAN_MAX) { 1893 return EINVAL; 1894 } else { 1895 struct ieee80211_channel *c2; 1896 1897 c = findchannel(ic, ireq->i_val, vap->iv_des_mode); 1898 if (c == NULL) { 1899 c = findchannel(ic, ireq->i_val, 1900 IEEE80211_MODE_AUTO); 1901 if (c == NULL) 1902 return EINVAL; 1903 } 1904 /* 1905 * Fine tune channel selection based on desired mode: 1906 * if 11b is requested, find the 11b version of any 1907 * 11g channel returned, 1908 * if static turbo, find the turbo version of any 1909 * 11a channel return, 1910 * if 11na is requested, find the ht version of any 1911 * 11a channel returned, 1912 * if 11ng is requested, find the ht version of any 1913 * 11g channel returned, 1914 * otherwise we should be ok with what we've got. 1915 */ 1916 switch (vap->iv_des_mode) { 1917 case IEEE80211_MODE_11B: 1918 if (IEEE80211_IS_CHAN_ANYG(c)) { 1919 c2 = findchannel(ic, ireq->i_val, 1920 IEEE80211_MODE_11B); 1921 /* NB: should not happen, =>'s 11g w/o 11b */ 1922 if (c2 != NULL) 1923 c = c2; 1924 } 1925 break; 1926 case IEEE80211_MODE_TURBO_A: 1927 if (IEEE80211_IS_CHAN_A(c)) { 1928 c2 = findchannel(ic, ireq->i_val, 1929 IEEE80211_MODE_TURBO_A); 1930 if (c2 != NULL) 1931 c = c2; 1932 } 1933 break; 1934 case IEEE80211_MODE_11NA: 1935 if (IEEE80211_IS_CHAN_A(c)) { 1936 c2 = findchannel(ic, ireq->i_val, 1937 IEEE80211_MODE_11NA); 1938 if (c2 != NULL) 1939 c = c2; 1940 } 1941 break; 1942 case IEEE80211_MODE_11NG: 1943 if (IEEE80211_IS_CHAN_ANYG(c)) { 1944 c2 = findchannel(ic, ireq->i_val, 1945 IEEE80211_MODE_11NG); 1946 if (c2 != NULL) 1947 c = c2; 1948 } 1949 break; 1950 default: /* NB: no static turboG */ 1951 break; 1952 } 1953 } 1954 return setcurchan(vap, c); 1955} 1956 1957/* 1958 * New/current api for setting the current channel; a complete 1959 * channel description is provide so there is no ambiguity in 1960 * identifying the channel. 1961 */ 1962static __noinline int 1963ieee80211_ioctl_setcurchan(struct ieee80211vap *vap, 1964 const struct ieee80211req *ireq) 1965{ 1966 struct ieee80211com *ic = vap->iv_ic; 1967 struct ieee80211_channel chan, *c; 1968 int error; 1969 1970 if (ireq->i_len != sizeof(chan)) 1971 return EINVAL; 1972 error = copyin(ireq->i_data, &chan, sizeof(chan)); 1973 if (error != 0) 1974 return error; 1975 /* XXX 0xffff overflows 16-bit signed */ 1976 if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) { 1977 c = IEEE80211_CHAN_ANYC; 1978 } else { 1979 c = ieee80211_find_channel(ic, chan.ic_freq, chan.ic_flags); 1980 if (c == NULL) 1981 return EINVAL; 1982 } 1983 return setcurchan(vap, c); 1984} 1985 1986static __noinline int 1987ieee80211_ioctl_setregdomain(struct ieee80211vap *vap, 1988 const struct ieee80211req *ireq) 1989{ 1990 struct ieee80211_regdomain_req *reg; 1991 int error; 1992 1993 if (ireq->i_len != sizeof(struct ieee80211_regdomain_req)) 1994 return EINVAL;
| 711 return error; 712} 713 714static __noinline int 715ieee80211_ioctl_getstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) 716{ 717 struct ieee80211_node *ni; 718 struct ieee80211req_sta_vlan vlan; 719 int error; 720 721 if (ireq->i_len != sizeof(vlan)) 722 return EINVAL; 723 error = copyin(ireq->i_data, &vlan, sizeof(vlan)); 724 if (error != 0) 725 return error; 726 if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { 727 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 728 vlan.sv_macaddr); 729 if (ni == NULL) 730 return ENOENT; 731 } else 732 ni = ieee80211_ref_node(vap->iv_bss); 733 vlan.sv_vlan = ni->ni_vlan; 734 error = copyout(&vlan, ireq->i_data, sizeof(vlan)); 735 ieee80211_free_node(ni); 736 return error; 737} 738 739/* 740 * When building the kernel with -O2 on the i386 architecture, gcc 741 * seems to want to inline this function into ieee80211_ioctl() 742 * (which is the only routine that calls it). When this happens, 743 * ieee80211_ioctl() ends up consuming an additional 2K of stack 744 * space. (Exactly why it needs so much is unclear.) The problem 745 * is that it's possible for ieee80211_ioctl() to invoke other 746 * routines (including driver init functions) which could then find 747 * themselves perilously close to exhausting the stack. 748 * 749 * To avoid this, we deliberately prevent gcc from inlining this 750 * routine. Another way to avoid this is to use less agressive 751 * optimization when compiling this file (i.e. -O instead of -O2) 752 * but special-casing the compilation of this one module in the 753 * build system would be awkward. 754 */ 755static __noinline int 756ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, 757 struct ieee80211req *ireq) 758{ 759#define MS(_v, _f) (((_v) & _f) >> _f##_S) 760 struct ieee80211com *ic = vap->iv_ic; 761 u_int kid, len; 762 uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 763 char tmpssid[IEEE80211_NWID_LEN]; 764 int error = 0; 765 766 switch (ireq->i_type) { 767 case IEEE80211_IOC_SSID: 768 switch (vap->iv_state) { 769 case IEEE80211_S_INIT: 770 case IEEE80211_S_SCAN: 771 ireq->i_len = vap->iv_des_ssid[0].len; 772 memcpy(tmpssid, vap->iv_des_ssid[0].ssid, ireq->i_len); 773 break; 774 default: 775 ireq->i_len = vap->iv_bss->ni_esslen; 776 memcpy(tmpssid, vap->iv_bss->ni_essid, ireq->i_len); 777 break; 778 } 779 error = copyout(tmpssid, ireq->i_data, ireq->i_len); 780 break; 781 case IEEE80211_IOC_NUMSSIDS: 782 ireq->i_val = 1; 783 break; 784 case IEEE80211_IOC_WEP: 785 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) 786 ireq->i_val = IEEE80211_WEP_OFF; 787 else if (vap->iv_flags & IEEE80211_F_DROPUNENC) 788 ireq->i_val = IEEE80211_WEP_ON; 789 else 790 ireq->i_val = IEEE80211_WEP_MIXED; 791 break; 792 case IEEE80211_IOC_WEPKEY: 793 kid = (u_int) ireq->i_val; 794 if (kid >= IEEE80211_WEP_NKID) 795 return EINVAL; 796 len = (u_int) vap->iv_nw_keys[kid].wk_keylen; 797 /* NB: only root can read WEP keys */ 798 if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { 799 bcopy(vap->iv_nw_keys[kid].wk_key, tmpkey, len); 800 } else { 801 bzero(tmpkey, len); 802 } 803 ireq->i_len = len; 804 error = copyout(tmpkey, ireq->i_data, len); 805 break; 806 case IEEE80211_IOC_NUMWEPKEYS: 807 ireq->i_val = IEEE80211_WEP_NKID; 808 break; 809 case IEEE80211_IOC_WEPTXKEY: 810 ireq->i_val = vap->iv_def_txkey; 811 break; 812 case IEEE80211_IOC_AUTHMODE: 813 if (vap->iv_flags & IEEE80211_F_WPA) 814 ireq->i_val = IEEE80211_AUTH_WPA; 815 else 816 ireq->i_val = vap->iv_bss->ni_authmode; 817 break; 818 case IEEE80211_IOC_CHANNEL: 819 ireq->i_val = ieee80211_chan2ieee(ic, ic->ic_curchan); 820 break; 821 case IEEE80211_IOC_POWERSAVE: 822 if (vap->iv_flags & IEEE80211_F_PMGTON) 823 ireq->i_val = IEEE80211_POWERSAVE_ON; 824 else 825 ireq->i_val = IEEE80211_POWERSAVE_OFF; 826 break; 827 case IEEE80211_IOC_POWERSAVESLEEP: 828 ireq->i_val = ic->ic_lintval; 829 break; 830 case IEEE80211_IOC_RTSTHRESHOLD: 831 ireq->i_val = vap->iv_rtsthreshold; 832 break; 833 case IEEE80211_IOC_PROTMODE: 834 ireq->i_val = ic->ic_protmode; 835 break; 836 case IEEE80211_IOC_TXPOWER: 837 /* 838 * Tx power limit is the min of max regulatory 839 * power, any user-set limit, and the max the 840 * radio can do. 841 */ 842 ireq->i_val = 2*ic->ic_curchan->ic_maxregpower; 843 if (ireq->i_val > ic->ic_txpowlimit) 844 ireq->i_val = ic->ic_txpowlimit; 845 if (ireq->i_val > ic->ic_curchan->ic_maxpower) 846 ireq->i_val = ic->ic_curchan->ic_maxpower; 847 break; 848 case IEEE80211_IOC_WPA: 849 switch (vap->iv_flags & IEEE80211_F_WPA) { 850 case IEEE80211_F_WPA1: 851 ireq->i_val = 1; 852 break; 853 case IEEE80211_F_WPA2: 854 ireq->i_val = 2; 855 break; 856 case IEEE80211_F_WPA1 | IEEE80211_F_WPA2: 857 ireq->i_val = 3; 858 break; 859 default: 860 ireq->i_val = 0; 861 break; 862 } 863 break; 864 case IEEE80211_IOC_CHANLIST: 865 error = ieee80211_ioctl_getchanlist(vap, ireq); 866 break; 867 case IEEE80211_IOC_ROAMING: 868 ireq->i_val = vap->iv_roaming; 869 break; 870 case IEEE80211_IOC_PRIVACY: 871 ireq->i_val = (vap->iv_flags & IEEE80211_F_PRIVACY) != 0; 872 break; 873 case IEEE80211_IOC_DROPUNENCRYPTED: 874 ireq->i_val = (vap->iv_flags & IEEE80211_F_DROPUNENC) != 0; 875 break; 876 case IEEE80211_IOC_COUNTERMEASURES: 877 ireq->i_val = (vap->iv_flags & IEEE80211_F_COUNTERM) != 0; 878 break; 879 case IEEE80211_IOC_WME: 880 ireq->i_val = (vap->iv_flags & IEEE80211_F_WME) != 0; 881 break; 882 case IEEE80211_IOC_HIDESSID: 883 ireq->i_val = (vap->iv_flags & IEEE80211_F_HIDESSID) != 0; 884 break; 885 case IEEE80211_IOC_APBRIDGE: 886 ireq->i_val = (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0; 887 break; 888 case IEEE80211_IOC_WPAKEY: 889 error = ieee80211_ioctl_getkey(vap, ireq); 890 break; 891 case IEEE80211_IOC_CHANINFO: 892 error = ieee80211_ioctl_getchaninfo(vap, ireq); 893 break; 894 case IEEE80211_IOC_BSSID: 895 if (ireq->i_len != IEEE80211_ADDR_LEN) 896 return EINVAL; 897 error = copyout(vap->iv_state == IEEE80211_S_RUN ? 898 vap->iv_bss->ni_bssid : 899 vap->iv_des_bssid, 900 ireq->i_data, ireq->i_len); 901 break; 902 case IEEE80211_IOC_WPAIE: 903 error = ieee80211_ioctl_getwpaie(vap, ireq, ireq->i_type); 904 break; 905 case IEEE80211_IOC_WPAIE2: 906 error = ieee80211_ioctl_getwpaie(vap, ireq, ireq->i_type); 907 break; 908 case IEEE80211_IOC_SCAN_RESULTS: 909 error = ieee80211_ioctl_getscanresults(vap, ireq); 910 break; 911 case IEEE80211_IOC_STA_STATS: 912 error = ieee80211_ioctl_getstastats(vap, ireq); 913 break; 914 case IEEE80211_IOC_TXPOWMAX: 915 ireq->i_val = vap->iv_bss->ni_txpower; 916 break; 917 case IEEE80211_IOC_STA_TXPOW: 918 error = ieee80211_ioctl_getstatxpow(vap, ireq); 919 break; 920 case IEEE80211_IOC_STA_INFO: 921 error = ieee80211_ioctl_getstainfo(vap, ireq); 922 break; 923 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 924 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 925 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 926 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 927 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 928 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 929 error = ieee80211_ioctl_getwmeparam(vap, ireq); 930 break; 931 case IEEE80211_IOC_DTIM_PERIOD: 932 ireq->i_val = vap->iv_dtim_period; 933 break; 934 case IEEE80211_IOC_BEACON_INTERVAL: 935 /* NB: get from ic_bss for station mode */ 936 ireq->i_val = vap->iv_bss->ni_intval; 937 break; 938 case IEEE80211_IOC_PUREG: 939 ireq->i_val = (vap->iv_flags & IEEE80211_F_PUREG) != 0; 940 break; 941 case IEEE80211_IOC_FF: 942 ireq->i_val = getathcap(vap, IEEE80211_F_FF); 943 break; 944 case IEEE80211_IOC_TURBOP: 945 ireq->i_val = getathcap(vap, IEEE80211_F_TURBOP); 946 break; 947 case IEEE80211_IOC_BGSCAN: 948 ireq->i_val = (vap->iv_flags & IEEE80211_F_BGSCAN) != 0; 949 break; 950 case IEEE80211_IOC_BGSCAN_IDLE: 951 ireq->i_val = vap->iv_bgscanidle*hz/1000; /* ms */ 952 break; 953 case IEEE80211_IOC_BGSCAN_INTERVAL: 954 ireq->i_val = vap->iv_bgscanintvl/hz; /* seconds */ 955 break; 956 case IEEE80211_IOC_SCANVALID: 957 ireq->i_val = vap->iv_scanvalid/hz; /* seconds */ 958 break; 959 case IEEE80211_IOC_FRAGTHRESHOLD: 960 ireq->i_val = vap->iv_fragthreshold; 961 break; 962 case IEEE80211_IOC_MACCMD: 963 error = ieee80211_ioctl_getmaccmd(vap, ireq); 964 break; 965 case IEEE80211_IOC_BURST: 966 ireq->i_val = (vap->iv_flags & IEEE80211_F_BURST) != 0; 967 break; 968 case IEEE80211_IOC_BMISSTHRESHOLD: 969 ireq->i_val = vap->iv_bmissthreshold; 970 break; 971 case IEEE80211_IOC_CURCHAN: 972 error = ieee80211_ioctl_getcurchan(vap, ireq); 973 break; 974 case IEEE80211_IOC_SHORTGI: 975 ireq->i_val = 0; 976 if (vap->iv_flags_ext & IEEE80211_FEXT_SHORTGI20) 977 ireq->i_val |= IEEE80211_HTCAP_SHORTGI20; 978 if (vap->iv_flags_ext & IEEE80211_FEXT_SHORTGI40) 979 ireq->i_val |= IEEE80211_HTCAP_SHORTGI40; 980 break; 981 case IEEE80211_IOC_AMPDU: 982 ireq->i_val = 0; 983 if (vap->iv_flags_ext & IEEE80211_FEXT_AMPDU_TX) 984 ireq->i_val |= 1; 985 if (vap->iv_flags_ext & IEEE80211_FEXT_AMPDU_RX) 986 ireq->i_val |= 2; 987 break; 988 case IEEE80211_IOC_AMPDU_LIMIT: 989 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 990 ireq->i_val = vap->iv_ampdu_rxmax; 991 else if (vap->iv_state == IEEE80211_S_RUN) 992 ireq->i_val = MS(vap->iv_bss->ni_htparam, 993 IEEE80211_HTCAP_MAXRXAMPDU); 994 else 995 ireq->i_val = vap->iv_ampdu_limit; 996 break; 997 case IEEE80211_IOC_AMPDU_DENSITY: 998 if (vap->iv_opmode == IEEE80211_M_STA && 999 vap->iv_state == IEEE80211_S_RUN) 1000 ireq->i_val = MS(vap->iv_bss->ni_htparam, 1001 IEEE80211_HTCAP_MPDUDENSITY); 1002 else 1003 ireq->i_val = vap->iv_ampdu_density; 1004 break; 1005 case IEEE80211_IOC_AMSDU: 1006 ireq->i_val = 0; 1007 if (vap->iv_flags_ext & IEEE80211_FEXT_AMSDU_TX) 1008 ireq->i_val |= 1; 1009 if (vap->iv_flags_ext & IEEE80211_FEXT_AMSDU_RX) 1010 ireq->i_val |= 2; 1011 break; 1012 case IEEE80211_IOC_AMSDU_LIMIT: 1013 ireq->i_val = vap->iv_amsdu_limit; /* XXX truncation? */ 1014 break; 1015 case IEEE80211_IOC_PUREN: 1016 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_PUREN) != 0; 1017 break; 1018 case IEEE80211_IOC_DOTH: 1019 ireq->i_val = (vap->iv_flags & IEEE80211_F_DOTH) != 0; 1020 break; 1021 case IEEE80211_IOC_REGDOMAIN: 1022 error = ieee80211_ioctl_getregdomain(vap, ireq); 1023 break; 1024 case IEEE80211_IOC_ROAM: 1025 error = ieee80211_ioctl_getroam(vap, ireq); 1026 break; 1027 case IEEE80211_IOC_TXPARAMS: 1028 error = ieee80211_ioctl_gettxparams(vap, ireq); 1029 break; 1030 case IEEE80211_IOC_HTCOMPAT: 1031 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) != 0; 1032 break; 1033 case IEEE80211_IOC_DWDS: 1034 ireq->i_val = (vap->iv_flags & IEEE80211_F_DWDS) != 0; 1035 break; 1036 case IEEE80211_IOC_INACTIVITY: 1037 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_INACT) != 0; 1038 break; 1039 case IEEE80211_IOC_APPIE: 1040 error = ieee80211_ioctl_getappie(vap, ireq); 1041 break; 1042 case IEEE80211_IOC_WPS: 1043 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_WPS) != 0; 1044 break; 1045 case IEEE80211_IOC_TSN: 1046 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_TSN) != 0; 1047 break; 1048 case IEEE80211_IOC_DFS: 1049 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DFS) != 0; 1050 break; 1051 case IEEE80211_IOC_DOTD: 1052 ireq->i_val = (vap->iv_flags_ext & IEEE80211_FEXT_DOTD) != 0; 1053 break; 1054 case IEEE80211_IOC_DEVCAPS: 1055 error = ieee80211_ioctl_getdevcaps(ic, ireq); 1056 break; 1057 case IEEE80211_IOC_HTPROTMODE: 1058 ireq->i_val = ic->ic_htprotmode; 1059 break; 1060 case IEEE80211_IOC_HTCONF: 1061 if (vap->iv_flags_ext & IEEE80211_FEXT_HT) { 1062 ireq->i_val = 1; 1063 if (vap->iv_flags_ext & IEEE80211_FEXT_USEHT40) 1064 ireq->i_val |= 2; 1065 } else 1066 ireq->i_val = 0; 1067 break; 1068 case IEEE80211_IOC_STA_VLAN: 1069 error = ieee80211_ioctl_getstavlan(vap, ireq); 1070 break; 1071 case IEEE80211_IOC_SMPS: 1072 if (vap->iv_opmode == IEEE80211_M_STA && 1073 vap->iv_state == IEEE80211_S_RUN) { 1074 if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_RTS) 1075 ireq->i_val = IEEE80211_HTCAP_SMPS_DYNAMIC; 1076 else if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_PS) 1077 ireq->i_val = IEEE80211_HTCAP_SMPS_ENA; 1078 else 1079 ireq->i_val = IEEE80211_HTCAP_SMPS_OFF; 1080 } else 1081 ireq->i_val = vap->iv_htcaps & IEEE80211_HTCAP_SMPS; 1082 break; 1083 case IEEE80211_IOC_RIFS: 1084 if (vap->iv_opmode == IEEE80211_M_STA && 1085 vap->iv_state == IEEE80211_S_RUN) 1086 ireq->i_val = 1087 (vap->iv_bss->ni_flags & IEEE80211_NODE_RIFS) != 0; 1088 else 1089 ireq->i_val = 1090 (vap->iv_flags_ext & IEEE80211_FEXT_RIFS) != 0; 1091 break; 1092 default: 1093 error = EINVAL; 1094 break; 1095 } 1096 return error; 1097#undef MS 1098} 1099 1100static __noinline int 1101ieee80211_ioctl_setkey(struct ieee80211vap *vap, struct ieee80211req *ireq) 1102{ 1103 struct ieee80211req_key ik; 1104 struct ieee80211_node *ni; 1105 struct ieee80211_key *wk; 1106 uint16_t kid; 1107 int error, i; 1108 1109 if (ireq->i_len != sizeof(ik)) 1110 return EINVAL; 1111 error = copyin(ireq->i_data, &ik, sizeof(ik)); 1112 if (error) 1113 return error; 1114 /* NB: cipher support is verified by ieee80211_crypt_newkey */ 1115 /* NB: this also checks ik->ik_keylen > sizeof(wk->wk_key) */ 1116 if (ik.ik_keylen > sizeof(ik.ik_keydata)) 1117 return E2BIG; 1118 kid = ik.ik_keyix; 1119 if (kid == IEEE80211_KEYIX_NONE) { 1120 /* XXX unicast keys currently must be tx/rx */ 1121 if (ik.ik_flags != (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV)) 1122 return EINVAL; 1123 if (vap->iv_opmode == IEEE80211_M_STA) { 1124 ni = ieee80211_ref_node(vap->iv_bss); 1125 if (!IEEE80211_ADDR_EQ(ik.ik_macaddr, ni->ni_bssid)) { 1126 ieee80211_free_node(ni); 1127 return EADDRNOTAVAIL; 1128 } 1129 } else { 1130 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 1131 ik.ik_macaddr); 1132 if (ni == NULL) 1133 return ENOENT; 1134 } 1135 wk = &ni->ni_ucastkey; 1136 } else { 1137 if (kid >= IEEE80211_WEP_NKID) 1138 return EINVAL; 1139 wk = &vap->iv_nw_keys[kid]; 1140 /* 1141 * Global slots start off w/o any assigned key index. 1142 * Force one here for consistency with IEEE80211_IOC_WEPKEY. 1143 */ 1144 if (wk->wk_keyix == IEEE80211_KEYIX_NONE) 1145 wk->wk_keyix = kid; 1146 ni = NULL; 1147 } 1148 error = 0; 1149 ieee80211_key_update_begin(vap); 1150 if (ieee80211_crypto_newkey(vap, ik.ik_type, ik.ik_flags, wk)) { 1151 wk->wk_keylen = ik.ik_keylen; 1152 /* NB: MIC presence is implied by cipher type */ 1153 if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE) 1154 wk->wk_keylen = IEEE80211_KEYBUF_SIZE; 1155 for (i = 0; i < IEEE80211_TID_SIZE; i++) 1156 wk->wk_keyrsc[i] = ik.ik_keyrsc; 1157 wk->wk_keytsc = 0; /* new key, reset */ 1158 memset(wk->wk_key, 0, sizeof(wk->wk_key)); 1159 memcpy(wk->wk_key, ik.ik_keydata, ik.ik_keylen); 1160 IEEE80211_ADDR_COPY(wk->wk_macaddr, 1161 ni != NULL ? ni->ni_macaddr : ik.ik_macaddr); 1162 if (!ieee80211_crypto_setkey(vap, wk)) 1163 error = EIO; 1164 else if ((ik.ik_flags & IEEE80211_KEY_DEFAULT)) 1165 vap->iv_def_txkey = kid; 1166 } else 1167 error = ENXIO; 1168 ieee80211_key_update_end(vap); 1169 if (ni != NULL) 1170 ieee80211_free_node(ni); 1171 return error; 1172} 1173 1174static __noinline int 1175ieee80211_ioctl_delkey(struct ieee80211vap *vap, struct ieee80211req *ireq) 1176{ 1177 struct ieee80211req_del_key dk; 1178 int kid, error; 1179 1180 if (ireq->i_len != sizeof(dk)) 1181 return EINVAL; 1182 error = copyin(ireq->i_data, &dk, sizeof(dk)); 1183 if (error) 1184 return error; 1185 kid = dk.idk_keyix; 1186 /* XXX uint8_t -> uint16_t */ 1187 if (dk.idk_keyix == (uint8_t) IEEE80211_KEYIX_NONE) { 1188 struct ieee80211_node *ni; 1189 1190 if (vap->iv_opmode == IEEE80211_M_STA) { 1191 ni = ieee80211_ref_node(vap->iv_bss); 1192 if (!IEEE80211_ADDR_EQ(dk.idk_macaddr, ni->ni_bssid)) { 1193 ieee80211_free_node(ni); 1194 return EADDRNOTAVAIL; 1195 } 1196 } else { 1197 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 1198 dk.idk_macaddr); 1199 if (ni == NULL) 1200 return ENOENT; 1201 } 1202 /* XXX error return */ 1203 ieee80211_node_delucastkey(ni); 1204 ieee80211_free_node(ni); 1205 } else { 1206 if (kid >= IEEE80211_WEP_NKID) 1207 return EINVAL; 1208 /* XXX error return */ 1209 ieee80211_crypto_delkey(vap, &vap->iv_nw_keys[kid]); 1210 } 1211 return 0; 1212} 1213 1214struct mlmeop { 1215 struct ieee80211vap *vap; 1216 int op; 1217 int reason; 1218}; 1219 1220static void 1221mlmedebug(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], 1222 int op, int reason) 1223{ 1224#ifdef IEEE80211_DEBUG 1225 static const struct { 1226 int mask; 1227 const char *opstr; 1228 } ops[] = { 1229 { 0, "op#0" }, 1230 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1231 IEEE80211_MSG_ASSOC, "assoc" }, 1232 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1233 IEEE80211_MSG_ASSOC, "disassoc" }, 1234 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1235 IEEE80211_MSG_AUTH, "deauth" }, 1236 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1237 IEEE80211_MSG_AUTH, "authorize" }, 1238 { IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | 1239 IEEE80211_MSG_AUTH, "unauthorize" }, 1240 }; 1241 1242 if (op == IEEE80211_MLME_AUTH) { 1243 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_IOCTL | 1244 IEEE80211_MSG_STATE | IEEE80211_MSG_AUTH, mac, 1245 "station authenticate %s via MLME (reason %d)", 1246 reason == IEEE80211_STATUS_SUCCESS ? "ACCEPT" : "REJECT", 1247 reason); 1248 } else if (!(IEEE80211_MLME_ASSOC <= op && op <= IEEE80211_MLME_AUTH)) { 1249 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, mac, 1250 "unknown MLME request %d (reason %d)", op, reason); 1251 } else if (reason == IEEE80211_STATUS_SUCCESS) { 1252 IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, 1253 "station %s via MLME", ops[op].opstr); 1254 } else { 1255 IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, 1256 "station %s via MLME (reason %d)", ops[op].opstr, reason); 1257 } 1258#endif /* IEEE80211_DEBUG */ 1259} 1260 1261static void 1262domlme(void *arg, struct ieee80211_node *ni) 1263{ 1264 struct mlmeop *mop = arg; 1265 struct ieee80211vap *vap = ni->ni_vap; 1266 1267 if (vap != mop->vap) 1268 return; 1269 /* 1270 * NB: if ni_associd is zero then the node is already cleaned 1271 * up and we don't need to do this (we're safely holding a 1272 * reference but should otherwise not modify it's state). 1273 */ 1274 if (ni->ni_associd == 0) 1275 return; 1276 mlmedebug(vap, ni->ni_macaddr, mop->op, mop->reason); 1277 if (mop->op == IEEE80211_MLME_DEAUTH) { 1278 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 1279 mop->reason); 1280 } else { 1281 IEEE80211_SEND_MGMT(ni, IEEE80211_FC0_SUBTYPE_DISASSOC, 1282 mop->reason); 1283 } 1284 ieee80211_node_leave(ni); 1285} 1286 1287static int 1288setmlme_dropsta(struct ieee80211vap *vap, 1289 const uint8_t mac[IEEE80211_ADDR_LEN], struct mlmeop *mlmeop) 1290{ 1291 struct ieee80211com *ic = vap->iv_ic; 1292 struct ieee80211_node_table *nt = &ic->ic_sta; 1293 struct ieee80211_node *ni; 1294 int error = 0; 1295 1296 /* NB: the broadcast address means do 'em all */ 1297 if (!IEEE80211_ADDR_EQ(mac, ic->ic_ifp->if_broadcastaddr)) { 1298 IEEE80211_NODE_LOCK(nt); 1299 ni = ieee80211_find_node_locked(nt, mac); 1300 if (ni != NULL) { 1301 domlme(mlmeop, ni); 1302 ieee80211_free_node(ni); 1303 } else 1304 error = ENOENT; 1305 IEEE80211_NODE_UNLOCK(nt); 1306 } else { 1307 ieee80211_iterate_nodes(nt, domlme, mlmeop); 1308 } 1309 return error; 1310} 1311 1312static __noinline int 1313setmlme_common(struct ieee80211vap *vap, int op, 1314 const uint8_t mac[IEEE80211_ADDR_LEN], int reason) 1315{ 1316 struct ieee80211com *ic = vap->iv_ic; 1317 struct ieee80211_node_table *nt = &ic->ic_sta; 1318 struct ieee80211_node *ni; 1319 struct mlmeop mlmeop; 1320 int error; 1321 1322 error = 0; 1323 switch (op) { 1324 case IEEE80211_MLME_DISASSOC: 1325 case IEEE80211_MLME_DEAUTH: 1326 switch (vap->iv_opmode) { 1327 case IEEE80211_M_STA: 1328 mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason); 1329 /* XXX not quite right */ 1330 ieee80211_new_state(vap, IEEE80211_S_INIT, reason); 1331 break; 1332 case IEEE80211_M_HOSTAP: 1333 mlmeop.vap = vap; 1334 mlmeop.op = op; 1335 mlmeop.reason = reason; 1336 error = setmlme_dropsta(vap, mac, &mlmeop); 1337 break; 1338 case IEEE80211_M_WDS: 1339 /* XXX user app should send raw frame? */ 1340 if (op != IEEE80211_MLME_DEAUTH) { 1341 error = EINVAL; 1342 break; 1343 } 1344#if 0 1345 /* XXX accept any address, simplifies user code */ 1346 if (!IEEE80211_ADDR_EQ(mac, vap->iv_bss->ni_macaddr)) { 1347 error = EINVAL; 1348 break; 1349 } 1350#endif 1351 mlmedebug(vap, vap->iv_bss->ni_macaddr, op, reason); 1352 ni = ieee80211_ref_node(vap->iv_bss); 1353 IEEE80211_SEND_MGMT(ni, 1354 IEEE80211_FC0_SUBTYPE_DEAUTH, reason); 1355 ieee80211_free_node(ni); 1356 break; 1357 default: 1358 error = EINVAL; 1359 break; 1360 } 1361 break; 1362 case IEEE80211_MLME_AUTHORIZE: 1363 case IEEE80211_MLME_UNAUTHORIZE: 1364 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 1365 vap->iv_opmode != IEEE80211_M_WDS) { 1366 error = EINVAL; 1367 break; 1368 } 1369 IEEE80211_NODE_LOCK(nt); 1370 ni = ieee80211_find_vap_node_locked(nt, vap, mac); 1371 if (ni != NULL) { 1372 mlmedebug(vap, mac, op, reason); 1373 if (op == IEEE80211_MLME_AUTHORIZE) 1374 ieee80211_node_authorize(ni); 1375 else 1376 ieee80211_node_unauthorize(ni); 1377 ieee80211_free_node(ni); 1378 } else 1379 error = ENOENT; 1380 IEEE80211_NODE_UNLOCK(nt); 1381 break; 1382 case IEEE80211_MLME_AUTH: 1383 if (vap->iv_opmode != IEEE80211_M_HOSTAP) { 1384 error = EINVAL; 1385 break; 1386 } 1387 IEEE80211_NODE_LOCK(nt); 1388 ni = ieee80211_find_vap_node_locked(nt, vap, mac); 1389 if (ni != NULL) { 1390 mlmedebug(vap, mac, op, reason); 1391 if (reason == IEEE80211_STATUS_SUCCESS) { 1392 IEEE80211_SEND_MGMT(ni, 1393 IEEE80211_FC0_SUBTYPE_AUTH, 2); 1394 /* 1395 * For shared key auth, just continue the 1396 * exchange. Otherwise when 802.1x is not in 1397 * use mark the port authorized at this point 1398 * so traffic can flow. 1399 */ 1400 if (ni->ni_authmode != IEEE80211_AUTH_8021X && 1401 ni->ni_challenge == NULL) 1402 ieee80211_node_authorize(ni); 1403 } else { 1404 vap->iv_stats.is_rx_acl++; 1405 ieee80211_send_error(ni, ni->ni_macaddr, 1406 IEEE80211_FC0_SUBTYPE_AUTH, 2|(reason<<16)); 1407 ieee80211_node_leave(ni); 1408 } 1409 ieee80211_free_node(ni); 1410 } else 1411 error = ENOENT; 1412 IEEE80211_NODE_UNLOCK(nt); 1413 break; 1414 default: 1415 error = EINVAL; 1416 break; 1417 } 1418 return error; 1419} 1420 1421struct scanlookup { 1422 const uint8_t *mac; 1423 int esslen; 1424 const uint8_t *essid; 1425 const struct ieee80211_scan_entry *se; 1426}; 1427 1428/* 1429 * Match mac address and any ssid. 1430 */ 1431static void 1432mlmelookup(void *arg, const struct ieee80211_scan_entry *se) 1433{ 1434 struct scanlookup *look = arg; 1435 1436 if (!IEEE80211_ADDR_EQ(look->mac, se->se_macaddr)) 1437 return; 1438 if (look->esslen != 0) { 1439 if (se->se_ssid[1] != look->esslen) 1440 return; 1441 if (memcmp(look->essid, se->se_ssid+2, look->esslen)) 1442 return; 1443 } 1444 look->se = se; 1445} 1446 1447static __noinline int 1448setmlme_assoc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], 1449 int ssid_len, const uint8_t ssid[IEEE80211_NWID_LEN]) 1450{ 1451 struct scanlookup lookup; 1452 1453 /* XXX ibss/ahdemo */ 1454 if (vap->iv_opmode != IEEE80211_M_STA) 1455 return EINVAL; 1456 1457 /* NB: this is racey if roaming is !manual */ 1458 lookup.se = NULL; 1459 lookup.mac = mac; 1460 lookup.esslen = ssid_len; 1461 lookup.essid = ssid; 1462 ieee80211_scan_iterate(vap, mlmelookup, &lookup); 1463 if (lookup.se == NULL) 1464 return ENOENT; 1465 mlmedebug(vap, mac, IEEE80211_MLME_ASSOC, 0); 1466 if (!ieee80211_sta_join(vap, lookup.se)) 1467 return EIO; /* XXX unique but could be better */ 1468 return 0; 1469} 1470 1471static __noinline int 1472ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct ieee80211req *ireq) 1473{ 1474 struct ieee80211req_mlme mlme; 1475 int error; 1476 1477 if (ireq->i_len != sizeof(mlme)) 1478 return EINVAL; 1479 error = copyin(ireq->i_data, &mlme, sizeof(mlme)); 1480 if (error) 1481 return error; 1482 if (mlme.im_op == IEEE80211_MLME_ASSOC) 1483 return setmlme_assoc(vap, mlme.im_macaddr, 1484 vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid); 1485 else 1486 return setmlme_common(vap, mlme.im_op, 1487 mlme.im_macaddr, mlme.im_reason); 1488} 1489 1490static __noinline int 1491ieee80211_ioctl_macmac(struct ieee80211vap *vap, struct ieee80211req *ireq) 1492{ 1493 uint8_t mac[IEEE80211_ADDR_LEN]; 1494 const struct ieee80211_aclator *acl = vap->iv_acl; 1495 int error; 1496 1497 if (ireq->i_len != sizeof(mac)) 1498 return EINVAL; 1499 error = copyin(ireq->i_data, mac, ireq->i_len); 1500 if (error) 1501 return error; 1502 if (acl == NULL) { 1503 acl = ieee80211_aclator_get("mac"); 1504 if (acl == NULL || !acl->iac_attach(vap)) 1505 return EINVAL; 1506 vap->iv_acl = acl; 1507 } 1508 if (ireq->i_type == IEEE80211_IOC_ADDMAC) 1509 acl->iac_add(vap, mac); 1510 else 1511 acl->iac_remove(vap, mac); 1512 return 0; 1513} 1514 1515static __noinline int 1516ieee80211_ioctl_setmaccmd(struct ieee80211vap *vap, struct ieee80211req *ireq) 1517{ 1518 const struct ieee80211_aclator *acl = vap->iv_acl; 1519 1520 switch (ireq->i_val) { 1521 case IEEE80211_MACCMD_POLICY_OPEN: 1522 case IEEE80211_MACCMD_POLICY_ALLOW: 1523 case IEEE80211_MACCMD_POLICY_DENY: 1524 case IEEE80211_MACCMD_POLICY_RADIUS: 1525 if (acl == NULL) { 1526 acl = ieee80211_aclator_get("mac"); 1527 if (acl == NULL || !acl->iac_attach(vap)) 1528 return EINVAL; 1529 vap->iv_acl = acl; 1530 } 1531 acl->iac_setpolicy(vap, ireq->i_val); 1532 break; 1533 case IEEE80211_MACCMD_FLUSH: 1534 if (acl != NULL) 1535 acl->iac_flush(vap); 1536 /* NB: silently ignore when not in use */ 1537 break; 1538 case IEEE80211_MACCMD_DETACH: 1539 if (acl != NULL) { 1540 vap->iv_acl = NULL; 1541 acl->iac_detach(vap); 1542 } 1543 break; 1544 default: 1545 if (acl == NULL) 1546 return EINVAL; 1547 else 1548 return acl->iac_setioctl(vap, ireq); 1549 } 1550 return 0; 1551} 1552 1553static __noinline int 1554ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq) 1555{ 1556 struct ieee80211com *ic = vap->iv_ic; 1557 struct ieee80211req_chanlist list; 1558 u_char chanlist[IEEE80211_CHAN_BYTES]; 1559 int i, j, nchan, error; 1560 1561 if (ireq->i_len != sizeof(list)) 1562 return EINVAL; 1563 error = copyin(ireq->i_data, &list, sizeof(list)); 1564 if (error) 1565 return error; 1566 memset(chanlist, 0, sizeof(chanlist)); 1567 /* 1568 * Since channel 0 is not available for DS, channel 1 1569 * is assigned to LSB on WaveLAN. 1570 */ 1571 if (ic->ic_phytype == IEEE80211_T_DS) 1572 i = 1; 1573 else 1574 i = 0; 1575 nchan = 0; 1576 for (j = 0; i <= IEEE80211_CHAN_MAX; i++, j++) { 1577 /* 1578 * NB: silently discard unavailable channels so users 1579 * can specify 1-255 to get all available channels. 1580 */ 1581 if (isset(list.ic_channels, j) && isset(ic->ic_chan_avail, i)) { 1582 setbit(chanlist, i); 1583 nchan++; 1584 } 1585 } 1586 if (nchan == 0) 1587 return EINVAL; 1588 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */ 1589 isclr(chanlist, ic->ic_bsschan->ic_ieee)) 1590 ic->ic_bsschan = IEEE80211_CHAN_ANYC; 1591 memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); 1592 ieee80211_scan_flush(vap); 1593 return ENETRESET; 1594} 1595 1596static __noinline int 1597ieee80211_ioctl_setstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) 1598{ 1599 struct ieee80211_node *ni; 1600 uint8_t macaddr[IEEE80211_ADDR_LEN]; 1601 int error; 1602 1603 /* 1604 * NB: we could copyin ieee80211req_sta_stats so apps 1605 * could make selective changes but that's overkill; 1606 * just clear all stats for now. 1607 */ 1608 if (ireq->i_len < IEEE80211_ADDR_LEN) 1609 return EINVAL; 1610 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 1611 if (error != 0) 1612 return error; 1613 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 1614 if (ni == NULL) 1615 return ENOENT; 1616 /* XXX require ni_vap == vap? */ 1617 memset(&ni->ni_stats, 0, sizeof(ni->ni_stats)); 1618 ieee80211_free_node(ni); 1619 return 0; 1620} 1621 1622static __noinline int 1623ieee80211_ioctl_setstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) 1624{ 1625 struct ieee80211_node *ni; 1626 struct ieee80211req_sta_txpow txpow; 1627 int error; 1628 1629 if (ireq->i_len != sizeof(txpow)) 1630 return EINVAL; 1631 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 1632 if (error != 0) 1633 return error; 1634 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); 1635 if (ni == NULL) 1636 return ENOENT; 1637 ni->ni_txpower = txpow.it_txpow; 1638 ieee80211_free_node(ni); 1639 return error; 1640} 1641 1642static __noinline int 1643ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) 1644{ 1645 struct ieee80211com *ic = vap->iv_ic; 1646 struct ieee80211_wme_state *wme = &ic->ic_wme; 1647 struct wmeParams *wmep, *chanp; 1648 int isbss, ac; 1649 1650 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 1651 return EOPNOTSUPP; 1652 1653 isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); 1654 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 1655 if (ac >= WME_NUM_AC) 1656 ac = WME_AC_BE; 1657 if (isbss) { 1658 chanp = &wme->wme_bssChanParams.cap_wmeParams[ac]; 1659 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 1660 } else { 1661 chanp = &wme->wme_chanParams.cap_wmeParams[ac]; 1662 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 1663 } 1664 switch (ireq->i_type) { 1665 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1666 if (isbss) { 1667 wmep->wmep_logcwmin = ireq->i_val; 1668 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1669 chanp->wmep_logcwmin = ireq->i_val; 1670 } else { 1671 wmep->wmep_logcwmin = chanp->wmep_logcwmin = 1672 ireq->i_val; 1673 } 1674 break; 1675 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1676 if (isbss) { 1677 wmep->wmep_logcwmax = ireq->i_val; 1678 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1679 chanp->wmep_logcwmax = ireq->i_val; 1680 } else { 1681 wmep->wmep_logcwmax = chanp->wmep_logcwmax = 1682 ireq->i_val; 1683 } 1684 break; 1685 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1686 if (isbss) { 1687 wmep->wmep_aifsn = ireq->i_val; 1688 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1689 chanp->wmep_aifsn = ireq->i_val; 1690 } else { 1691 wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; 1692 } 1693 break; 1694 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1695 if (isbss) { 1696 wmep->wmep_txopLimit = ireq->i_val; 1697 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1698 chanp->wmep_txopLimit = ireq->i_val; 1699 } else { 1700 wmep->wmep_txopLimit = chanp->wmep_txopLimit = 1701 ireq->i_val; 1702 } 1703 break; 1704 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 1705 wmep->wmep_acm = ireq->i_val; 1706 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1707 chanp->wmep_acm = ireq->i_val; 1708 break; 1709 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 1710 wmep->wmep_noackPolicy = chanp->wmep_noackPolicy = 1711 (ireq->i_val) == 0; 1712 break; 1713 } 1714 ieee80211_wme_updateparams(vap); 1715 return 0; 1716} 1717 1718static int 1719find11gchannel(struct ieee80211com *ic, int start, int freq) 1720{ 1721 const struct ieee80211_channel *c; 1722 int i; 1723 1724 for (i = start+1; i < ic->ic_nchans; i++) { 1725 c = &ic->ic_channels[i]; 1726 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1727 return 1; 1728 } 1729 /* NB: should not be needed but in case things are mis-sorted */ 1730 for (i = 0; i < start; i++) { 1731 c = &ic->ic_channels[i]; 1732 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1733 return 1; 1734 } 1735 return 0; 1736} 1737 1738static struct ieee80211_channel * 1739findchannel(struct ieee80211com *ic, int ieee, int mode) 1740{ 1741 static const u_int chanflags[IEEE80211_MODE_MAX] = { 1742 0, /* IEEE80211_MODE_AUTO */ 1743 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ 1744 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ 1745 IEEE80211_CHAN_G, /* IEEE80211_MODE_11G */ 1746 IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ 1747 IEEE80211_CHAN_108A, /* IEEE80211_MODE_TURBO_A */ 1748 IEEE80211_CHAN_108G, /* IEEE80211_MODE_TURBO_G */ 1749 IEEE80211_CHAN_STURBO, /* IEEE80211_MODE_STURBO_A */ 1750 /* NB: handled specially below */ 1751 IEEE80211_CHAN_A, /* IEEE80211_MODE_11NA */ 1752 IEEE80211_CHAN_G, /* IEEE80211_MODE_11NG */ 1753 }; 1754 u_int modeflags; 1755 int i; 1756 1757 modeflags = chanflags[mode]; 1758 for (i = 0; i < ic->ic_nchans; i++) { 1759 struct ieee80211_channel *c = &ic->ic_channels[i]; 1760 1761 if (c->ic_ieee != ieee) 1762 continue; 1763 if (mode == IEEE80211_MODE_AUTO) { 1764 /* ignore turbo channels for autoselect */ 1765 if (IEEE80211_IS_CHAN_TURBO(c)) 1766 continue; 1767 /* 1768 * XXX special-case 11b/g channels so we 1769 * always select the g channel if both 1770 * are present. 1771 * XXX prefer HT to non-HT? 1772 */ 1773 if (!IEEE80211_IS_CHAN_B(c) || 1774 !find11gchannel(ic, i, c->ic_freq)) 1775 return c; 1776 } else { 1777 /* must check HT specially */ 1778 if ((mode == IEEE80211_MODE_11NA || 1779 mode == IEEE80211_MODE_11NG) && 1780 !IEEE80211_IS_CHAN_HT(c)) 1781 continue; 1782 if ((c->ic_flags & modeflags) == modeflags) 1783 return c; 1784 } 1785 } 1786 return NULL; 1787} 1788 1789/* 1790 * Check the specified against any desired mode (aka netband). 1791 * This is only used (presently) when operating in hostap mode 1792 * to enforce consistency. 1793 */ 1794static int 1795check_mode_consistency(const struct ieee80211_channel *c, int mode) 1796{ 1797 KASSERT(c != IEEE80211_CHAN_ANYC, ("oops, no channel")); 1798 1799 switch (mode) { 1800 case IEEE80211_MODE_11B: 1801 return (IEEE80211_IS_CHAN_B(c)); 1802 case IEEE80211_MODE_11G: 1803 return (IEEE80211_IS_CHAN_ANYG(c) && !IEEE80211_IS_CHAN_HT(c)); 1804 case IEEE80211_MODE_11A: 1805 return (IEEE80211_IS_CHAN_A(c) && !IEEE80211_IS_CHAN_HT(c)); 1806 case IEEE80211_MODE_STURBO_A: 1807 return (IEEE80211_IS_CHAN_STURBO(c)); 1808 case IEEE80211_MODE_11NA: 1809 return (IEEE80211_IS_CHAN_HTA(c)); 1810 case IEEE80211_MODE_11NG: 1811 return (IEEE80211_IS_CHAN_HTG(c)); 1812 } 1813 return 1; 1814 1815} 1816 1817/* 1818 * Common code to set the current channel. If the device 1819 * is up and running this may result in an immediate channel 1820 * change or a kick of the state machine. 1821 */ 1822static int 1823setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c) 1824{ 1825 struct ieee80211com *ic = vap->iv_ic; 1826 int error; 1827 1828 if (c != IEEE80211_CHAN_ANYC) { 1829 if (IEEE80211_IS_CHAN_RADAR(c)) 1830 return EBUSY; /* XXX better code? */ 1831 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 1832 if (IEEE80211_IS_CHAN_NOHOSTAP(c)) 1833 return EINVAL; 1834 if (!check_mode_consistency(c, vap->iv_des_mode)) 1835 return EINVAL; 1836 } else if (vap->iv_opmode == IEEE80211_M_IBSS) { 1837 if (IEEE80211_IS_CHAN_NOADHOC(c)) 1838 return EINVAL; 1839 } 1840 if (vap->iv_state == IEEE80211_S_RUN && 1841 vap->iv_bss->ni_chan == c) 1842 return 0; /* NB: nothing to do */ 1843 } 1844 vap->iv_des_chan = c; 1845 1846 error = 0; 1847 if (vap->iv_opmode == IEEE80211_M_MONITOR && 1848 vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1849 /* 1850 * Monitor mode can switch directly. 1851 */ 1852 if (IFNET_IS_UP_RUNNING(vap->iv_ifp)) { 1853 /* XXX need state machine for other vap's to follow */ 1854 ieee80211_setcurchan(ic, vap->iv_des_chan); 1855 vap->iv_bss->ni_chan = ic->ic_curchan; 1856 } else 1857 ic->ic_curchan = vap->iv_des_chan; 1858 } else { 1859 /* 1860 * Need to go through the state machine in case we 1861 * need to reassociate or the like. The state machine 1862 * will pickup the desired channel and avoid scanning. 1863 */ 1864 if (IS_UP_AUTO(vap)) 1865 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 1866 else if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1867 /* 1868 * When not up+running and a real channel has 1869 * been specified fix the current channel so 1870 * there is immediate feedback; e.g. via ifconfig. 1871 */ 1872 ic->ic_curchan = vap->iv_des_chan; 1873 } 1874 } 1875 return error; 1876} 1877 1878/* 1879 * Old api for setting the current channel; this is 1880 * deprecated because channel numbers are ambiguous. 1881 */ 1882static __noinline int 1883ieee80211_ioctl_setchannel(struct ieee80211vap *vap, 1884 const struct ieee80211req *ireq) 1885{ 1886 struct ieee80211com *ic = vap->iv_ic; 1887 struct ieee80211_channel *c; 1888 1889 /* XXX 0xffff overflows 16-bit signed */ 1890 if (ireq->i_val == 0 || 1891 ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) { 1892 c = IEEE80211_CHAN_ANYC; 1893 } else if ((u_int) ireq->i_val > IEEE80211_CHAN_MAX) { 1894 return EINVAL; 1895 } else { 1896 struct ieee80211_channel *c2; 1897 1898 c = findchannel(ic, ireq->i_val, vap->iv_des_mode); 1899 if (c == NULL) { 1900 c = findchannel(ic, ireq->i_val, 1901 IEEE80211_MODE_AUTO); 1902 if (c == NULL) 1903 return EINVAL; 1904 } 1905 /* 1906 * Fine tune channel selection based on desired mode: 1907 * if 11b is requested, find the 11b version of any 1908 * 11g channel returned, 1909 * if static turbo, find the turbo version of any 1910 * 11a channel return, 1911 * if 11na is requested, find the ht version of any 1912 * 11a channel returned, 1913 * if 11ng is requested, find the ht version of any 1914 * 11g channel returned, 1915 * otherwise we should be ok with what we've got. 1916 */ 1917 switch (vap->iv_des_mode) { 1918 case IEEE80211_MODE_11B: 1919 if (IEEE80211_IS_CHAN_ANYG(c)) { 1920 c2 = findchannel(ic, ireq->i_val, 1921 IEEE80211_MODE_11B); 1922 /* NB: should not happen, =>'s 11g w/o 11b */ 1923 if (c2 != NULL) 1924 c = c2; 1925 } 1926 break; 1927 case IEEE80211_MODE_TURBO_A: 1928 if (IEEE80211_IS_CHAN_A(c)) { 1929 c2 = findchannel(ic, ireq->i_val, 1930 IEEE80211_MODE_TURBO_A); 1931 if (c2 != NULL) 1932 c = c2; 1933 } 1934 break; 1935 case IEEE80211_MODE_11NA: 1936 if (IEEE80211_IS_CHAN_A(c)) { 1937 c2 = findchannel(ic, ireq->i_val, 1938 IEEE80211_MODE_11NA); 1939 if (c2 != NULL) 1940 c = c2; 1941 } 1942 break; 1943 case IEEE80211_MODE_11NG: 1944 if (IEEE80211_IS_CHAN_ANYG(c)) { 1945 c2 = findchannel(ic, ireq->i_val, 1946 IEEE80211_MODE_11NG); 1947 if (c2 != NULL) 1948 c = c2; 1949 } 1950 break; 1951 default: /* NB: no static turboG */ 1952 break; 1953 } 1954 } 1955 return setcurchan(vap, c); 1956} 1957 1958/* 1959 * New/current api for setting the current channel; a complete 1960 * channel description is provide so there is no ambiguity in 1961 * identifying the channel. 1962 */ 1963static __noinline int 1964ieee80211_ioctl_setcurchan(struct ieee80211vap *vap, 1965 const struct ieee80211req *ireq) 1966{ 1967 struct ieee80211com *ic = vap->iv_ic; 1968 struct ieee80211_channel chan, *c; 1969 int error; 1970 1971 if (ireq->i_len != sizeof(chan)) 1972 return EINVAL; 1973 error = copyin(ireq->i_data, &chan, sizeof(chan)); 1974 if (error != 0) 1975 return error; 1976 /* XXX 0xffff overflows 16-bit signed */ 1977 if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) { 1978 c = IEEE80211_CHAN_ANYC; 1979 } else { 1980 c = ieee80211_find_channel(ic, chan.ic_freq, chan.ic_flags); 1981 if (c == NULL) 1982 return EINVAL; 1983 } 1984 return setcurchan(vap, c); 1985} 1986 1987static __noinline int 1988ieee80211_ioctl_setregdomain(struct ieee80211vap *vap, 1989 const struct ieee80211req *ireq) 1990{ 1991 struct ieee80211_regdomain_req *reg; 1992 int error; 1993 1994 if (ireq->i_len != sizeof(struct ieee80211_regdomain_req)) 1995 return EINVAL;
|
1995 reg = malloc( sizeof(struct ieee80211_regdomain_req), M_TEMP, M_NOWAIT);
| 1996 MALLOC(reg, struct ieee80211_regdomain_req *, 1997 sizeof(struct ieee80211_regdomain_req), M_TEMP, M_NOWAIT);
|
1996 if (reg == NULL) 1997 return ENOMEM; 1998 error = copyin(ireq->i_data, reg, sizeof(*reg)); 1999 if (error == 0) 2000 error = ieee80211_setregdomain(vap, reg);
| 1998 if (reg == NULL) 1999 return ENOMEM; 2000 error = copyin(ireq->i_data, reg, sizeof(*reg)); 2001 if (error == 0) 2002 error = ieee80211_setregdomain(vap, reg);
|
2001 free(reg, M_TEMP);
| 2003 FREE(reg, M_TEMP);
|
2002 2003 return (error == 0 ? ENETRESET : error); 2004} 2005 2006static int 2007ieee80211_ioctl_setroam(struct ieee80211vap *vap, 2008 const struct ieee80211req *ireq) 2009{ 2010 if (ireq->i_len != sizeof(vap->iv_roamparms)) 2011 return EINVAL; 2012 /* XXX validate params */ 2013 /* XXX? ENETRESET to push to device? */ 2014 return copyin(ireq->i_data, vap->iv_roamparms, 2015 sizeof(vap->iv_roamparms)); 2016} 2017 2018static int 2019checkrate(const struct ieee80211_rateset *rs, int rate) 2020{ 2021 int i; 2022 2023 if (rate == IEEE80211_FIXED_RATE_NONE) 2024 return 1; 2025 for (i = 0; i < rs->rs_nrates; i++) 2026 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) 2027 return 1; 2028 return 0; 2029} 2030 2031static int 2032checkmcs(int mcs) 2033{ 2034 if (mcs == IEEE80211_FIXED_RATE_NONE) 2035 return 1; 2036 if ((mcs & IEEE80211_RATE_MCS) == 0) /* MCS always have 0x80 set */ 2037 return 0; 2038 return (mcs & 0x7f) <= 15; /* XXX could search ht rate set */ 2039} 2040 2041static __noinline int 2042ieee80211_ioctl_settxparams(struct ieee80211vap *vap, 2043 const struct ieee80211req *ireq) 2044{ 2045 struct ieee80211com *ic = vap->iv_ic; 2046 struct ieee80211_txparams_req parms; /* XXX stack use? */ 2047 struct ieee80211_txparam *src, *dst; 2048 const struct ieee80211_rateset *rs; 2049 int error, i, changed; 2050 2051 if (ireq->i_len != sizeof(parms)) 2052 return EINVAL; 2053 error = copyin(ireq->i_data, &parms, sizeof(parms)); 2054 if (error != 0) 2055 return error; 2056 changed = 0; 2057 /* validate parameters and check if anything changed */ 2058 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_11NA; i++) { 2059 if (isclr(ic->ic_modecaps, i)) 2060 continue; 2061 src = &parms.params[i]; 2062 dst = &vap->iv_txparms[i]; 2063 rs = &ic->ic_sup_rates[i]; 2064 if (src->ucastrate != dst->ucastrate) { 2065 if (!checkrate(rs, src->ucastrate)) 2066 return EINVAL; 2067 changed++; 2068 } 2069 if (src->mcastrate != dst->mcastrate) { 2070 if (!checkrate(rs, src->mcastrate)) 2071 return EINVAL; 2072 changed++; 2073 } 2074 if (src->mgmtrate != dst->mgmtrate) { 2075 if (!checkrate(rs, src->mgmtrate)) 2076 return EINVAL; 2077 changed++; 2078 } 2079 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2080 changed++; 2081 } 2082 /* 11n parameters are handled differently */ 2083 for (; i < IEEE80211_MODE_MAX; i++) { 2084 if (isclr(ic->ic_modecaps, i)) 2085 continue; 2086 src = &parms.params[i]; 2087 dst = &vap->iv_txparms[i]; 2088 rs = &ic->ic_sup_rates[i == IEEE80211_MODE_11NA ? 2089 IEEE80211_MODE_11A : IEEE80211_MODE_11G]; 2090 if (src->ucastrate != dst->ucastrate) { 2091 if (!checkmcs(src->ucastrate) && 2092 !checkrate(rs, src->ucastrate)) 2093 return EINVAL; 2094 changed++; 2095 } 2096 if (src->mcastrate != dst->mcastrate) { 2097 if (!checkmcs(src->mcastrate) && 2098 !checkrate(rs, src->mcastrate)) 2099 return EINVAL; 2100 changed++; 2101 } 2102 if (src->mgmtrate != dst->mgmtrate) { 2103 if (!checkmcs(src->mgmtrate) && 2104 !checkrate(rs, src->mgmtrate)) 2105 return EINVAL; 2106 changed++; 2107 } 2108 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2109 changed++; 2110 } 2111 if (changed) { 2112 /* 2113 * Copy new parameters in place and notify the 2114 * driver so it can push state to the device. 2115 */ 2116 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) { 2117 if (isset(ic->ic_modecaps, i)) 2118 vap->iv_txparms[i] = parms.params[i]; 2119 } 2120 /* XXX could be more intelligent, 2121 e.g. don't reset if setting not being used */ 2122 return ENETRESET; 2123 } 2124 return 0; 2125} 2126 2127/* 2128 * Application Information Element support. 2129 */ 2130static int 2131setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq) 2132{ 2133 struct ieee80211_appie *app = *aie; 2134 struct ieee80211_appie *napp; 2135 int error; 2136 2137 if (ireq->i_len == 0) { /* delete any existing ie */ 2138 if (app != NULL) { 2139 *aie = NULL; /* XXX racey */
| 2004 2005 return (error == 0 ? ENETRESET : error); 2006} 2007 2008static int 2009ieee80211_ioctl_setroam(struct ieee80211vap *vap, 2010 const struct ieee80211req *ireq) 2011{ 2012 if (ireq->i_len != sizeof(vap->iv_roamparms)) 2013 return EINVAL; 2014 /* XXX validate params */ 2015 /* XXX? ENETRESET to push to device? */ 2016 return copyin(ireq->i_data, vap->iv_roamparms, 2017 sizeof(vap->iv_roamparms)); 2018} 2019 2020static int 2021checkrate(const struct ieee80211_rateset *rs, int rate) 2022{ 2023 int i; 2024 2025 if (rate == IEEE80211_FIXED_RATE_NONE) 2026 return 1; 2027 for (i = 0; i < rs->rs_nrates; i++) 2028 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) 2029 return 1; 2030 return 0; 2031} 2032 2033static int 2034checkmcs(int mcs) 2035{ 2036 if (mcs == IEEE80211_FIXED_RATE_NONE) 2037 return 1; 2038 if ((mcs & IEEE80211_RATE_MCS) == 0) /* MCS always have 0x80 set */ 2039 return 0; 2040 return (mcs & 0x7f) <= 15; /* XXX could search ht rate set */ 2041} 2042 2043static __noinline int 2044ieee80211_ioctl_settxparams(struct ieee80211vap *vap, 2045 const struct ieee80211req *ireq) 2046{ 2047 struct ieee80211com *ic = vap->iv_ic; 2048 struct ieee80211_txparams_req parms; /* XXX stack use? */ 2049 struct ieee80211_txparam *src, *dst; 2050 const struct ieee80211_rateset *rs; 2051 int error, i, changed; 2052 2053 if (ireq->i_len != sizeof(parms)) 2054 return EINVAL; 2055 error = copyin(ireq->i_data, &parms, sizeof(parms)); 2056 if (error != 0) 2057 return error; 2058 changed = 0; 2059 /* validate parameters and check if anything changed */ 2060 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_11NA; i++) { 2061 if (isclr(ic->ic_modecaps, i)) 2062 continue; 2063 src = &parms.params[i]; 2064 dst = &vap->iv_txparms[i]; 2065 rs = &ic->ic_sup_rates[i]; 2066 if (src->ucastrate != dst->ucastrate) { 2067 if (!checkrate(rs, src->ucastrate)) 2068 return EINVAL; 2069 changed++; 2070 } 2071 if (src->mcastrate != dst->mcastrate) { 2072 if (!checkrate(rs, src->mcastrate)) 2073 return EINVAL; 2074 changed++; 2075 } 2076 if (src->mgmtrate != dst->mgmtrate) { 2077 if (!checkrate(rs, src->mgmtrate)) 2078 return EINVAL; 2079 changed++; 2080 } 2081 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2082 changed++; 2083 } 2084 /* 11n parameters are handled differently */ 2085 for (; i < IEEE80211_MODE_MAX; i++) { 2086 if (isclr(ic->ic_modecaps, i)) 2087 continue; 2088 src = &parms.params[i]; 2089 dst = &vap->iv_txparms[i]; 2090 rs = &ic->ic_sup_rates[i == IEEE80211_MODE_11NA ? 2091 IEEE80211_MODE_11A : IEEE80211_MODE_11G]; 2092 if (src->ucastrate != dst->ucastrate) { 2093 if (!checkmcs(src->ucastrate) && 2094 !checkrate(rs, src->ucastrate)) 2095 return EINVAL; 2096 changed++; 2097 } 2098 if (src->mcastrate != dst->mcastrate) { 2099 if (!checkmcs(src->mcastrate) && 2100 !checkrate(rs, src->mcastrate)) 2101 return EINVAL; 2102 changed++; 2103 } 2104 if (src->mgmtrate != dst->mgmtrate) { 2105 if (!checkmcs(src->mgmtrate) && 2106 !checkrate(rs, src->mgmtrate)) 2107 return EINVAL; 2108 changed++; 2109 } 2110 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2111 changed++; 2112 } 2113 if (changed) { 2114 /* 2115 * Copy new parameters in place and notify the 2116 * driver so it can push state to the device. 2117 */ 2118 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) { 2119 if (isset(ic->ic_modecaps, i)) 2120 vap->iv_txparms[i] = parms.params[i]; 2121 } 2122 /* XXX could be more intelligent, 2123 e.g. don't reset if setting not being used */ 2124 return ENETRESET; 2125 } 2126 return 0; 2127} 2128 2129/* 2130 * Application Information Element support. 2131 */ 2132static int 2133setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq) 2134{ 2135 struct ieee80211_appie *app = *aie; 2136 struct ieee80211_appie *napp; 2137 int error; 2138 2139 if (ireq->i_len == 0) { /* delete any existing ie */ 2140 if (app != NULL) { 2141 *aie = NULL; /* XXX racey */
|
2140 free(app, M_80211_NODE_IE);
| 2142 FREE(app, M_80211_NODE_IE);
|
2141 } 2142 return 0; 2143 } 2144 if (!(2 <= ireq->i_len && ireq->i_len <= IEEE80211_MAX_APPIE)) 2145 return EINVAL; 2146 /* 2147 * Allocate a new appie structure and copy in the user data. 2148 * When done swap in the new structure. Note that we do not 2149 * guard against users holding a ref to the old structure; 2150 * this must be handled outside this code. 2151 * 2152 * XXX bad bad bad 2153 */
| 2143 } 2144 return 0; 2145 } 2146 if (!(2 <= ireq->i_len && ireq->i_len <= IEEE80211_MAX_APPIE)) 2147 return EINVAL; 2148 /* 2149 * Allocate a new appie structure and copy in the user data. 2150 * When done swap in the new structure. Note that we do not 2151 * guard against users holding a ref to the old structure; 2152 * this must be handled outside this code. 2153 * 2154 * XXX bad bad bad 2155 */
|
2154 napp = malloc( sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT);
| 2156 MALLOC(napp, struct ieee80211_appie *, 2157 sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT);
|
2155 if (napp == NULL) 2156 return ENOMEM; 2157 /* XXX holding ic lock */ 2158 error = copyin(ireq->i_data, napp->ie_data, ireq->i_len); 2159 if (error) {
| 2158 if (napp == NULL) 2159 return ENOMEM; 2160 /* XXX holding ic lock */ 2161 error = copyin(ireq->i_data, napp->ie_data, ireq->i_len); 2162 if (error) {
|
2160 free(napp, M_80211_NODE_IE);
| 2163 FREE(napp, M_80211_NODE_IE);
|
2161 return error; 2162 } 2163 napp->ie_len = ireq->i_len; 2164 *aie = napp; 2165 if (app != NULL)
| 2164 return error; 2165 } 2166 napp->ie_len = ireq->i_len; 2167 *aie = napp; 2168 if (app != NULL)
|
2166 free(app, M_80211_NODE_IE);
| 2169 FREE(app, M_80211_NODE_IE);
|
2167 return 0; 2168} 2169 2170static void 2171setwparsnie(struct ieee80211vap *vap, uint8_t *ie, int space) 2172{ 2173 /* validate data is present as best we can */ 2174 if (space == 0 || 2+ie[1] > space) 2175 return; 2176 if (ie[0] == IEEE80211_ELEMID_VENDOR) 2177 vap->iv_wpa_ie = ie; 2178 else if (ie[0] == IEEE80211_ELEMID_RSN) 2179 vap->iv_rsn_ie = ie; 2180} 2181 2182static __noinline int 2183ieee80211_ioctl_setappie_locked(struct ieee80211vap *vap, 2184 const struct ieee80211req *ireq, int fc0) 2185{ 2186 int error; 2187 2188 IEEE80211_LOCK_ASSERT(vap->iv_ic); 2189 2190 switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { 2191 case IEEE80211_FC0_SUBTYPE_BEACON: 2192 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2193 vap->iv_opmode != IEEE80211_M_IBSS) { 2194 error = EINVAL; 2195 break; 2196 } 2197 error = setappie(&vap->iv_appie_beacon, ireq); 2198 if (error == 0) 2199 ieee80211_beacon_notify(vap, IEEE80211_BEACON_APPIE); 2200 break; 2201 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2202 error = setappie(&vap->iv_appie_proberesp, ireq); 2203 break; 2204 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2205 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2206 error = setappie(&vap->iv_appie_assocresp, ireq); 2207 else 2208 error = EINVAL; 2209 break; 2210 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2211 error = setappie(&vap->iv_appie_probereq, ireq); 2212 break; 2213 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2214 if (vap->iv_opmode == IEEE80211_M_STA) 2215 error = setappie(&vap->iv_appie_assocreq, ireq); 2216 else 2217 error = EINVAL; 2218 break; 2219 case (IEEE80211_APPIE_WPA & IEEE80211_FC0_SUBTYPE_MASK): 2220 error = setappie(&vap->iv_appie_wpa, ireq); 2221 if (error == 0) { 2222 /* 2223 * Must split single blob of data into separate 2224 * WPA and RSN ie's because they go in different 2225 * locations in the mgt frames. 2226 * XXX use IEEE80211_IOC_WPA2 so user code does split 2227 */ 2228 vap->iv_wpa_ie = NULL; 2229 vap->iv_rsn_ie = NULL; 2230 if (vap->iv_appie_wpa != NULL) { 2231 struct ieee80211_appie *appie = 2232 vap->iv_appie_wpa; 2233 uint8_t *data = appie->ie_data; 2234 2235 /* XXX ie length validate is painful, cheat */ 2236 setwparsnie(vap, data, appie->ie_len); 2237 setwparsnie(vap, data + 2 + data[1], 2238 appie->ie_len - (2 + data[1])); 2239 } 2240 if (vap->iv_opmode == IEEE80211_M_HOSTAP || 2241 vap->iv_opmode == IEEE80211_M_IBSS) { 2242 /* 2243 * Must rebuild beacon frame as the update 2244 * mechanism doesn't handle WPA/RSN ie's. 2245 * Could extend it but it doesn't normally 2246 * change; this is just to deal with hostapd 2247 * plumbing the ie after the interface is up. 2248 */ 2249 error = ENETRESET; 2250 } 2251 } 2252 break; 2253 default: 2254 error = EINVAL; 2255 break; 2256 } 2257 return error; 2258} 2259 2260static __noinline int 2261ieee80211_ioctl_setappie(struct ieee80211vap *vap, 2262 const struct ieee80211req *ireq) 2263{ 2264 struct ieee80211com *ic = vap->iv_ic; 2265 int error; 2266 uint8_t fc0; 2267 2268 fc0 = ireq->i_val & 0xff; 2269 if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) 2270 return EINVAL; 2271 /* NB: could check iv_opmode and reject but hardly worth the effort */ 2272 IEEE80211_LOCK(ic); 2273 error = ieee80211_ioctl_setappie_locked(vap, ireq, fc0); 2274 IEEE80211_UNLOCK(ic); 2275 return error; 2276} 2277 2278static __noinline int 2279ieee80211_ioctl_chanswitch(struct ieee80211vap *vap, struct ieee80211req *ireq) 2280{ 2281 struct ieee80211com *ic = vap->iv_ic; 2282 struct ieee80211_chanswitch_req csr; 2283 struct ieee80211_channel *c; 2284 int error; 2285 2286 if (ireq->i_len != sizeof(csr)) 2287 return EINVAL; 2288 error = copyin(ireq->i_data, &csr, sizeof(csr)); 2289 if (error != 0) 2290 return error; 2291 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 2292 return EINVAL; 2293 c = ieee80211_find_channel(ic, 2294 csr.csa_chan.ic_freq, csr.csa_chan.ic_flags); 2295 if (c == NULL) 2296 return ENOENT; 2297 IEEE80211_LOCK(ic); 2298 if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) 2299 ieee80211_csa_startswitch(ic, c, csr.csa_mode, csr.csa_count); 2300 else 2301 error = EBUSY; 2302 IEEE80211_UNLOCK(ic); 2303 return error; 2304} 2305 2306static __noinline int 2307ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq) 2308{ 2309#define IEEE80211_IOC_SCAN_FLAGS \ 2310 (IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \ 2311 IEEE80211_IOC_SCAN_PICK1ST | IEEE80211_IOC_SCAN_BGSCAN | \ 2312 IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOBCAST | \ 2313 IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \ 2314 IEEE80211_IOC_SCAN_CHECK) 2315 struct ieee80211com *ic = vap->iv_ic; 2316 struct ieee80211_scan_req sr; /* XXX off stack? */ 2317 int error, i; 2318 2319 /* NB: parent must be running */ 2320 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 2321 return ENXIO; 2322 2323 if (ireq->i_len != sizeof(sr)) 2324 return EINVAL; 2325 error = copyin(ireq->i_data, &sr, sizeof(sr)); 2326 if (error != 0) 2327 return error; 2328 /* convert duration */ 2329 if (sr.sr_duration == IEEE80211_IOC_SCAN_FOREVER) 2330 sr.sr_duration = IEEE80211_SCAN_FOREVER; 2331 else { 2332 if (sr.sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN || 2333 sr.sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX) 2334 return EINVAL; 2335 sr.sr_duration = msecs_to_ticks(sr.sr_duration); 2336 if (sr.sr_duration < 1) 2337 sr.sr_duration = 1; 2338 } 2339 /* convert min/max channel dwell */ 2340 if (sr.sr_mindwell != 0) { 2341 sr.sr_mindwell = msecs_to_ticks(sr.sr_mindwell); 2342 if (sr.sr_mindwell < 1) 2343 sr.sr_mindwell = 1; 2344 } 2345 if (sr.sr_maxdwell != 0) { 2346 sr.sr_maxdwell = msecs_to_ticks(sr.sr_maxdwell); 2347 if (sr.sr_maxdwell < 1) 2348 sr.sr_maxdwell = 1; 2349 } 2350 /* NB: silently reduce ssid count to what is supported */ 2351 if (sr.sr_nssid > IEEE80211_SCAN_MAX_SSID) 2352 sr.sr_nssid = IEEE80211_SCAN_MAX_SSID; 2353 for (i = 0; i < sr.sr_nssid; i++) 2354 if (sr.sr_ssid[i].len > IEEE80211_NWID_LEN) 2355 return EINVAL; 2356 /* cleanse flags just in case, could reject if invalid flags */ 2357 sr.sr_flags &= IEEE80211_IOC_SCAN_FLAGS; 2358 /* 2359 * Add an implicit NOPICK if the vap is not marked UP. This 2360 * allows applications to scan without joining a bss (or picking 2361 * a channel and setting up a bss) and without forcing manual 2362 * roaming mode--you just need to mark the parent device UP. 2363 */ 2364 if ((vap->iv_ifp->if_flags & IFF_UP) == 0) 2365 sr.sr_flags |= IEEE80211_IOC_SCAN_NOPICK; 2366 2367 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2368 "%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n", 2369 __func__, sr.sr_flags, 2370 (vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "", 2371 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, sr.sr_nssid); 2372 /* 2373 * If we are in INIT state then the driver has never had a chance 2374 * to setup hardware state to do a scan; we must use the state 2375 * machine to get us up to the SCAN state but once we reach SCAN 2376 * state we then want to use the supplied params. Stash the 2377 * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the 2378 * state machines will recognize this and use the stashed params 2379 * to issue the scan request. 2380 * 2381 * Otherwise just invoke the scan machinery directly. 2382 */ 2383 IEEE80211_LOCK(ic); 2384 if (vap->iv_state == IEEE80211_S_INIT) { 2385 /* NB: clobbers previous settings */ 2386 vap->iv_scanreq_flags = sr.sr_flags; 2387 vap->iv_scanreq_duration = sr.sr_duration; 2388 vap->iv_scanreq_nssid = sr.sr_nssid; 2389 for (i = 0; i < sr.sr_nssid; i++) { 2390 vap->iv_scanreq_ssid[i].len = sr.sr_ssid[i].len; 2391 memcpy(vap->iv_scanreq_ssid[i].ssid, sr.sr_ssid[i].ssid, 2392 sr.sr_ssid[i].len); 2393 } 2394 vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ; 2395 IEEE80211_UNLOCK(ic); 2396 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2397 } else { 2398 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; 2399 IEEE80211_UNLOCK(ic); 2400 /* XXX neeed error return codes */ 2401 if (sr.sr_flags & IEEE80211_IOC_SCAN_CHECK) { 2402 (void) ieee80211_check_scan(vap, sr.sr_flags, 2403 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2404 sr.sr_nssid, 2405 /* NB: cheat, we assume structures are compatible */ 2406 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2407 } else { 2408 (void) ieee80211_start_scan(vap, sr.sr_flags, 2409 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2410 sr.sr_nssid, 2411 /* NB: cheat, we assume structures are compatible */ 2412 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2413 } 2414 } 2415 return error; 2416#undef IEEE80211_IOC_SCAN_FLAGS 2417} 2418 2419static __noinline int 2420ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) 2421{ 2422 struct ieee80211_node *ni; 2423 struct ieee80211req_sta_vlan vlan; 2424 int error; 2425 2426 if (ireq->i_len != sizeof(vlan)) 2427 return EINVAL; 2428 error = copyin(ireq->i_data, &vlan, sizeof(vlan)); 2429 if (error != 0) 2430 return error; 2431 if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { 2432 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 2433 vlan.sv_macaddr); 2434 if (ni == NULL) 2435 return ENOENT; 2436 } else 2437 ni = ieee80211_ref_node(vap->iv_bss); 2438 ni->ni_vlan = vlan.sv_vlan; 2439 ieee80211_free_node(ni); 2440 return error; 2441} 2442 2443static int 2444isvap11g(const struct ieee80211vap *vap) 2445{ 2446 const struct ieee80211_node *bss = vap->iv_bss; 2447 return bss->ni_chan != IEEE80211_CHAN_ANYC && 2448 IEEE80211_IS_CHAN_ANYG(bss->ni_chan); 2449} 2450 2451static int 2452isvapht(const struct ieee80211vap *vap) 2453{ 2454 const struct ieee80211_node *bss = vap->iv_bss; 2455 return bss->ni_chan != IEEE80211_CHAN_ANYC && 2456 IEEE80211_IS_CHAN_HT(bss->ni_chan); 2457} 2458 2459static __noinline int 2460ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211req *ireq) 2461{ 2462 struct ieee80211com *ic = vap->iv_ic; 2463 int error; 2464 const struct ieee80211_authenticator *auth; 2465 uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 2466 char tmpssid[IEEE80211_NWID_LEN]; 2467 uint8_t tmpbssid[IEEE80211_ADDR_LEN]; 2468 struct ieee80211_key *k; 2469 u_int kid; 2470 uint32_t flags; 2471 2472 error = 0; 2473 switch (ireq->i_type) { 2474 case IEEE80211_IOC_SSID: 2475 if (ireq->i_val != 0 || 2476 ireq->i_len > IEEE80211_NWID_LEN) 2477 return EINVAL; 2478 error = copyin(ireq->i_data, tmpssid, ireq->i_len); 2479 if (error) 2480 break; 2481 memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN); 2482 vap->iv_des_ssid[0].len = ireq->i_len; 2483 memcpy(vap->iv_des_ssid[0].ssid, tmpssid, ireq->i_len); 2484 vap->iv_des_nssid = (ireq->i_len > 0); 2485 error = ENETRESET; 2486 break; 2487 case IEEE80211_IOC_WEP: 2488 switch (ireq->i_val) { 2489 case IEEE80211_WEP_OFF: 2490 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2491 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2492 break; 2493 case IEEE80211_WEP_ON: 2494 vap->iv_flags |= IEEE80211_F_PRIVACY; 2495 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2496 break; 2497 case IEEE80211_WEP_MIXED: 2498 vap->iv_flags |= IEEE80211_F_PRIVACY; 2499 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2500 break; 2501 } 2502 error = ENETRESET; 2503 break; 2504 case IEEE80211_IOC_WEPKEY: 2505 kid = (u_int) ireq->i_val; 2506 if (kid >= IEEE80211_WEP_NKID) 2507 return EINVAL; 2508 k = &vap->iv_nw_keys[kid]; 2509 if (ireq->i_len == 0) { 2510 /* zero-len =>'s delete any existing key */ 2511 (void) ieee80211_crypto_delkey(vap, k); 2512 break; 2513 } 2514 if (ireq->i_len > sizeof(tmpkey)) 2515 return EINVAL; 2516 memset(tmpkey, 0, sizeof(tmpkey)); 2517 error = copyin(ireq->i_data, tmpkey, ireq->i_len); 2518 if (error) 2519 break; 2520 ieee80211_key_update_begin(vap); 2521 k->wk_keyix = kid; /* NB: force fixed key id */ 2522 if (ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP, 2523 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) { 2524 k->wk_keylen = ireq->i_len; 2525 memcpy(k->wk_key, tmpkey, sizeof(tmpkey)); 2526 IEEE80211_ADDR_COPY(k->wk_macaddr, vap->iv_myaddr); 2527 if (!ieee80211_crypto_setkey(vap, k)) 2528 error = EINVAL; 2529 } else 2530 error = EINVAL; 2531 ieee80211_key_update_end(vap); 2532 break; 2533 case IEEE80211_IOC_WEPTXKEY: 2534 kid = (u_int) ireq->i_val; 2535 if (kid >= IEEE80211_WEP_NKID && 2536 (uint16_t) kid != IEEE80211_KEYIX_NONE) 2537 return EINVAL; 2538 vap->iv_def_txkey = kid; 2539 break; 2540 case IEEE80211_IOC_AUTHMODE: 2541 switch (ireq->i_val) { 2542 case IEEE80211_AUTH_WPA: 2543 case IEEE80211_AUTH_8021X: /* 802.1x */ 2544 case IEEE80211_AUTH_OPEN: /* open */ 2545 case IEEE80211_AUTH_SHARED: /* shared-key */ 2546 case IEEE80211_AUTH_AUTO: /* auto */ 2547 auth = ieee80211_authenticator_get(ireq->i_val); 2548 if (auth == NULL) 2549 return EINVAL; 2550 break; 2551 default: 2552 return EINVAL; 2553 } 2554 switch (ireq->i_val) { 2555 case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ 2556 vap->iv_flags |= IEEE80211_F_PRIVACY; 2557 ireq->i_val = IEEE80211_AUTH_8021X; 2558 break; 2559 case IEEE80211_AUTH_OPEN: /* open */ 2560 vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY); 2561 break; 2562 case IEEE80211_AUTH_SHARED: /* shared-key */ 2563 case IEEE80211_AUTH_8021X: /* 802.1x */ 2564 vap->iv_flags &= ~IEEE80211_F_WPA; 2565 /* both require a key so mark the PRIVACY capability */ 2566 vap->iv_flags |= IEEE80211_F_PRIVACY; 2567 break; 2568 case IEEE80211_AUTH_AUTO: /* auto */ 2569 vap->iv_flags &= ~IEEE80211_F_WPA; 2570 /* XXX PRIVACY handling? */ 2571 /* XXX what's the right way to do this? */ 2572 break; 2573 } 2574 /* NB: authenticator attach/detach happens on state change */ 2575 vap->iv_bss->ni_authmode = ireq->i_val; 2576 /* XXX mixed/mode/usage? */ 2577 vap->iv_auth = auth; 2578 error = ENETRESET; 2579 break; 2580 case IEEE80211_IOC_CHANNEL: 2581 error = ieee80211_ioctl_setchannel(vap, ireq); 2582 break; 2583 case IEEE80211_IOC_POWERSAVE: 2584 switch (ireq->i_val) { 2585 case IEEE80211_POWERSAVE_OFF: 2586 if (vap->iv_flags & IEEE80211_F_PMGTON) { 2587 ieee80211_syncflag(vap, -IEEE80211_F_PMGTON); 2588 error = ERESTART; 2589 } 2590 break; 2591 case IEEE80211_POWERSAVE_ON: 2592 if ((vap->iv_caps & IEEE80211_C_PMGT) == 0) 2593 error = EOPNOTSUPP; 2594 else if ((vap->iv_flags & IEEE80211_F_PMGTON) == 0) { 2595 ieee80211_syncflag(vap, IEEE80211_F_PMGTON); 2596 error = ERESTART; 2597 } 2598 break; 2599 default: 2600 error = EINVAL; 2601 break; 2602 } 2603 break; 2604 case IEEE80211_IOC_POWERSAVESLEEP: 2605 if (ireq->i_val < 0) 2606 return EINVAL; 2607 ic->ic_lintval = ireq->i_val; 2608 error = ERESTART; 2609 break; 2610 case IEEE80211_IOC_RTSTHRESHOLD: 2611 if (!(IEEE80211_RTS_MIN <= ireq->i_val && 2612 ireq->i_val <= IEEE80211_RTS_MAX)) 2613 return EINVAL; 2614 vap->iv_rtsthreshold = ireq->i_val; 2615 error = ERESTART; 2616 break; 2617 case IEEE80211_IOC_PROTMODE: 2618 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 2619 return EINVAL; 2620 ic->ic_protmode = ireq->i_val; 2621 /* NB: if not operating in 11g this can wait */ 2622 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && 2623 IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) 2624 error = ERESTART; 2625 break; 2626 case IEEE80211_IOC_TXPOWER: 2627 if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) 2628 return EOPNOTSUPP; 2629 if (!(IEEE80211_TXPOWER_MIN <= ireq->i_val && 2630 ireq->i_val <= IEEE80211_TXPOWER_MAX)) 2631 return EINVAL; 2632 ic->ic_txpowlimit = ireq->i_val; 2633 error = ERESTART; 2634 break; 2635 case IEEE80211_IOC_ROAMING: 2636 if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val && 2637 ireq->i_val <= IEEE80211_ROAMING_MANUAL)) 2638 return EINVAL; 2639 vap->iv_roaming = ireq->i_val; 2640 /* XXXX reset? */ 2641 break; 2642 case IEEE80211_IOC_PRIVACY: 2643 if (ireq->i_val) { 2644 /* XXX check for key state? */ 2645 vap->iv_flags |= IEEE80211_F_PRIVACY; 2646 } else 2647 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2648 /* XXX ERESTART? */ 2649 break; 2650 case IEEE80211_IOC_DROPUNENCRYPTED: 2651 if (ireq->i_val) 2652 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2653 else 2654 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2655 /* XXX ERESTART? */ 2656 break; 2657 case IEEE80211_IOC_WPAKEY: 2658 error = ieee80211_ioctl_setkey(vap, ireq); 2659 break; 2660 case IEEE80211_IOC_DELKEY: 2661 error = ieee80211_ioctl_delkey(vap, ireq); 2662 break; 2663 case IEEE80211_IOC_MLME: 2664 error = ieee80211_ioctl_setmlme(vap, ireq); 2665 break; 2666 case IEEE80211_IOC_COUNTERMEASURES: 2667 if (ireq->i_val) { 2668 if ((vap->iv_flags & IEEE80211_F_WPA) == 0) 2669 return EOPNOTSUPP; 2670 vap->iv_flags |= IEEE80211_F_COUNTERM; 2671 } else 2672 vap->iv_flags &= ~IEEE80211_F_COUNTERM; 2673 /* XXX ERESTART? */ 2674 break; 2675 case IEEE80211_IOC_WPA: 2676 if (ireq->i_val > 3) 2677 return EINVAL; 2678 /* XXX verify ciphers available */ 2679 flags = vap->iv_flags & ~IEEE80211_F_WPA; 2680 switch (ireq->i_val) { 2681 case 1: 2682 if (!(vap->iv_caps & IEEE80211_C_WPA1)) 2683 return EOPNOTSUPP; 2684 flags |= IEEE80211_F_WPA1; 2685 break; 2686 case 2: 2687 if (!(vap->iv_caps & IEEE80211_C_WPA2)) 2688 return EOPNOTSUPP; 2689 flags |= IEEE80211_F_WPA2; 2690 break; 2691 case 3: 2692 if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA) 2693 flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; 2694 break; 2695 default: /* Can't set any -> error */ 2696 return EOPNOTSUPP; 2697 } 2698 vap->iv_flags = flags; 2699 error = ERESTART; /* NB: can change beacon frame */ 2700 break; 2701 case IEEE80211_IOC_WME: 2702 if (ireq->i_val) { 2703 if ((vap->iv_caps & IEEE80211_C_WME) == 0) 2704 return EOPNOTSUPP; 2705 ieee80211_syncflag(vap, IEEE80211_F_WME); 2706 } else 2707 ieee80211_syncflag(vap, -IEEE80211_F_WME); 2708 error = ERESTART; /* NB: can change beacon frame */ 2709 break; 2710 case IEEE80211_IOC_HIDESSID: 2711 if (ireq->i_val) 2712 vap->iv_flags |= IEEE80211_F_HIDESSID; 2713 else 2714 vap->iv_flags &= ~IEEE80211_F_HIDESSID; 2715 error = ERESTART; /* XXX ENETRESET? */ 2716 break; 2717 case IEEE80211_IOC_APBRIDGE: 2718 if (ireq->i_val == 0) 2719 vap->iv_flags |= IEEE80211_F_NOBRIDGE; 2720 else 2721 vap->iv_flags &= ~IEEE80211_F_NOBRIDGE; 2722 break; 2723 case IEEE80211_IOC_BSSID: 2724 if (ireq->i_len != sizeof(tmpbssid)) 2725 return EINVAL; 2726 error = copyin(ireq->i_data, tmpbssid, ireq->i_len); 2727 if (error) 2728 break; 2729 IEEE80211_ADDR_COPY(vap->iv_des_bssid, tmpbssid); 2730 if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, zerobssid)) 2731 vap->iv_flags &= ~IEEE80211_F_DESBSSID; 2732 else 2733 vap->iv_flags |= IEEE80211_F_DESBSSID; 2734 error = ENETRESET; 2735 break; 2736 case IEEE80211_IOC_CHANLIST: 2737 error = ieee80211_ioctl_setchanlist(vap, ireq); 2738 break; 2739#define OLD_IEEE80211_IOC_SCAN_REQ 23 2740#ifdef OLD_IEEE80211_IOC_SCAN_REQ 2741 case OLD_IEEE80211_IOC_SCAN_REQ: 2742 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2743 "%s: active scan request\n", __func__); 2744 /* 2745 * If we are in INIT state then the driver has never 2746 * had a chance to setup hardware state to do a scan; 2747 * use the state machine to get us up the SCAN state. 2748 * Otherwise just invoke the scan machinery to start 2749 * a one-time scan. 2750 */ 2751 if (vap->iv_state == IEEE80211_S_INIT) 2752 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2753 else 2754 (void) ieee80211_start_scan(vap, 2755 IEEE80211_SCAN_ACTIVE | 2756 IEEE80211_SCAN_NOPICK | 2757 IEEE80211_SCAN_ONCE, 2758 IEEE80211_SCAN_FOREVER, 0, 0, 2759 /* XXX use ioctl params */ 2760 vap->iv_des_nssid, vap->iv_des_ssid); 2761 break; 2762#endif /* OLD_IEEE80211_IOC_SCAN_REQ */ 2763 case IEEE80211_IOC_SCAN_REQ: 2764 error = ieee80211_ioctl_scanreq(vap, ireq); 2765 break; 2766 case IEEE80211_IOC_SCAN_CANCEL: 2767 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2768 "%s: cancel scan\n", __func__); 2769 ieee80211_cancel_scan(vap); 2770 break; 2771 case IEEE80211_IOC_HTCONF: 2772 if (ireq->i_val & 1) 2773 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_HT); 2774 else 2775 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_HT); 2776 if (ireq->i_val & 2) 2777 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_USEHT40); 2778 else 2779 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_USEHT40); 2780 error = ENETRESET; 2781 break; 2782 case IEEE80211_IOC_ADDMAC: 2783 case IEEE80211_IOC_DELMAC: 2784 error = ieee80211_ioctl_macmac(vap, ireq); 2785 break; 2786 case IEEE80211_IOC_MACCMD: 2787 error = ieee80211_ioctl_setmaccmd(vap, ireq); 2788 break; 2789 case IEEE80211_IOC_STA_STATS: 2790 error = ieee80211_ioctl_setstastats(vap, ireq); 2791 break; 2792 case IEEE80211_IOC_STA_TXPOW: 2793 error = ieee80211_ioctl_setstatxpow(vap, ireq); 2794 break; 2795 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2796 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2797 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2798 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2799 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2800 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 2801 error = ieee80211_ioctl_setwmeparam(vap, ireq); 2802 break; 2803 case IEEE80211_IOC_DTIM_PERIOD: 2804 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2805 vap->iv_opmode != IEEE80211_M_IBSS) 2806 return EINVAL; 2807 if (IEEE80211_DTIM_MIN <= ireq->i_val && 2808 ireq->i_val <= IEEE80211_DTIM_MAX) { 2809 vap->iv_dtim_period = ireq->i_val; 2810 error = ENETRESET; /* requires restart */ 2811 } else 2812 error = EINVAL; 2813 break; 2814 case IEEE80211_IOC_BEACON_INTERVAL: 2815 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2816 vap->iv_opmode != IEEE80211_M_IBSS) 2817 return EINVAL; 2818 if (IEEE80211_BINTVAL_MIN <= ireq->i_val && 2819 ireq->i_val <= IEEE80211_BINTVAL_MAX) { 2820 ic->ic_bintval = ireq->i_val; 2821 error = ENETRESET; /* requires restart */ 2822 } else 2823 error = EINVAL; 2824 break; 2825 case IEEE80211_IOC_PUREG: 2826 if (ireq->i_val) 2827 vap->iv_flags |= IEEE80211_F_PUREG; 2828 else 2829 vap->iv_flags &= ~IEEE80211_F_PUREG; 2830 /* NB: reset only if we're operating on an 11g channel */ 2831 if (isvap11g(vap)) 2832 error = ENETRESET; 2833 break; 2834 case IEEE80211_IOC_FF: 2835 if (ireq->i_val) { 2836 if ((vap->iv_caps & IEEE80211_C_FF) == 0) 2837 return EOPNOTSUPP; 2838 vap->iv_flags |= IEEE80211_F_FF; 2839 } else 2840 vap->iv_flags &= ~IEEE80211_F_FF; 2841 error = ERESTART; 2842 break; 2843 case IEEE80211_IOC_TURBOP: 2844 if (ireq->i_val) { 2845 if ((vap->iv_caps & IEEE80211_C_TURBOP) == 0) 2846 return EOPNOTSUPP; 2847 vap->iv_flags |= IEEE80211_F_TURBOP; 2848 } else 2849 vap->iv_flags &= ~IEEE80211_F_TURBOP; 2850 error = ENETRESET; 2851 break; 2852 case IEEE80211_IOC_BGSCAN: 2853 if (ireq->i_val) { 2854 if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0) 2855 return EOPNOTSUPP; 2856 vap->iv_flags |= IEEE80211_F_BGSCAN; 2857 } else 2858 vap->iv_flags &= ~IEEE80211_F_BGSCAN; 2859 break; 2860 case IEEE80211_IOC_BGSCAN_IDLE: 2861 if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN) 2862 vap->iv_bgscanidle = ireq->i_val*hz/1000; 2863 else 2864 error = EINVAL; 2865 break; 2866 case IEEE80211_IOC_BGSCAN_INTERVAL: 2867 if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN) 2868 vap->iv_bgscanintvl = ireq->i_val*hz; 2869 else 2870 error = EINVAL; 2871 break; 2872 case IEEE80211_IOC_SCANVALID: 2873 if (ireq->i_val >= IEEE80211_SCAN_VALID_MIN) 2874 vap->iv_scanvalid = ireq->i_val*hz; 2875 else 2876 error = EINVAL; 2877 break; 2878 case IEEE80211_IOC_FRAGTHRESHOLD: 2879 if ((vap->iv_caps & IEEE80211_C_TXFRAG) == 0 && 2880 ireq->i_val != IEEE80211_FRAG_MAX) 2881 return EOPNOTSUPP; 2882 if (!(IEEE80211_FRAG_MIN <= ireq->i_val && 2883 ireq->i_val <= IEEE80211_FRAG_MAX)) 2884 return EINVAL; 2885 vap->iv_fragthreshold = ireq->i_val; 2886 error = ERESTART; 2887 break; 2888 case IEEE80211_IOC_BURST: 2889 if (ireq->i_val) { 2890 if ((vap->iv_caps & IEEE80211_C_BURST) == 0) 2891 return EOPNOTSUPP; 2892 ieee80211_syncflag(vap, IEEE80211_F_BURST); 2893 } else 2894 ieee80211_syncflag(vap, -IEEE80211_F_BURST); 2895 error = ERESTART; 2896 break; 2897 case IEEE80211_IOC_BMISSTHRESHOLD: 2898 if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val && 2899 ireq->i_val <= IEEE80211_HWBMISS_MAX)) 2900 return EINVAL; 2901 vap->iv_bmissthreshold = ireq->i_val; 2902 error = ERESTART; 2903 break; 2904 case IEEE80211_IOC_CURCHAN: 2905 error = ieee80211_ioctl_setcurchan(vap, ireq); 2906 break; 2907 case IEEE80211_IOC_SHORTGI: 2908 if (ireq->i_val) { 2909#define IEEE80211_HTCAP_SHORTGI \ 2910 (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40) 2911 if (((ireq->i_val ^ vap->iv_htcaps) & IEEE80211_HTCAP_SHORTGI) != 0) 2912 return EINVAL; 2913 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI20) 2914 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI20; 2915 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI40) 2916 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI40; 2917#undef IEEE80211_HTCAP_SHORTGI 2918 } else 2919 vap->iv_flags_ext &= 2920 ~(IEEE80211_FEXT_SHORTGI20 | IEEE80211_FEXT_SHORTGI40); 2921 error = ERESTART; 2922 break; 2923 case IEEE80211_IOC_AMPDU: 2924 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0) 2925 return EINVAL; 2926 if (ireq->i_val & 1) 2927 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_TX; 2928 else 2929 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_TX; 2930 if (ireq->i_val & 2) 2931 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_RX; 2932 else 2933 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_RX; 2934 /* NB: reset only if we're operating on an 11n channel */ 2935 if (isvapht(vap)) 2936 error = ERESTART; 2937 break; 2938 case IEEE80211_IOC_AMPDU_LIMIT: 2939 if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val && 2940 ireq->i_val <= IEEE80211_HTCAP_MAXRXAMPDU_64K)) 2941 return EINVAL; 2942 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2943 vap->iv_ampdu_rxmax = ireq->i_val; 2944 else 2945 vap->iv_ampdu_limit = ireq->i_val; 2946 error = ERESTART; 2947 break; 2948 case IEEE80211_IOC_AMPDU_DENSITY: 2949 if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val && 2950 ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16)) 2951 return EINVAL; 2952 vap->iv_ampdu_density = ireq->i_val; 2953 error = ERESTART; 2954 break; 2955 case IEEE80211_IOC_AMSDU: 2956 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0) 2957 return EINVAL; 2958 if (ireq->i_val & 1) 2959 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_TX; 2960 else 2961 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_TX; 2962 if (ireq->i_val & 2) 2963 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_RX; 2964 else 2965 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_RX; 2966 /* NB: reset only if we're operating on an 11n channel */ 2967 if (isvapht(vap)) 2968 error = ERESTART; 2969 break; 2970 case IEEE80211_IOC_AMSDU_LIMIT: 2971 /* XXX validate */ 2972 vap->iv_amsdu_limit = ireq->i_val; /* XXX truncation? */ 2973 break; 2974 case IEEE80211_IOC_PUREN: 2975 if (ireq->i_val) { 2976 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 2977 return EINVAL; 2978 vap->iv_flags_ext |= IEEE80211_FEXT_PUREN; 2979 } else 2980 vap->iv_flags_ext &= ~IEEE80211_FEXT_PUREN; 2981 /* NB: reset only if we're operating on an 11n channel */ 2982 if (isvapht(vap)) 2983 error = ERESTART; 2984 break; 2985 case IEEE80211_IOC_DOTH: 2986 if (ireq->i_val) { 2987#if 0 2988 /* XXX no capability */ 2989 if ((vap->iv_caps & IEEE80211_C_DOTH) == 0) 2990 return EOPNOTSUPP; 2991#endif 2992 vap->iv_flags |= IEEE80211_F_DOTH; 2993 } else 2994 vap->iv_flags &= ~IEEE80211_F_DOTH; 2995 error = ENETRESET; 2996 break; 2997 case IEEE80211_IOC_REGDOMAIN: 2998 error = ieee80211_ioctl_setregdomain(vap, ireq); 2999 break; 3000 case IEEE80211_IOC_ROAM: 3001 error = ieee80211_ioctl_setroam(vap, ireq); 3002 break; 3003 case IEEE80211_IOC_TXPARAMS: 3004 error = ieee80211_ioctl_settxparams(vap, ireq); 3005 break; 3006 case IEEE80211_IOC_HTCOMPAT: 3007 if (ireq->i_val) { 3008 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 3009 return EOPNOTSUPP; 3010 vap->iv_flags_ext |= IEEE80211_FEXT_HTCOMPAT; 3011 } else 3012 vap->iv_flags_ext &= ~IEEE80211_FEXT_HTCOMPAT; 3013 /* NB: reset only if we're operating on an 11n channel */ 3014 if (isvapht(vap)) 3015 error = ERESTART; 3016 break; 3017 case IEEE80211_IOC_DWDS: 3018 if (ireq->i_val) { 3019 /* NB: DWDS only makes sense for WDS-capable devices */ 3020 if ((ic->ic_caps & IEEE80211_C_WDS) == 0) 3021 return EOPNOTSUPP; 3022 /* NB: DWDS is used only with ap+sta vaps */ 3023 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 3024 vap->iv_opmode != IEEE80211_M_STA) 3025 return EINVAL; 3026 vap->iv_flags |= IEEE80211_F_DWDS; 3027 } else 3028 vap->iv_flags &= ~IEEE80211_F_DWDS; 3029 break; 3030 case IEEE80211_IOC_INACTIVITY: 3031 if (ireq->i_val) 3032 vap->iv_flags_ext |= IEEE80211_FEXT_INACT; 3033 else 3034 vap->iv_flags_ext &= ~IEEE80211_FEXT_INACT; 3035 break; 3036 case IEEE80211_IOC_APPIE: 3037 error = ieee80211_ioctl_setappie(vap, ireq); 3038 break; 3039 case IEEE80211_IOC_WPS: 3040 if (ireq->i_val) { 3041 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3042 return EOPNOTSUPP; 3043 vap->iv_flags_ext |= IEEE80211_FEXT_WPS; 3044 } else 3045 vap->iv_flags_ext &= ~IEEE80211_FEXT_WPS; 3046 break; 3047 case IEEE80211_IOC_TSN: 3048 if (ireq->i_val) { 3049 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3050 return EOPNOTSUPP; 3051 vap->iv_flags_ext |= IEEE80211_FEXT_TSN; 3052 } else 3053 vap->iv_flags_ext &= ~IEEE80211_FEXT_TSN; 3054 break; 3055 case IEEE80211_IOC_CHANSWITCH: 3056 error = ieee80211_ioctl_chanswitch(vap, ireq); 3057 break; 3058 case IEEE80211_IOC_DFS: 3059 if (ireq->i_val) { 3060 if ((vap->iv_caps & IEEE80211_C_DFS) == 0) 3061 return EOPNOTSUPP; 3062 /* NB: DFS requires 11h support */ 3063 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 3064 return EINVAL; 3065 vap->iv_flags_ext |= IEEE80211_FEXT_DFS; 3066 } else 3067 vap->iv_flags_ext &= ~IEEE80211_FEXT_DFS; 3068 break; 3069 case IEEE80211_IOC_DOTD: 3070 if (ireq->i_val) 3071 vap->iv_flags_ext |= IEEE80211_FEXT_DOTD; 3072 else 3073 vap->iv_flags_ext &= ~IEEE80211_FEXT_DOTD; 3074 if (vap->iv_opmode == IEEE80211_M_STA) 3075 error = ENETRESET; 3076 break; 3077 case IEEE80211_IOC_HTPROTMODE: 3078 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 3079 return EINVAL; 3080 ic->ic_htprotmode = ireq->i_val ? 3081 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE; 3082 /* NB: if not operating in 11n this can wait */ 3083 if (isvapht(vap)) 3084 error = ERESTART; 3085 break; 3086 case IEEE80211_IOC_STA_VLAN: 3087 error = ieee80211_ioctl_setstavlan(vap, ireq); 3088 break; 3089 case IEEE80211_IOC_SMPS: 3090 if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 || 3091 ireq->i_val == 0x0008) /* value of 2 is reserved */ 3092 return EINVAL; 3093 if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF && 3094 (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0) 3095 return EOPNOTSUPP; 3096 vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) | 3097 ireq->i_val; 3098 /* NB: if not operating in 11n this can wait */ 3099 if (isvapht(vap)) 3100 error = ERESTART; 3101 break; 3102 case IEEE80211_IOC_RIFS: 3103 if (ireq->i_val != 0) { 3104 if ((vap->iv_htcaps & IEEE80211_HTC_RIFS) == 0) 3105 return EOPNOTSUPP; 3106 vap->iv_flags_ext |= IEEE80211_FEXT_RIFS; 3107 } else 3108 vap->iv_flags_ext &= ~IEEE80211_FEXT_RIFS; 3109 /* NB: if not operating in 11n this can wait */ 3110 if (isvapht(vap)) 3111 error = ERESTART; 3112 break; 3113 default: 3114 error = EINVAL; 3115 break; 3116 } 3117 /* 3118 * The convention is that ENETRESET means an operation 3119 * requires a complete re-initialization of the device (e.g. 3120 * changing something that affects the association state). 3121 * ERESTART means the request may be handled with only a 3122 * reload of the hardware state. We hand ERESTART requests 3123 * to the iv_reset callback so the driver can decide. If 3124 * a device does not fillin iv_reset then it defaults to one 3125 * that returns ENETRESET. Otherwise a driver may return 3126 * ENETRESET (in which case a full reset will be done) or 3127 * 0 to mean there's no need to do anything (e.g. when the 3128 * change has no effect on the driver/device). 3129 */ 3130 if (error == ERESTART) 3131 error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ? 3132 vap->iv_reset(vap, ireq->i_type) : 0; 3133 if (error == ENETRESET) { 3134 /* XXX need to re-think AUTO handling */ 3135 if (IS_UP_AUTO(vap)) 3136 ieee80211_init(vap); 3137 error = 0; 3138 } 3139 return error; 3140} 3141 3142/* 3143 * Rebuild the parent's multicast address list after an add/del 3144 * of a multicast address for a vap. We have no way to tell 3145 * what happened above to optimize the work so we purge the entire 3146 * list and rebuild from scratch. This is way expensive. 3147 * Note also the half-baked workaround for if_addmulti calling 3148 * back to the parent device; there's no way to insert mcast 3149 * entries quietly and/or cheaply. 3150 */ 3151static void 3152ieee80211_ioctl_updatemulti(struct ieee80211com *ic) 3153{ 3154 struct ifnet *parent = ic->ic_ifp; 3155 struct ieee80211vap *vap; 3156 void *ioctl; 3157 3158 IEEE80211_LOCK(ic); 3159 if_purgemaddrs(parent); 3160 ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */ 3161 parent->if_ioctl = NULL; 3162 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 3163 struct ifnet *ifp = vap->iv_ifp; 3164 struct ifmultiaddr *ifma; 3165 3166 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) 3167 (void) if_addmulti(parent, ifma->ifma_addr, NULL); 3168 } 3169 parent->if_ioctl = ioctl; 3170 3171 ic->ic_update_mcast(ic->ic_ifp); 3172 IEEE80211_UNLOCK(ic); 3173} 3174 3175int 3176ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 3177{ 3178 struct ieee80211vap *vap; 3179 struct ieee80211com *ic; 3180 int error = 0; 3181 struct ifreq *ifr; 3182 struct ifaddr *ifa; /* XXX */ 3183 3184 vap = ifp->if_softc; 3185 if (vap == NULL) { 3186 /* 3187 * During detach we clear the backpointer in the softc 3188 * so any ioctl request through the ifnet that arrives 3189 * before teardown is ignored/rejected. In particular 3190 * this hack handles destroying a vap used by an app 3191 * like wpa_supplicant that will respond to the vap 3192 * being forced into INIT state by immediately trying 3193 * to force it back up. We can yank this hack if/when 3194 * we can destroy the ifnet before cleaning up vap state. 3195 */ 3196 return ENXIO; 3197 } 3198 switch (cmd) { 3199 case SIOCSIFFLAGS: 3200 ic = vap->iv_ic; 3201 IEEE80211_LOCK(ic); 3202 ieee80211_syncifflag_locked(ic, IFF_PROMISC); 3203 ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); 3204 if (ifp->if_flags & IFF_UP) { 3205 /* 3206 * Bring ourself up unless we're already operational. 3207 * If we're the first vap and the parent is not up 3208 * then it will automatically be brought up as a 3209 * side-effect of bringing ourself up. 3210 */ 3211 if (vap->iv_state == IEEE80211_S_INIT) 3212 ieee80211_start_locked(vap); 3213 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 3214 /* 3215 * Stop ourself. If we are the last vap to be 3216 * marked down the parent will also be taken down. 3217 */ 3218 ieee80211_stop_locked(vap); 3219 } 3220 IEEE80211_UNLOCK(ic); 3221 break; 3222 case SIOCADDMULTI: 3223 case SIOCDELMULTI: 3224 ieee80211_ioctl_updatemulti(vap->iv_ic); 3225 break; 3226 case SIOCSIFMEDIA: 3227 case SIOCGIFMEDIA: 3228 ifr = (struct ifreq *)data; 3229 error = ifmedia_ioctl(ifp, ifr, &vap->iv_media, cmd); 3230 break; 3231 case SIOCG80211: 3232 error = ieee80211_ioctl_get80211(vap, cmd, 3233 (struct ieee80211req *) data); 3234 break; 3235 case SIOCS80211: 3236 error = priv_check(curthread, PRIV_NET80211_MANAGE); 3237 if (error == 0) 3238 error = ieee80211_ioctl_set80211(vap, cmd, 3239 (struct ieee80211req *) data); 3240 break; 3241 case SIOCG80211STATS: 3242 ifr = (struct ifreq *)data; 3243 copyout(&vap->iv_stats, ifr->ifr_data, sizeof (vap->iv_stats)); 3244 break; 3245 case SIOCSIFMTU: 3246 ifr = (struct ifreq *)data; 3247 if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu && 3248 ifr->ifr_mtu <= IEEE80211_MTU_MAX)) 3249 error = EINVAL; 3250 else 3251 ifp->if_mtu = ifr->ifr_mtu; 3252 break; 3253 case SIOCSIFADDR: 3254 /* 3255 * XXX Handle this directly so we can supress if_init calls. 3256 * XXX This should be done in ether_ioctl but for the moment 3257 * XXX there are too many other parts of the system that 3258 * XXX set IFF_UP and so supress if_init being called when 3259 * XXX it should be. 3260 */ 3261 ifa = (struct ifaddr *) data; 3262 switch (ifa->ifa_addr->sa_family) { 3263#ifdef INET 3264 case AF_INET: 3265 if ((ifp->if_flags & IFF_UP) == 0) { 3266 ifp->if_flags |= IFF_UP; 3267 ifp->if_init(ifp->if_softc); 3268 } 3269 arp_ifinit(ifp, ifa); 3270 break; 3271#endif 3272#ifdef IPX 3273 /* 3274 * XXX - This code is probably wrong, 3275 * but has been copied many times. 3276 */ 3277 case AF_IPX: { 3278 struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 3279 3280 if (ipx_nullhost(*ina)) 3281 ina->x_host = *(union ipx_host *) 3282 IF_LLADDR(ifp); 3283 else 3284 bcopy((caddr_t) ina->x_host.c_host, 3285 (caddr_t) IF_LLADDR(ifp), 3286 ETHER_ADDR_LEN); 3287 /* fall thru... */ 3288 } 3289#endif 3290 default: 3291 if ((ifp->if_flags & IFF_UP) == 0) { 3292 ifp->if_flags |= IFF_UP; 3293 ifp->if_init(ifp->if_softc); 3294 } 3295 break; 3296 } 3297 break; 3298 /* Pass NDIS ioctls up to the driver */ 3299 case SIOCGDRVSPEC: 3300 case SIOCSDRVSPEC: 3301 case SIOCGPRIVATE_0: { 3302 struct ifnet *parent = vap->iv_ic->ic_ifp; 3303 error = parent->if_ioctl(parent, cmd, data); 3304 break; 3305 } 3306 default: 3307 error = ether_ioctl(ifp, cmd, data); 3308 break; 3309 } 3310 return error; 3311}
| 2170 return 0; 2171} 2172 2173static void 2174setwparsnie(struct ieee80211vap *vap, uint8_t *ie, int space) 2175{ 2176 /* validate data is present as best we can */ 2177 if (space == 0 || 2+ie[1] > space) 2178 return; 2179 if (ie[0] == IEEE80211_ELEMID_VENDOR) 2180 vap->iv_wpa_ie = ie; 2181 else if (ie[0] == IEEE80211_ELEMID_RSN) 2182 vap->iv_rsn_ie = ie; 2183} 2184 2185static __noinline int 2186ieee80211_ioctl_setappie_locked(struct ieee80211vap *vap, 2187 const struct ieee80211req *ireq, int fc0) 2188{ 2189 int error; 2190 2191 IEEE80211_LOCK_ASSERT(vap->iv_ic); 2192 2193 switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { 2194 case IEEE80211_FC0_SUBTYPE_BEACON: 2195 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2196 vap->iv_opmode != IEEE80211_M_IBSS) { 2197 error = EINVAL; 2198 break; 2199 } 2200 error = setappie(&vap->iv_appie_beacon, ireq); 2201 if (error == 0) 2202 ieee80211_beacon_notify(vap, IEEE80211_BEACON_APPIE); 2203 break; 2204 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2205 error = setappie(&vap->iv_appie_proberesp, ireq); 2206 break; 2207 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2208 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2209 error = setappie(&vap->iv_appie_assocresp, ireq); 2210 else 2211 error = EINVAL; 2212 break; 2213 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2214 error = setappie(&vap->iv_appie_probereq, ireq); 2215 break; 2216 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2217 if (vap->iv_opmode == IEEE80211_M_STA) 2218 error = setappie(&vap->iv_appie_assocreq, ireq); 2219 else 2220 error = EINVAL; 2221 break; 2222 case (IEEE80211_APPIE_WPA & IEEE80211_FC0_SUBTYPE_MASK): 2223 error = setappie(&vap->iv_appie_wpa, ireq); 2224 if (error == 0) { 2225 /* 2226 * Must split single blob of data into separate 2227 * WPA and RSN ie's because they go in different 2228 * locations in the mgt frames. 2229 * XXX use IEEE80211_IOC_WPA2 so user code does split 2230 */ 2231 vap->iv_wpa_ie = NULL; 2232 vap->iv_rsn_ie = NULL; 2233 if (vap->iv_appie_wpa != NULL) { 2234 struct ieee80211_appie *appie = 2235 vap->iv_appie_wpa; 2236 uint8_t *data = appie->ie_data; 2237 2238 /* XXX ie length validate is painful, cheat */ 2239 setwparsnie(vap, data, appie->ie_len); 2240 setwparsnie(vap, data + 2 + data[1], 2241 appie->ie_len - (2 + data[1])); 2242 } 2243 if (vap->iv_opmode == IEEE80211_M_HOSTAP || 2244 vap->iv_opmode == IEEE80211_M_IBSS) { 2245 /* 2246 * Must rebuild beacon frame as the update 2247 * mechanism doesn't handle WPA/RSN ie's. 2248 * Could extend it but it doesn't normally 2249 * change; this is just to deal with hostapd 2250 * plumbing the ie after the interface is up. 2251 */ 2252 error = ENETRESET; 2253 } 2254 } 2255 break; 2256 default: 2257 error = EINVAL; 2258 break; 2259 } 2260 return error; 2261} 2262 2263static __noinline int 2264ieee80211_ioctl_setappie(struct ieee80211vap *vap, 2265 const struct ieee80211req *ireq) 2266{ 2267 struct ieee80211com *ic = vap->iv_ic; 2268 int error; 2269 uint8_t fc0; 2270 2271 fc0 = ireq->i_val & 0xff; 2272 if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) 2273 return EINVAL; 2274 /* NB: could check iv_opmode and reject but hardly worth the effort */ 2275 IEEE80211_LOCK(ic); 2276 error = ieee80211_ioctl_setappie_locked(vap, ireq, fc0); 2277 IEEE80211_UNLOCK(ic); 2278 return error; 2279} 2280 2281static __noinline int 2282ieee80211_ioctl_chanswitch(struct ieee80211vap *vap, struct ieee80211req *ireq) 2283{ 2284 struct ieee80211com *ic = vap->iv_ic; 2285 struct ieee80211_chanswitch_req csr; 2286 struct ieee80211_channel *c; 2287 int error; 2288 2289 if (ireq->i_len != sizeof(csr)) 2290 return EINVAL; 2291 error = copyin(ireq->i_data, &csr, sizeof(csr)); 2292 if (error != 0) 2293 return error; 2294 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 2295 return EINVAL; 2296 c = ieee80211_find_channel(ic, 2297 csr.csa_chan.ic_freq, csr.csa_chan.ic_flags); 2298 if (c == NULL) 2299 return ENOENT; 2300 IEEE80211_LOCK(ic); 2301 if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) 2302 ieee80211_csa_startswitch(ic, c, csr.csa_mode, csr.csa_count); 2303 else 2304 error = EBUSY; 2305 IEEE80211_UNLOCK(ic); 2306 return error; 2307} 2308 2309static __noinline int 2310ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq) 2311{ 2312#define IEEE80211_IOC_SCAN_FLAGS \ 2313 (IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \ 2314 IEEE80211_IOC_SCAN_PICK1ST | IEEE80211_IOC_SCAN_BGSCAN | \ 2315 IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOBCAST | \ 2316 IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \ 2317 IEEE80211_IOC_SCAN_CHECK) 2318 struct ieee80211com *ic = vap->iv_ic; 2319 struct ieee80211_scan_req sr; /* XXX off stack? */ 2320 int error, i; 2321 2322 /* NB: parent must be running */ 2323 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 2324 return ENXIO; 2325 2326 if (ireq->i_len != sizeof(sr)) 2327 return EINVAL; 2328 error = copyin(ireq->i_data, &sr, sizeof(sr)); 2329 if (error != 0) 2330 return error; 2331 /* convert duration */ 2332 if (sr.sr_duration == IEEE80211_IOC_SCAN_FOREVER) 2333 sr.sr_duration = IEEE80211_SCAN_FOREVER; 2334 else { 2335 if (sr.sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN || 2336 sr.sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX) 2337 return EINVAL; 2338 sr.sr_duration = msecs_to_ticks(sr.sr_duration); 2339 if (sr.sr_duration < 1) 2340 sr.sr_duration = 1; 2341 } 2342 /* convert min/max channel dwell */ 2343 if (sr.sr_mindwell != 0) { 2344 sr.sr_mindwell = msecs_to_ticks(sr.sr_mindwell); 2345 if (sr.sr_mindwell < 1) 2346 sr.sr_mindwell = 1; 2347 } 2348 if (sr.sr_maxdwell != 0) { 2349 sr.sr_maxdwell = msecs_to_ticks(sr.sr_maxdwell); 2350 if (sr.sr_maxdwell < 1) 2351 sr.sr_maxdwell = 1; 2352 } 2353 /* NB: silently reduce ssid count to what is supported */ 2354 if (sr.sr_nssid > IEEE80211_SCAN_MAX_SSID) 2355 sr.sr_nssid = IEEE80211_SCAN_MAX_SSID; 2356 for (i = 0; i < sr.sr_nssid; i++) 2357 if (sr.sr_ssid[i].len > IEEE80211_NWID_LEN) 2358 return EINVAL; 2359 /* cleanse flags just in case, could reject if invalid flags */ 2360 sr.sr_flags &= IEEE80211_IOC_SCAN_FLAGS; 2361 /* 2362 * Add an implicit NOPICK if the vap is not marked UP. This 2363 * allows applications to scan without joining a bss (or picking 2364 * a channel and setting up a bss) and without forcing manual 2365 * roaming mode--you just need to mark the parent device UP. 2366 */ 2367 if ((vap->iv_ifp->if_flags & IFF_UP) == 0) 2368 sr.sr_flags |= IEEE80211_IOC_SCAN_NOPICK; 2369 2370 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2371 "%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n", 2372 __func__, sr.sr_flags, 2373 (vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "", 2374 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, sr.sr_nssid); 2375 /* 2376 * If we are in INIT state then the driver has never had a chance 2377 * to setup hardware state to do a scan; we must use the state 2378 * machine to get us up to the SCAN state but once we reach SCAN 2379 * state we then want to use the supplied params. Stash the 2380 * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the 2381 * state machines will recognize this and use the stashed params 2382 * to issue the scan request. 2383 * 2384 * Otherwise just invoke the scan machinery directly. 2385 */ 2386 IEEE80211_LOCK(ic); 2387 if (vap->iv_state == IEEE80211_S_INIT) { 2388 /* NB: clobbers previous settings */ 2389 vap->iv_scanreq_flags = sr.sr_flags; 2390 vap->iv_scanreq_duration = sr.sr_duration; 2391 vap->iv_scanreq_nssid = sr.sr_nssid; 2392 for (i = 0; i < sr.sr_nssid; i++) { 2393 vap->iv_scanreq_ssid[i].len = sr.sr_ssid[i].len; 2394 memcpy(vap->iv_scanreq_ssid[i].ssid, sr.sr_ssid[i].ssid, 2395 sr.sr_ssid[i].len); 2396 } 2397 vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ; 2398 IEEE80211_UNLOCK(ic); 2399 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2400 } else { 2401 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; 2402 IEEE80211_UNLOCK(ic); 2403 /* XXX neeed error return codes */ 2404 if (sr.sr_flags & IEEE80211_IOC_SCAN_CHECK) { 2405 (void) ieee80211_check_scan(vap, sr.sr_flags, 2406 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2407 sr.sr_nssid, 2408 /* NB: cheat, we assume structures are compatible */ 2409 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2410 } else { 2411 (void) ieee80211_start_scan(vap, sr.sr_flags, 2412 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2413 sr.sr_nssid, 2414 /* NB: cheat, we assume structures are compatible */ 2415 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2416 } 2417 } 2418 return error; 2419#undef IEEE80211_IOC_SCAN_FLAGS 2420} 2421 2422static __noinline int 2423ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) 2424{ 2425 struct ieee80211_node *ni; 2426 struct ieee80211req_sta_vlan vlan; 2427 int error; 2428 2429 if (ireq->i_len != sizeof(vlan)) 2430 return EINVAL; 2431 error = copyin(ireq->i_data, &vlan, sizeof(vlan)); 2432 if (error != 0) 2433 return error; 2434 if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { 2435 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 2436 vlan.sv_macaddr); 2437 if (ni == NULL) 2438 return ENOENT; 2439 } else 2440 ni = ieee80211_ref_node(vap->iv_bss); 2441 ni->ni_vlan = vlan.sv_vlan; 2442 ieee80211_free_node(ni); 2443 return error; 2444} 2445 2446static int 2447isvap11g(const struct ieee80211vap *vap) 2448{ 2449 const struct ieee80211_node *bss = vap->iv_bss; 2450 return bss->ni_chan != IEEE80211_CHAN_ANYC && 2451 IEEE80211_IS_CHAN_ANYG(bss->ni_chan); 2452} 2453 2454static int 2455isvapht(const struct ieee80211vap *vap) 2456{ 2457 const struct ieee80211_node *bss = vap->iv_bss; 2458 return bss->ni_chan != IEEE80211_CHAN_ANYC && 2459 IEEE80211_IS_CHAN_HT(bss->ni_chan); 2460} 2461 2462static __noinline int 2463ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211req *ireq) 2464{ 2465 struct ieee80211com *ic = vap->iv_ic; 2466 int error; 2467 const struct ieee80211_authenticator *auth; 2468 uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 2469 char tmpssid[IEEE80211_NWID_LEN]; 2470 uint8_t tmpbssid[IEEE80211_ADDR_LEN]; 2471 struct ieee80211_key *k; 2472 u_int kid; 2473 uint32_t flags; 2474 2475 error = 0; 2476 switch (ireq->i_type) { 2477 case IEEE80211_IOC_SSID: 2478 if (ireq->i_val != 0 || 2479 ireq->i_len > IEEE80211_NWID_LEN) 2480 return EINVAL; 2481 error = copyin(ireq->i_data, tmpssid, ireq->i_len); 2482 if (error) 2483 break; 2484 memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN); 2485 vap->iv_des_ssid[0].len = ireq->i_len; 2486 memcpy(vap->iv_des_ssid[0].ssid, tmpssid, ireq->i_len); 2487 vap->iv_des_nssid = (ireq->i_len > 0); 2488 error = ENETRESET; 2489 break; 2490 case IEEE80211_IOC_WEP: 2491 switch (ireq->i_val) { 2492 case IEEE80211_WEP_OFF: 2493 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2494 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2495 break; 2496 case IEEE80211_WEP_ON: 2497 vap->iv_flags |= IEEE80211_F_PRIVACY; 2498 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2499 break; 2500 case IEEE80211_WEP_MIXED: 2501 vap->iv_flags |= IEEE80211_F_PRIVACY; 2502 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2503 break; 2504 } 2505 error = ENETRESET; 2506 break; 2507 case IEEE80211_IOC_WEPKEY: 2508 kid = (u_int) ireq->i_val; 2509 if (kid >= IEEE80211_WEP_NKID) 2510 return EINVAL; 2511 k = &vap->iv_nw_keys[kid]; 2512 if (ireq->i_len == 0) { 2513 /* zero-len =>'s delete any existing key */ 2514 (void) ieee80211_crypto_delkey(vap, k); 2515 break; 2516 } 2517 if (ireq->i_len > sizeof(tmpkey)) 2518 return EINVAL; 2519 memset(tmpkey, 0, sizeof(tmpkey)); 2520 error = copyin(ireq->i_data, tmpkey, ireq->i_len); 2521 if (error) 2522 break; 2523 ieee80211_key_update_begin(vap); 2524 k->wk_keyix = kid; /* NB: force fixed key id */ 2525 if (ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP, 2526 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) { 2527 k->wk_keylen = ireq->i_len; 2528 memcpy(k->wk_key, tmpkey, sizeof(tmpkey)); 2529 IEEE80211_ADDR_COPY(k->wk_macaddr, vap->iv_myaddr); 2530 if (!ieee80211_crypto_setkey(vap, k)) 2531 error = EINVAL; 2532 } else 2533 error = EINVAL; 2534 ieee80211_key_update_end(vap); 2535 break; 2536 case IEEE80211_IOC_WEPTXKEY: 2537 kid = (u_int) ireq->i_val; 2538 if (kid >= IEEE80211_WEP_NKID && 2539 (uint16_t) kid != IEEE80211_KEYIX_NONE) 2540 return EINVAL; 2541 vap->iv_def_txkey = kid; 2542 break; 2543 case IEEE80211_IOC_AUTHMODE: 2544 switch (ireq->i_val) { 2545 case IEEE80211_AUTH_WPA: 2546 case IEEE80211_AUTH_8021X: /* 802.1x */ 2547 case IEEE80211_AUTH_OPEN: /* open */ 2548 case IEEE80211_AUTH_SHARED: /* shared-key */ 2549 case IEEE80211_AUTH_AUTO: /* auto */ 2550 auth = ieee80211_authenticator_get(ireq->i_val); 2551 if (auth == NULL) 2552 return EINVAL; 2553 break; 2554 default: 2555 return EINVAL; 2556 } 2557 switch (ireq->i_val) { 2558 case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ 2559 vap->iv_flags |= IEEE80211_F_PRIVACY; 2560 ireq->i_val = IEEE80211_AUTH_8021X; 2561 break; 2562 case IEEE80211_AUTH_OPEN: /* open */ 2563 vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY); 2564 break; 2565 case IEEE80211_AUTH_SHARED: /* shared-key */ 2566 case IEEE80211_AUTH_8021X: /* 802.1x */ 2567 vap->iv_flags &= ~IEEE80211_F_WPA; 2568 /* both require a key so mark the PRIVACY capability */ 2569 vap->iv_flags |= IEEE80211_F_PRIVACY; 2570 break; 2571 case IEEE80211_AUTH_AUTO: /* auto */ 2572 vap->iv_flags &= ~IEEE80211_F_WPA; 2573 /* XXX PRIVACY handling? */ 2574 /* XXX what's the right way to do this? */ 2575 break; 2576 } 2577 /* NB: authenticator attach/detach happens on state change */ 2578 vap->iv_bss->ni_authmode = ireq->i_val; 2579 /* XXX mixed/mode/usage? */ 2580 vap->iv_auth = auth; 2581 error = ENETRESET; 2582 break; 2583 case IEEE80211_IOC_CHANNEL: 2584 error = ieee80211_ioctl_setchannel(vap, ireq); 2585 break; 2586 case IEEE80211_IOC_POWERSAVE: 2587 switch (ireq->i_val) { 2588 case IEEE80211_POWERSAVE_OFF: 2589 if (vap->iv_flags & IEEE80211_F_PMGTON) { 2590 ieee80211_syncflag(vap, -IEEE80211_F_PMGTON); 2591 error = ERESTART; 2592 } 2593 break; 2594 case IEEE80211_POWERSAVE_ON: 2595 if ((vap->iv_caps & IEEE80211_C_PMGT) == 0) 2596 error = EOPNOTSUPP; 2597 else if ((vap->iv_flags & IEEE80211_F_PMGTON) == 0) { 2598 ieee80211_syncflag(vap, IEEE80211_F_PMGTON); 2599 error = ERESTART; 2600 } 2601 break; 2602 default: 2603 error = EINVAL; 2604 break; 2605 } 2606 break; 2607 case IEEE80211_IOC_POWERSAVESLEEP: 2608 if (ireq->i_val < 0) 2609 return EINVAL; 2610 ic->ic_lintval = ireq->i_val; 2611 error = ERESTART; 2612 break; 2613 case IEEE80211_IOC_RTSTHRESHOLD: 2614 if (!(IEEE80211_RTS_MIN <= ireq->i_val && 2615 ireq->i_val <= IEEE80211_RTS_MAX)) 2616 return EINVAL; 2617 vap->iv_rtsthreshold = ireq->i_val; 2618 error = ERESTART; 2619 break; 2620 case IEEE80211_IOC_PROTMODE: 2621 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 2622 return EINVAL; 2623 ic->ic_protmode = ireq->i_val; 2624 /* NB: if not operating in 11g this can wait */ 2625 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && 2626 IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) 2627 error = ERESTART; 2628 break; 2629 case IEEE80211_IOC_TXPOWER: 2630 if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) 2631 return EOPNOTSUPP; 2632 if (!(IEEE80211_TXPOWER_MIN <= ireq->i_val && 2633 ireq->i_val <= IEEE80211_TXPOWER_MAX)) 2634 return EINVAL; 2635 ic->ic_txpowlimit = ireq->i_val; 2636 error = ERESTART; 2637 break; 2638 case IEEE80211_IOC_ROAMING: 2639 if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val && 2640 ireq->i_val <= IEEE80211_ROAMING_MANUAL)) 2641 return EINVAL; 2642 vap->iv_roaming = ireq->i_val; 2643 /* XXXX reset? */ 2644 break; 2645 case IEEE80211_IOC_PRIVACY: 2646 if (ireq->i_val) { 2647 /* XXX check for key state? */ 2648 vap->iv_flags |= IEEE80211_F_PRIVACY; 2649 } else 2650 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2651 /* XXX ERESTART? */ 2652 break; 2653 case IEEE80211_IOC_DROPUNENCRYPTED: 2654 if (ireq->i_val) 2655 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2656 else 2657 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2658 /* XXX ERESTART? */ 2659 break; 2660 case IEEE80211_IOC_WPAKEY: 2661 error = ieee80211_ioctl_setkey(vap, ireq); 2662 break; 2663 case IEEE80211_IOC_DELKEY: 2664 error = ieee80211_ioctl_delkey(vap, ireq); 2665 break; 2666 case IEEE80211_IOC_MLME: 2667 error = ieee80211_ioctl_setmlme(vap, ireq); 2668 break; 2669 case IEEE80211_IOC_COUNTERMEASURES: 2670 if (ireq->i_val) { 2671 if ((vap->iv_flags & IEEE80211_F_WPA) == 0) 2672 return EOPNOTSUPP; 2673 vap->iv_flags |= IEEE80211_F_COUNTERM; 2674 } else 2675 vap->iv_flags &= ~IEEE80211_F_COUNTERM; 2676 /* XXX ERESTART? */ 2677 break; 2678 case IEEE80211_IOC_WPA: 2679 if (ireq->i_val > 3) 2680 return EINVAL; 2681 /* XXX verify ciphers available */ 2682 flags = vap->iv_flags & ~IEEE80211_F_WPA; 2683 switch (ireq->i_val) { 2684 case 1: 2685 if (!(vap->iv_caps & IEEE80211_C_WPA1)) 2686 return EOPNOTSUPP; 2687 flags |= IEEE80211_F_WPA1; 2688 break; 2689 case 2: 2690 if (!(vap->iv_caps & IEEE80211_C_WPA2)) 2691 return EOPNOTSUPP; 2692 flags |= IEEE80211_F_WPA2; 2693 break; 2694 case 3: 2695 if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA) 2696 flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; 2697 break; 2698 default: /* Can't set any -> error */ 2699 return EOPNOTSUPP; 2700 } 2701 vap->iv_flags = flags; 2702 error = ERESTART; /* NB: can change beacon frame */ 2703 break; 2704 case IEEE80211_IOC_WME: 2705 if (ireq->i_val) { 2706 if ((vap->iv_caps & IEEE80211_C_WME) == 0) 2707 return EOPNOTSUPP; 2708 ieee80211_syncflag(vap, IEEE80211_F_WME); 2709 } else 2710 ieee80211_syncflag(vap, -IEEE80211_F_WME); 2711 error = ERESTART; /* NB: can change beacon frame */ 2712 break; 2713 case IEEE80211_IOC_HIDESSID: 2714 if (ireq->i_val) 2715 vap->iv_flags |= IEEE80211_F_HIDESSID; 2716 else 2717 vap->iv_flags &= ~IEEE80211_F_HIDESSID; 2718 error = ERESTART; /* XXX ENETRESET? */ 2719 break; 2720 case IEEE80211_IOC_APBRIDGE: 2721 if (ireq->i_val == 0) 2722 vap->iv_flags |= IEEE80211_F_NOBRIDGE; 2723 else 2724 vap->iv_flags &= ~IEEE80211_F_NOBRIDGE; 2725 break; 2726 case IEEE80211_IOC_BSSID: 2727 if (ireq->i_len != sizeof(tmpbssid)) 2728 return EINVAL; 2729 error = copyin(ireq->i_data, tmpbssid, ireq->i_len); 2730 if (error) 2731 break; 2732 IEEE80211_ADDR_COPY(vap->iv_des_bssid, tmpbssid); 2733 if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, zerobssid)) 2734 vap->iv_flags &= ~IEEE80211_F_DESBSSID; 2735 else 2736 vap->iv_flags |= IEEE80211_F_DESBSSID; 2737 error = ENETRESET; 2738 break; 2739 case IEEE80211_IOC_CHANLIST: 2740 error = ieee80211_ioctl_setchanlist(vap, ireq); 2741 break; 2742#define OLD_IEEE80211_IOC_SCAN_REQ 23 2743#ifdef OLD_IEEE80211_IOC_SCAN_REQ 2744 case OLD_IEEE80211_IOC_SCAN_REQ: 2745 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2746 "%s: active scan request\n", __func__); 2747 /* 2748 * If we are in INIT state then the driver has never 2749 * had a chance to setup hardware state to do a scan; 2750 * use the state machine to get us up the SCAN state. 2751 * Otherwise just invoke the scan machinery to start 2752 * a one-time scan. 2753 */ 2754 if (vap->iv_state == IEEE80211_S_INIT) 2755 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2756 else 2757 (void) ieee80211_start_scan(vap, 2758 IEEE80211_SCAN_ACTIVE | 2759 IEEE80211_SCAN_NOPICK | 2760 IEEE80211_SCAN_ONCE, 2761 IEEE80211_SCAN_FOREVER, 0, 0, 2762 /* XXX use ioctl params */ 2763 vap->iv_des_nssid, vap->iv_des_ssid); 2764 break; 2765#endif /* OLD_IEEE80211_IOC_SCAN_REQ */ 2766 case IEEE80211_IOC_SCAN_REQ: 2767 error = ieee80211_ioctl_scanreq(vap, ireq); 2768 break; 2769 case IEEE80211_IOC_SCAN_CANCEL: 2770 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2771 "%s: cancel scan\n", __func__); 2772 ieee80211_cancel_scan(vap); 2773 break; 2774 case IEEE80211_IOC_HTCONF: 2775 if (ireq->i_val & 1) 2776 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_HT); 2777 else 2778 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_HT); 2779 if (ireq->i_val & 2) 2780 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_USEHT40); 2781 else 2782 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_USEHT40); 2783 error = ENETRESET; 2784 break; 2785 case IEEE80211_IOC_ADDMAC: 2786 case IEEE80211_IOC_DELMAC: 2787 error = ieee80211_ioctl_macmac(vap, ireq); 2788 break; 2789 case IEEE80211_IOC_MACCMD: 2790 error = ieee80211_ioctl_setmaccmd(vap, ireq); 2791 break; 2792 case IEEE80211_IOC_STA_STATS: 2793 error = ieee80211_ioctl_setstastats(vap, ireq); 2794 break; 2795 case IEEE80211_IOC_STA_TXPOW: 2796 error = ieee80211_ioctl_setstatxpow(vap, ireq); 2797 break; 2798 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2799 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2800 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2801 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2802 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2803 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 2804 error = ieee80211_ioctl_setwmeparam(vap, ireq); 2805 break; 2806 case IEEE80211_IOC_DTIM_PERIOD: 2807 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2808 vap->iv_opmode != IEEE80211_M_IBSS) 2809 return EINVAL; 2810 if (IEEE80211_DTIM_MIN <= ireq->i_val && 2811 ireq->i_val <= IEEE80211_DTIM_MAX) { 2812 vap->iv_dtim_period = ireq->i_val; 2813 error = ENETRESET; /* requires restart */ 2814 } else 2815 error = EINVAL; 2816 break; 2817 case IEEE80211_IOC_BEACON_INTERVAL: 2818 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2819 vap->iv_opmode != IEEE80211_M_IBSS) 2820 return EINVAL; 2821 if (IEEE80211_BINTVAL_MIN <= ireq->i_val && 2822 ireq->i_val <= IEEE80211_BINTVAL_MAX) { 2823 ic->ic_bintval = ireq->i_val; 2824 error = ENETRESET; /* requires restart */ 2825 } else 2826 error = EINVAL; 2827 break; 2828 case IEEE80211_IOC_PUREG: 2829 if (ireq->i_val) 2830 vap->iv_flags |= IEEE80211_F_PUREG; 2831 else 2832 vap->iv_flags &= ~IEEE80211_F_PUREG; 2833 /* NB: reset only if we're operating on an 11g channel */ 2834 if (isvap11g(vap)) 2835 error = ENETRESET; 2836 break; 2837 case IEEE80211_IOC_FF: 2838 if (ireq->i_val) { 2839 if ((vap->iv_caps & IEEE80211_C_FF) == 0) 2840 return EOPNOTSUPP; 2841 vap->iv_flags |= IEEE80211_F_FF; 2842 } else 2843 vap->iv_flags &= ~IEEE80211_F_FF; 2844 error = ERESTART; 2845 break; 2846 case IEEE80211_IOC_TURBOP: 2847 if (ireq->i_val) { 2848 if ((vap->iv_caps & IEEE80211_C_TURBOP) == 0) 2849 return EOPNOTSUPP; 2850 vap->iv_flags |= IEEE80211_F_TURBOP; 2851 } else 2852 vap->iv_flags &= ~IEEE80211_F_TURBOP; 2853 error = ENETRESET; 2854 break; 2855 case IEEE80211_IOC_BGSCAN: 2856 if (ireq->i_val) { 2857 if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0) 2858 return EOPNOTSUPP; 2859 vap->iv_flags |= IEEE80211_F_BGSCAN; 2860 } else 2861 vap->iv_flags &= ~IEEE80211_F_BGSCAN; 2862 break; 2863 case IEEE80211_IOC_BGSCAN_IDLE: 2864 if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN) 2865 vap->iv_bgscanidle = ireq->i_val*hz/1000; 2866 else 2867 error = EINVAL; 2868 break; 2869 case IEEE80211_IOC_BGSCAN_INTERVAL: 2870 if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN) 2871 vap->iv_bgscanintvl = ireq->i_val*hz; 2872 else 2873 error = EINVAL; 2874 break; 2875 case IEEE80211_IOC_SCANVALID: 2876 if (ireq->i_val >= IEEE80211_SCAN_VALID_MIN) 2877 vap->iv_scanvalid = ireq->i_val*hz; 2878 else 2879 error = EINVAL; 2880 break; 2881 case IEEE80211_IOC_FRAGTHRESHOLD: 2882 if ((vap->iv_caps & IEEE80211_C_TXFRAG) == 0 && 2883 ireq->i_val != IEEE80211_FRAG_MAX) 2884 return EOPNOTSUPP; 2885 if (!(IEEE80211_FRAG_MIN <= ireq->i_val && 2886 ireq->i_val <= IEEE80211_FRAG_MAX)) 2887 return EINVAL; 2888 vap->iv_fragthreshold = ireq->i_val; 2889 error = ERESTART; 2890 break; 2891 case IEEE80211_IOC_BURST: 2892 if (ireq->i_val) { 2893 if ((vap->iv_caps & IEEE80211_C_BURST) == 0) 2894 return EOPNOTSUPP; 2895 ieee80211_syncflag(vap, IEEE80211_F_BURST); 2896 } else 2897 ieee80211_syncflag(vap, -IEEE80211_F_BURST); 2898 error = ERESTART; 2899 break; 2900 case IEEE80211_IOC_BMISSTHRESHOLD: 2901 if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val && 2902 ireq->i_val <= IEEE80211_HWBMISS_MAX)) 2903 return EINVAL; 2904 vap->iv_bmissthreshold = ireq->i_val; 2905 error = ERESTART; 2906 break; 2907 case IEEE80211_IOC_CURCHAN: 2908 error = ieee80211_ioctl_setcurchan(vap, ireq); 2909 break; 2910 case IEEE80211_IOC_SHORTGI: 2911 if (ireq->i_val) { 2912#define IEEE80211_HTCAP_SHORTGI \ 2913 (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40) 2914 if (((ireq->i_val ^ vap->iv_htcaps) & IEEE80211_HTCAP_SHORTGI) != 0) 2915 return EINVAL; 2916 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI20) 2917 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI20; 2918 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI40) 2919 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI40; 2920#undef IEEE80211_HTCAP_SHORTGI 2921 } else 2922 vap->iv_flags_ext &= 2923 ~(IEEE80211_FEXT_SHORTGI20 | IEEE80211_FEXT_SHORTGI40); 2924 error = ERESTART; 2925 break; 2926 case IEEE80211_IOC_AMPDU: 2927 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0) 2928 return EINVAL; 2929 if (ireq->i_val & 1) 2930 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_TX; 2931 else 2932 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_TX; 2933 if (ireq->i_val & 2) 2934 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_RX; 2935 else 2936 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_RX; 2937 /* NB: reset only if we're operating on an 11n channel */ 2938 if (isvapht(vap)) 2939 error = ERESTART; 2940 break; 2941 case IEEE80211_IOC_AMPDU_LIMIT: 2942 if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val && 2943 ireq->i_val <= IEEE80211_HTCAP_MAXRXAMPDU_64K)) 2944 return EINVAL; 2945 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2946 vap->iv_ampdu_rxmax = ireq->i_val; 2947 else 2948 vap->iv_ampdu_limit = ireq->i_val; 2949 error = ERESTART; 2950 break; 2951 case IEEE80211_IOC_AMPDU_DENSITY: 2952 if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val && 2953 ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16)) 2954 return EINVAL; 2955 vap->iv_ampdu_density = ireq->i_val; 2956 error = ERESTART; 2957 break; 2958 case IEEE80211_IOC_AMSDU: 2959 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0) 2960 return EINVAL; 2961 if (ireq->i_val & 1) 2962 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_TX; 2963 else 2964 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_TX; 2965 if (ireq->i_val & 2) 2966 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_RX; 2967 else 2968 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_RX; 2969 /* NB: reset only if we're operating on an 11n channel */ 2970 if (isvapht(vap)) 2971 error = ERESTART; 2972 break; 2973 case IEEE80211_IOC_AMSDU_LIMIT: 2974 /* XXX validate */ 2975 vap->iv_amsdu_limit = ireq->i_val; /* XXX truncation? */ 2976 break; 2977 case IEEE80211_IOC_PUREN: 2978 if (ireq->i_val) { 2979 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 2980 return EINVAL; 2981 vap->iv_flags_ext |= IEEE80211_FEXT_PUREN; 2982 } else 2983 vap->iv_flags_ext &= ~IEEE80211_FEXT_PUREN; 2984 /* NB: reset only if we're operating on an 11n channel */ 2985 if (isvapht(vap)) 2986 error = ERESTART; 2987 break; 2988 case IEEE80211_IOC_DOTH: 2989 if (ireq->i_val) { 2990#if 0 2991 /* XXX no capability */ 2992 if ((vap->iv_caps & IEEE80211_C_DOTH) == 0) 2993 return EOPNOTSUPP; 2994#endif 2995 vap->iv_flags |= IEEE80211_F_DOTH; 2996 } else 2997 vap->iv_flags &= ~IEEE80211_F_DOTH; 2998 error = ENETRESET; 2999 break; 3000 case IEEE80211_IOC_REGDOMAIN: 3001 error = ieee80211_ioctl_setregdomain(vap, ireq); 3002 break; 3003 case IEEE80211_IOC_ROAM: 3004 error = ieee80211_ioctl_setroam(vap, ireq); 3005 break; 3006 case IEEE80211_IOC_TXPARAMS: 3007 error = ieee80211_ioctl_settxparams(vap, ireq); 3008 break; 3009 case IEEE80211_IOC_HTCOMPAT: 3010 if (ireq->i_val) { 3011 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 3012 return EOPNOTSUPP; 3013 vap->iv_flags_ext |= IEEE80211_FEXT_HTCOMPAT; 3014 } else 3015 vap->iv_flags_ext &= ~IEEE80211_FEXT_HTCOMPAT; 3016 /* NB: reset only if we're operating on an 11n channel */ 3017 if (isvapht(vap)) 3018 error = ERESTART; 3019 break; 3020 case IEEE80211_IOC_DWDS: 3021 if (ireq->i_val) { 3022 /* NB: DWDS only makes sense for WDS-capable devices */ 3023 if ((ic->ic_caps & IEEE80211_C_WDS) == 0) 3024 return EOPNOTSUPP; 3025 /* NB: DWDS is used only with ap+sta vaps */ 3026 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 3027 vap->iv_opmode != IEEE80211_M_STA) 3028 return EINVAL; 3029 vap->iv_flags |= IEEE80211_F_DWDS; 3030 } else 3031 vap->iv_flags &= ~IEEE80211_F_DWDS; 3032 break; 3033 case IEEE80211_IOC_INACTIVITY: 3034 if (ireq->i_val) 3035 vap->iv_flags_ext |= IEEE80211_FEXT_INACT; 3036 else 3037 vap->iv_flags_ext &= ~IEEE80211_FEXT_INACT; 3038 break; 3039 case IEEE80211_IOC_APPIE: 3040 error = ieee80211_ioctl_setappie(vap, ireq); 3041 break; 3042 case IEEE80211_IOC_WPS: 3043 if (ireq->i_val) { 3044 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3045 return EOPNOTSUPP; 3046 vap->iv_flags_ext |= IEEE80211_FEXT_WPS; 3047 } else 3048 vap->iv_flags_ext &= ~IEEE80211_FEXT_WPS; 3049 break; 3050 case IEEE80211_IOC_TSN: 3051 if (ireq->i_val) { 3052 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3053 return EOPNOTSUPP; 3054 vap->iv_flags_ext |= IEEE80211_FEXT_TSN; 3055 } else 3056 vap->iv_flags_ext &= ~IEEE80211_FEXT_TSN; 3057 break; 3058 case IEEE80211_IOC_CHANSWITCH: 3059 error = ieee80211_ioctl_chanswitch(vap, ireq); 3060 break; 3061 case IEEE80211_IOC_DFS: 3062 if (ireq->i_val) { 3063 if ((vap->iv_caps & IEEE80211_C_DFS) == 0) 3064 return EOPNOTSUPP; 3065 /* NB: DFS requires 11h support */ 3066 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 3067 return EINVAL; 3068 vap->iv_flags_ext |= IEEE80211_FEXT_DFS; 3069 } else 3070 vap->iv_flags_ext &= ~IEEE80211_FEXT_DFS; 3071 break; 3072 case IEEE80211_IOC_DOTD: 3073 if (ireq->i_val) 3074 vap->iv_flags_ext |= IEEE80211_FEXT_DOTD; 3075 else 3076 vap->iv_flags_ext &= ~IEEE80211_FEXT_DOTD; 3077 if (vap->iv_opmode == IEEE80211_M_STA) 3078 error = ENETRESET; 3079 break; 3080 case IEEE80211_IOC_HTPROTMODE: 3081 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 3082 return EINVAL; 3083 ic->ic_htprotmode = ireq->i_val ? 3084 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE; 3085 /* NB: if not operating in 11n this can wait */ 3086 if (isvapht(vap)) 3087 error = ERESTART; 3088 break; 3089 case IEEE80211_IOC_STA_VLAN: 3090 error = ieee80211_ioctl_setstavlan(vap, ireq); 3091 break; 3092 case IEEE80211_IOC_SMPS: 3093 if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 || 3094 ireq->i_val == 0x0008) /* value of 2 is reserved */ 3095 return EINVAL; 3096 if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF && 3097 (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0) 3098 return EOPNOTSUPP; 3099 vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) | 3100 ireq->i_val; 3101 /* NB: if not operating in 11n this can wait */ 3102 if (isvapht(vap)) 3103 error = ERESTART; 3104 break; 3105 case IEEE80211_IOC_RIFS: 3106 if (ireq->i_val != 0) { 3107 if ((vap->iv_htcaps & IEEE80211_HTC_RIFS) == 0) 3108 return EOPNOTSUPP; 3109 vap->iv_flags_ext |= IEEE80211_FEXT_RIFS; 3110 } else 3111 vap->iv_flags_ext &= ~IEEE80211_FEXT_RIFS; 3112 /* NB: if not operating in 11n this can wait */ 3113 if (isvapht(vap)) 3114 error = ERESTART; 3115 break; 3116 default: 3117 error = EINVAL; 3118 break; 3119 } 3120 /* 3121 * The convention is that ENETRESET means an operation 3122 * requires a complete re-initialization of the device (e.g. 3123 * changing something that affects the association state). 3124 * ERESTART means the request may be handled with only a 3125 * reload of the hardware state. We hand ERESTART requests 3126 * to the iv_reset callback so the driver can decide. If 3127 * a device does not fillin iv_reset then it defaults to one 3128 * that returns ENETRESET. Otherwise a driver may return 3129 * ENETRESET (in which case a full reset will be done) or 3130 * 0 to mean there's no need to do anything (e.g. when the 3131 * change has no effect on the driver/device). 3132 */ 3133 if (error == ERESTART) 3134 error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ? 3135 vap->iv_reset(vap, ireq->i_type) : 0; 3136 if (error == ENETRESET) { 3137 /* XXX need to re-think AUTO handling */ 3138 if (IS_UP_AUTO(vap)) 3139 ieee80211_init(vap); 3140 error = 0; 3141 } 3142 return error; 3143} 3144 3145/* 3146 * Rebuild the parent's multicast address list after an add/del 3147 * of a multicast address for a vap. We have no way to tell 3148 * what happened above to optimize the work so we purge the entire 3149 * list and rebuild from scratch. This is way expensive. 3150 * Note also the half-baked workaround for if_addmulti calling 3151 * back to the parent device; there's no way to insert mcast 3152 * entries quietly and/or cheaply. 3153 */ 3154static void 3155ieee80211_ioctl_updatemulti(struct ieee80211com *ic) 3156{ 3157 struct ifnet *parent = ic->ic_ifp; 3158 struct ieee80211vap *vap; 3159 void *ioctl; 3160 3161 IEEE80211_LOCK(ic); 3162 if_purgemaddrs(parent); 3163 ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */ 3164 parent->if_ioctl = NULL; 3165 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 3166 struct ifnet *ifp = vap->iv_ifp; 3167 struct ifmultiaddr *ifma; 3168 3169 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) 3170 (void) if_addmulti(parent, ifma->ifma_addr, NULL); 3171 } 3172 parent->if_ioctl = ioctl; 3173 3174 ic->ic_update_mcast(ic->ic_ifp); 3175 IEEE80211_UNLOCK(ic); 3176} 3177 3178int 3179ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 3180{ 3181 struct ieee80211vap *vap; 3182 struct ieee80211com *ic; 3183 int error = 0; 3184 struct ifreq *ifr; 3185 struct ifaddr *ifa; /* XXX */ 3186 3187 vap = ifp->if_softc; 3188 if (vap == NULL) { 3189 /* 3190 * During detach we clear the backpointer in the softc 3191 * so any ioctl request through the ifnet that arrives 3192 * before teardown is ignored/rejected. In particular 3193 * this hack handles destroying a vap used by an app 3194 * like wpa_supplicant that will respond to the vap 3195 * being forced into INIT state by immediately trying 3196 * to force it back up. We can yank this hack if/when 3197 * we can destroy the ifnet before cleaning up vap state. 3198 */ 3199 return ENXIO; 3200 } 3201 switch (cmd) { 3202 case SIOCSIFFLAGS: 3203 ic = vap->iv_ic; 3204 IEEE80211_LOCK(ic); 3205 ieee80211_syncifflag_locked(ic, IFF_PROMISC); 3206 ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); 3207 if (ifp->if_flags & IFF_UP) { 3208 /* 3209 * Bring ourself up unless we're already operational. 3210 * If we're the first vap and the parent is not up 3211 * then it will automatically be brought up as a 3212 * side-effect of bringing ourself up. 3213 */ 3214 if (vap->iv_state == IEEE80211_S_INIT) 3215 ieee80211_start_locked(vap); 3216 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 3217 /* 3218 * Stop ourself. If we are the last vap to be 3219 * marked down the parent will also be taken down. 3220 */ 3221 ieee80211_stop_locked(vap); 3222 } 3223 IEEE80211_UNLOCK(ic); 3224 break; 3225 case SIOCADDMULTI: 3226 case SIOCDELMULTI: 3227 ieee80211_ioctl_updatemulti(vap->iv_ic); 3228 break; 3229 case SIOCSIFMEDIA: 3230 case SIOCGIFMEDIA: 3231 ifr = (struct ifreq *)data; 3232 error = ifmedia_ioctl(ifp, ifr, &vap->iv_media, cmd); 3233 break; 3234 case SIOCG80211: 3235 error = ieee80211_ioctl_get80211(vap, cmd, 3236 (struct ieee80211req *) data); 3237 break; 3238 case SIOCS80211: 3239 error = priv_check(curthread, PRIV_NET80211_MANAGE); 3240 if (error == 0) 3241 error = ieee80211_ioctl_set80211(vap, cmd, 3242 (struct ieee80211req *) data); 3243 break; 3244 case SIOCG80211STATS: 3245 ifr = (struct ifreq *)data; 3246 copyout(&vap->iv_stats, ifr->ifr_data, sizeof (vap->iv_stats)); 3247 break; 3248 case SIOCSIFMTU: 3249 ifr = (struct ifreq *)data; 3250 if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu && 3251 ifr->ifr_mtu <= IEEE80211_MTU_MAX)) 3252 error = EINVAL; 3253 else 3254 ifp->if_mtu = ifr->ifr_mtu; 3255 break; 3256 case SIOCSIFADDR: 3257 /* 3258 * XXX Handle this directly so we can supress if_init calls. 3259 * XXX This should be done in ether_ioctl but for the moment 3260 * XXX there are too many other parts of the system that 3261 * XXX set IFF_UP and so supress if_init being called when 3262 * XXX it should be. 3263 */ 3264 ifa = (struct ifaddr *) data; 3265 switch (ifa->ifa_addr->sa_family) { 3266#ifdef INET 3267 case AF_INET: 3268 if ((ifp->if_flags & IFF_UP) == 0) { 3269 ifp->if_flags |= IFF_UP; 3270 ifp->if_init(ifp->if_softc); 3271 } 3272 arp_ifinit(ifp, ifa); 3273 break; 3274#endif 3275#ifdef IPX 3276 /* 3277 * XXX - This code is probably wrong, 3278 * but has been copied many times. 3279 */ 3280 case AF_IPX: { 3281 struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 3282 3283 if (ipx_nullhost(*ina)) 3284 ina->x_host = *(union ipx_host *) 3285 IF_LLADDR(ifp); 3286 else 3287 bcopy((caddr_t) ina->x_host.c_host, 3288 (caddr_t) IF_LLADDR(ifp), 3289 ETHER_ADDR_LEN); 3290 /* fall thru... */ 3291 } 3292#endif 3293 default: 3294 if ((ifp->if_flags & IFF_UP) == 0) { 3295 ifp->if_flags |= IFF_UP; 3296 ifp->if_init(ifp->if_softc); 3297 } 3298 break; 3299 } 3300 break; 3301 /* Pass NDIS ioctls up to the driver */ 3302 case SIOCGDRVSPEC: 3303 case SIOCSDRVSPEC: 3304 case SIOCGPRIVATE_0: { 3305 struct ifnet *parent = vap->iv_ic->ic_ifp; 3306 error = parent->if_ioctl(parent, cmd, data); 3307 break; 3308 } 3309 default: 3310 error = ether_ioctl(ifp, cmd, data); 3311 break; 3312 } 3313 return error; 3314}
|