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 186107 2008-12-15 01:26:33Z sam $");
| 28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ioctl.c 186302 2008-12-18 23:00:09Z sam $");
|
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 MALLOC(p, void *, space, M_TEMP, M_NOWAIT | M_ZERO);
| 323 p = malloc(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 MALLOC(p, void *, space, M_TEMP, M_NOWAIT | M_ZERO);
| 470 p = malloc(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 MALLOC(dc, struct ieee80211_devcaps_req *,
| 699 dc = (struct ieee80211_devcaps_req *) malloc(
|
700 sizeof(struct ieee80211_devcaps_req), M_TEMP, M_NOWAIT | M_ZERO); 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));
| 700 sizeof(struct ieee80211_devcaps_req), M_TEMP, M_NOWAIT | M_ZERO); 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));
|
710 FREE(dc, M_TEMP);
| 710 free(dc, M_TEMP);
|
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->se_chan, 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, 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 nchan = 0; 1568 for (i = 0; i < ic->ic_nchans; i++) { 1569 const struct ieee80211_channel *c = &ic->ic_channels[i]; 1570 /* 1571 * Calculate the intersection of the user list and the 1572 * available channels so users can do things like specify 1573 * 1-255 to get all available channels. 1574 */ 1575 if (isset(list.ic_channels, c->ic_ieee)) { 1576 setbit(chanlist, c->ic_ieee); 1577 nchan++; 1578 } 1579 } 1580 if (nchan == 0) 1581 return EINVAL; 1582 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */ 1583 isclr(chanlist, ic->ic_bsschan->ic_ieee)) 1584 ic->ic_bsschan = IEEE80211_CHAN_ANYC; 1585 memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); 1586 ieee80211_scan_flush(vap); 1587 return ENETRESET; 1588} 1589 1590static __noinline int 1591ieee80211_ioctl_setstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) 1592{ 1593 struct ieee80211_node *ni; 1594 uint8_t macaddr[IEEE80211_ADDR_LEN]; 1595 int error; 1596 1597 /* 1598 * NB: we could copyin ieee80211req_sta_stats so apps 1599 * could make selective changes but that's overkill; 1600 * just clear all stats for now. 1601 */ 1602 if (ireq->i_len < IEEE80211_ADDR_LEN) 1603 return EINVAL; 1604 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 1605 if (error != 0) 1606 return error; 1607 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 1608 if (ni == NULL) 1609 return ENOENT; 1610 /* XXX require ni_vap == vap? */ 1611 memset(&ni->ni_stats, 0, sizeof(ni->ni_stats)); 1612 ieee80211_free_node(ni); 1613 return 0; 1614} 1615 1616static __noinline int 1617ieee80211_ioctl_setstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) 1618{ 1619 struct ieee80211_node *ni; 1620 struct ieee80211req_sta_txpow txpow; 1621 int error; 1622 1623 if (ireq->i_len != sizeof(txpow)) 1624 return EINVAL; 1625 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 1626 if (error != 0) 1627 return error; 1628 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); 1629 if (ni == NULL) 1630 return ENOENT; 1631 ni->ni_txpower = txpow.it_txpow; 1632 ieee80211_free_node(ni); 1633 return error; 1634} 1635 1636static __noinline int 1637ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) 1638{ 1639 struct ieee80211com *ic = vap->iv_ic; 1640 struct ieee80211_wme_state *wme = &ic->ic_wme; 1641 struct wmeParams *wmep, *chanp; 1642 int isbss, ac; 1643 1644 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 1645 return EOPNOTSUPP; 1646 1647 isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); 1648 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 1649 if (ac >= WME_NUM_AC) 1650 ac = WME_AC_BE; 1651 if (isbss) { 1652 chanp = &wme->wme_bssChanParams.cap_wmeParams[ac]; 1653 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 1654 } else { 1655 chanp = &wme->wme_chanParams.cap_wmeParams[ac]; 1656 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 1657 } 1658 switch (ireq->i_type) { 1659 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1660 if (isbss) { 1661 wmep->wmep_logcwmin = ireq->i_val; 1662 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1663 chanp->wmep_logcwmin = ireq->i_val; 1664 } else { 1665 wmep->wmep_logcwmin = chanp->wmep_logcwmin = 1666 ireq->i_val; 1667 } 1668 break; 1669 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1670 if (isbss) { 1671 wmep->wmep_logcwmax = ireq->i_val; 1672 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1673 chanp->wmep_logcwmax = ireq->i_val; 1674 } else { 1675 wmep->wmep_logcwmax = chanp->wmep_logcwmax = 1676 ireq->i_val; 1677 } 1678 break; 1679 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1680 if (isbss) { 1681 wmep->wmep_aifsn = ireq->i_val; 1682 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1683 chanp->wmep_aifsn = ireq->i_val; 1684 } else { 1685 wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; 1686 } 1687 break; 1688 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1689 if (isbss) { 1690 wmep->wmep_txopLimit = ireq->i_val; 1691 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1692 chanp->wmep_txopLimit = ireq->i_val; 1693 } else { 1694 wmep->wmep_txopLimit = chanp->wmep_txopLimit = 1695 ireq->i_val; 1696 } 1697 break; 1698 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 1699 wmep->wmep_acm = ireq->i_val; 1700 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1701 chanp->wmep_acm = ireq->i_val; 1702 break; 1703 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 1704 wmep->wmep_noackPolicy = chanp->wmep_noackPolicy = 1705 (ireq->i_val) == 0; 1706 break; 1707 } 1708 ieee80211_wme_updateparams(vap); 1709 return 0; 1710} 1711 1712static int 1713find11gchannel(struct ieee80211com *ic, int start, int freq) 1714{ 1715 const struct ieee80211_channel *c; 1716 int i; 1717 1718 for (i = start+1; i < ic->ic_nchans; i++) { 1719 c = &ic->ic_channels[i]; 1720 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1721 return 1; 1722 } 1723 /* NB: should not be needed but in case things are mis-sorted */ 1724 for (i = 0; i < start; i++) { 1725 c = &ic->ic_channels[i]; 1726 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1727 return 1; 1728 } 1729 return 0; 1730} 1731 1732static struct ieee80211_channel * 1733findchannel(struct ieee80211com *ic, int ieee, int mode) 1734{ 1735 static const u_int chanflags[IEEE80211_MODE_MAX] = { 1736 0, /* IEEE80211_MODE_AUTO */ 1737 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ 1738 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ 1739 IEEE80211_CHAN_G, /* IEEE80211_MODE_11G */ 1740 IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ 1741 IEEE80211_CHAN_108A, /* IEEE80211_MODE_TURBO_A */ 1742 IEEE80211_CHAN_108G, /* IEEE80211_MODE_TURBO_G */ 1743 IEEE80211_CHAN_STURBO, /* IEEE80211_MODE_STURBO_A */ 1744 /* NB: handled specially below */ 1745 IEEE80211_CHAN_A, /* IEEE80211_MODE_11NA */ 1746 IEEE80211_CHAN_G, /* IEEE80211_MODE_11NG */ 1747 }; 1748 u_int modeflags; 1749 int i; 1750 1751 modeflags = chanflags[mode]; 1752 for (i = 0; i < ic->ic_nchans; i++) { 1753 struct ieee80211_channel *c = &ic->ic_channels[i]; 1754 1755 if (c->ic_ieee != ieee) 1756 continue; 1757 if (mode == IEEE80211_MODE_AUTO) { 1758 /* ignore turbo channels for autoselect */ 1759 if (IEEE80211_IS_CHAN_TURBO(c)) 1760 continue; 1761 /* 1762 * XXX special-case 11b/g channels so we 1763 * always select the g channel if both 1764 * are present. 1765 * XXX prefer HT to non-HT? 1766 */ 1767 if (!IEEE80211_IS_CHAN_B(c) || 1768 !find11gchannel(ic, i, c->ic_freq)) 1769 return c; 1770 } else { 1771 /* must check HT specially */ 1772 if ((mode == IEEE80211_MODE_11NA || 1773 mode == IEEE80211_MODE_11NG) && 1774 !IEEE80211_IS_CHAN_HT(c)) 1775 continue; 1776 if ((c->ic_flags & modeflags) == modeflags) 1777 return c; 1778 } 1779 } 1780 return NULL; 1781} 1782 1783/* 1784 * Check the specified against any desired mode (aka netband). 1785 * This is only used (presently) when operating in hostap mode 1786 * to enforce consistency. 1787 */ 1788static int 1789check_mode_consistency(const struct ieee80211_channel *c, int mode) 1790{ 1791 KASSERT(c != IEEE80211_CHAN_ANYC, ("oops, no channel")); 1792 1793 switch (mode) { 1794 case IEEE80211_MODE_11B: 1795 return (IEEE80211_IS_CHAN_B(c)); 1796 case IEEE80211_MODE_11G: 1797 return (IEEE80211_IS_CHAN_ANYG(c) && !IEEE80211_IS_CHAN_HT(c)); 1798 case IEEE80211_MODE_11A: 1799 return (IEEE80211_IS_CHAN_A(c) && !IEEE80211_IS_CHAN_HT(c)); 1800 case IEEE80211_MODE_STURBO_A: 1801 return (IEEE80211_IS_CHAN_STURBO(c)); 1802 case IEEE80211_MODE_11NA: 1803 return (IEEE80211_IS_CHAN_HTA(c)); 1804 case IEEE80211_MODE_11NG: 1805 return (IEEE80211_IS_CHAN_HTG(c)); 1806 } 1807 return 1; 1808 1809} 1810 1811/* 1812 * Common code to set the current channel. If the device 1813 * is up and running this may result in an immediate channel 1814 * change or a kick of the state machine. 1815 */ 1816static int 1817setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c) 1818{ 1819 struct ieee80211com *ic = vap->iv_ic; 1820 int error; 1821 1822 if (c != IEEE80211_CHAN_ANYC) { 1823 if (IEEE80211_IS_CHAN_RADAR(c)) 1824 return EBUSY; /* XXX better code? */ 1825 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 1826 if (IEEE80211_IS_CHAN_NOHOSTAP(c)) 1827 return EINVAL; 1828 if (!check_mode_consistency(c, vap->iv_des_mode)) 1829 return EINVAL; 1830 } else if (vap->iv_opmode == IEEE80211_M_IBSS) { 1831 if (IEEE80211_IS_CHAN_NOADHOC(c)) 1832 return EINVAL; 1833 } 1834 if (vap->iv_state == IEEE80211_S_RUN && 1835 vap->iv_bss->ni_chan == c) 1836 return 0; /* NB: nothing to do */ 1837 } 1838 vap->iv_des_chan = c; 1839 1840 error = 0; 1841 if (vap->iv_opmode == IEEE80211_M_MONITOR && 1842 vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1843 /* 1844 * Monitor mode can switch directly. 1845 */ 1846 if (IFNET_IS_UP_RUNNING(vap->iv_ifp)) { 1847 /* XXX need state machine for other vap's to follow */ 1848 ieee80211_setcurchan(ic, vap->iv_des_chan); 1849 vap->iv_bss->ni_chan = ic->ic_curchan; 1850 } else 1851 ic->ic_curchan = vap->iv_des_chan; 1852 } else { 1853 /* 1854 * Need to go through the state machine in case we 1855 * need to reassociate or the like. The state machine 1856 * will pickup the desired channel and avoid scanning. 1857 */ 1858 if (IS_UP_AUTO(vap)) 1859 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 1860 else if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1861 /* 1862 * When not up+running and a real channel has 1863 * been specified fix the current channel so 1864 * there is immediate feedback; e.g. via ifconfig. 1865 */ 1866 ic->ic_curchan = vap->iv_des_chan; 1867 } 1868 } 1869 return error; 1870} 1871 1872/* 1873 * Old api for setting the current channel; this is 1874 * deprecated because channel numbers are ambiguous. 1875 */ 1876static __noinline int 1877ieee80211_ioctl_setchannel(struct ieee80211vap *vap, 1878 const struct ieee80211req *ireq) 1879{ 1880 struct ieee80211com *ic = vap->iv_ic; 1881 struct ieee80211_channel *c; 1882 1883 /* XXX 0xffff overflows 16-bit signed */ 1884 if (ireq->i_val == 0 || 1885 ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) { 1886 c = IEEE80211_CHAN_ANYC; 1887 } else { 1888 struct ieee80211_channel *c2; 1889 1890 c = findchannel(ic, ireq->i_val, vap->iv_des_mode); 1891 if (c == NULL) { 1892 c = findchannel(ic, ireq->i_val, 1893 IEEE80211_MODE_AUTO); 1894 if (c == NULL) 1895 return EINVAL; 1896 } 1897 /* 1898 * Fine tune channel selection based on desired mode: 1899 * if 11b is requested, find the 11b version of any 1900 * 11g channel returned, 1901 * if static turbo, find the turbo version of any 1902 * 11a channel return, 1903 * if 11na is requested, find the ht version of any 1904 * 11a channel returned, 1905 * if 11ng is requested, find the ht version of any 1906 * 11g channel returned, 1907 * otherwise we should be ok with what we've got. 1908 */ 1909 switch (vap->iv_des_mode) { 1910 case IEEE80211_MODE_11B: 1911 if (IEEE80211_IS_CHAN_ANYG(c)) { 1912 c2 = findchannel(ic, ireq->i_val, 1913 IEEE80211_MODE_11B); 1914 /* NB: should not happen, =>'s 11g w/o 11b */ 1915 if (c2 != NULL) 1916 c = c2; 1917 } 1918 break; 1919 case IEEE80211_MODE_TURBO_A: 1920 if (IEEE80211_IS_CHAN_A(c)) { 1921 c2 = findchannel(ic, ireq->i_val, 1922 IEEE80211_MODE_TURBO_A); 1923 if (c2 != NULL) 1924 c = c2; 1925 } 1926 break; 1927 case IEEE80211_MODE_11NA: 1928 if (IEEE80211_IS_CHAN_A(c)) { 1929 c2 = findchannel(ic, ireq->i_val, 1930 IEEE80211_MODE_11NA); 1931 if (c2 != NULL) 1932 c = c2; 1933 } 1934 break; 1935 case IEEE80211_MODE_11NG: 1936 if (IEEE80211_IS_CHAN_ANYG(c)) { 1937 c2 = findchannel(ic, ireq->i_val, 1938 IEEE80211_MODE_11NG); 1939 if (c2 != NULL) 1940 c = c2; 1941 } 1942 break; 1943 default: /* NB: no static turboG */ 1944 break; 1945 } 1946 } 1947 return setcurchan(vap, c); 1948} 1949 1950/* 1951 * New/current api for setting the current channel; a complete 1952 * channel description is provide so there is no ambiguity in 1953 * identifying the channel. 1954 */ 1955static __noinline int 1956ieee80211_ioctl_setcurchan(struct ieee80211vap *vap, 1957 const struct ieee80211req *ireq) 1958{ 1959 struct ieee80211com *ic = vap->iv_ic; 1960 struct ieee80211_channel chan, *c; 1961 int error; 1962 1963 if (ireq->i_len != sizeof(chan)) 1964 return EINVAL; 1965 error = copyin(ireq->i_data, &chan, sizeof(chan)); 1966 if (error != 0) 1967 return error; 1968 /* XXX 0xffff overflows 16-bit signed */ 1969 if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) { 1970 c = IEEE80211_CHAN_ANYC; 1971 } else { 1972 c = ieee80211_find_channel(ic, chan.ic_freq, chan.ic_flags); 1973 if (c == NULL) 1974 return EINVAL; 1975 } 1976 return setcurchan(vap, c); 1977} 1978 1979static __noinline int 1980ieee80211_ioctl_setregdomain(struct ieee80211vap *vap, 1981 const struct ieee80211req *ireq) 1982{ 1983 struct ieee80211_regdomain_req *reg; 1984 int error; 1985 1986 if (ireq->i_len != sizeof(struct ieee80211_regdomain_req)) 1987 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->se_chan, 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, 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 nchan = 0; 1568 for (i = 0; i < ic->ic_nchans; i++) { 1569 const struct ieee80211_channel *c = &ic->ic_channels[i]; 1570 /* 1571 * Calculate the intersection of the user list and the 1572 * available channels so users can do things like specify 1573 * 1-255 to get all available channels. 1574 */ 1575 if (isset(list.ic_channels, c->ic_ieee)) { 1576 setbit(chanlist, c->ic_ieee); 1577 nchan++; 1578 } 1579 } 1580 if (nchan == 0) 1581 return EINVAL; 1582 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */ 1583 isclr(chanlist, ic->ic_bsschan->ic_ieee)) 1584 ic->ic_bsschan = IEEE80211_CHAN_ANYC; 1585 memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); 1586 ieee80211_scan_flush(vap); 1587 return ENETRESET; 1588} 1589 1590static __noinline int 1591ieee80211_ioctl_setstastats(struct ieee80211vap *vap, struct ieee80211req *ireq) 1592{ 1593 struct ieee80211_node *ni; 1594 uint8_t macaddr[IEEE80211_ADDR_LEN]; 1595 int error; 1596 1597 /* 1598 * NB: we could copyin ieee80211req_sta_stats so apps 1599 * could make selective changes but that's overkill; 1600 * just clear all stats for now. 1601 */ 1602 if (ireq->i_len < IEEE80211_ADDR_LEN) 1603 return EINVAL; 1604 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 1605 if (error != 0) 1606 return error; 1607 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, macaddr); 1608 if (ni == NULL) 1609 return ENOENT; 1610 /* XXX require ni_vap == vap? */ 1611 memset(&ni->ni_stats, 0, sizeof(ni->ni_stats)); 1612 ieee80211_free_node(ni); 1613 return 0; 1614} 1615 1616static __noinline int 1617ieee80211_ioctl_setstatxpow(struct ieee80211vap *vap, struct ieee80211req *ireq) 1618{ 1619 struct ieee80211_node *ni; 1620 struct ieee80211req_sta_txpow txpow; 1621 int error; 1622 1623 if (ireq->i_len != sizeof(txpow)) 1624 return EINVAL; 1625 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 1626 if (error != 0) 1627 return error; 1628 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, txpow.it_macaddr); 1629 if (ni == NULL) 1630 return ENOENT; 1631 ni->ni_txpower = txpow.it_txpow; 1632 ieee80211_free_node(ni); 1633 return error; 1634} 1635 1636static __noinline int 1637ieee80211_ioctl_setwmeparam(struct ieee80211vap *vap, struct ieee80211req *ireq) 1638{ 1639 struct ieee80211com *ic = vap->iv_ic; 1640 struct ieee80211_wme_state *wme = &ic->ic_wme; 1641 struct wmeParams *wmep, *chanp; 1642 int isbss, ac; 1643 1644 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 1645 return EOPNOTSUPP; 1646 1647 isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); 1648 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 1649 if (ac >= WME_NUM_AC) 1650 ac = WME_AC_BE; 1651 if (isbss) { 1652 chanp = &wme->wme_bssChanParams.cap_wmeParams[ac]; 1653 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 1654 } else { 1655 chanp = &wme->wme_chanParams.cap_wmeParams[ac]; 1656 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 1657 } 1658 switch (ireq->i_type) { 1659 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1660 if (isbss) { 1661 wmep->wmep_logcwmin = ireq->i_val; 1662 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1663 chanp->wmep_logcwmin = ireq->i_val; 1664 } else { 1665 wmep->wmep_logcwmin = chanp->wmep_logcwmin = 1666 ireq->i_val; 1667 } 1668 break; 1669 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1670 if (isbss) { 1671 wmep->wmep_logcwmax = ireq->i_val; 1672 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1673 chanp->wmep_logcwmax = ireq->i_val; 1674 } else { 1675 wmep->wmep_logcwmax = chanp->wmep_logcwmax = 1676 ireq->i_val; 1677 } 1678 break; 1679 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1680 if (isbss) { 1681 wmep->wmep_aifsn = ireq->i_val; 1682 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1683 chanp->wmep_aifsn = ireq->i_val; 1684 } else { 1685 wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; 1686 } 1687 break; 1688 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1689 if (isbss) { 1690 wmep->wmep_txopLimit = ireq->i_val; 1691 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1692 chanp->wmep_txopLimit = ireq->i_val; 1693 } else { 1694 wmep->wmep_txopLimit = chanp->wmep_txopLimit = 1695 ireq->i_val; 1696 } 1697 break; 1698 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 1699 wmep->wmep_acm = ireq->i_val; 1700 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 1701 chanp->wmep_acm = ireq->i_val; 1702 break; 1703 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 1704 wmep->wmep_noackPolicy = chanp->wmep_noackPolicy = 1705 (ireq->i_val) == 0; 1706 break; 1707 } 1708 ieee80211_wme_updateparams(vap); 1709 return 0; 1710} 1711 1712static int 1713find11gchannel(struct ieee80211com *ic, int start, int freq) 1714{ 1715 const struct ieee80211_channel *c; 1716 int i; 1717 1718 for (i = start+1; i < ic->ic_nchans; i++) { 1719 c = &ic->ic_channels[i]; 1720 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1721 return 1; 1722 } 1723 /* NB: should not be needed but in case things are mis-sorted */ 1724 for (i = 0; i < start; i++) { 1725 c = &ic->ic_channels[i]; 1726 if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c)) 1727 return 1; 1728 } 1729 return 0; 1730} 1731 1732static struct ieee80211_channel * 1733findchannel(struct ieee80211com *ic, int ieee, int mode) 1734{ 1735 static const u_int chanflags[IEEE80211_MODE_MAX] = { 1736 0, /* IEEE80211_MODE_AUTO */ 1737 IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ 1738 IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ 1739 IEEE80211_CHAN_G, /* IEEE80211_MODE_11G */ 1740 IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ 1741 IEEE80211_CHAN_108A, /* IEEE80211_MODE_TURBO_A */ 1742 IEEE80211_CHAN_108G, /* IEEE80211_MODE_TURBO_G */ 1743 IEEE80211_CHAN_STURBO, /* IEEE80211_MODE_STURBO_A */ 1744 /* NB: handled specially below */ 1745 IEEE80211_CHAN_A, /* IEEE80211_MODE_11NA */ 1746 IEEE80211_CHAN_G, /* IEEE80211_MODE_11NG */ 1747 }; 1748 u_int modeflags; 1749 int i; 1750 1751 modeflags = chanflags[mode]; 1752 for (i = 0; i < ic->ic_nchans; i++) { 1753 struct ieee80211_channel *c = &ic->ic_channels[i]; 1754 1755 if (c->ic_ieee != ieee) 1756 continue; 1757 if (mode == IEEE80211_MODE_AUTO) { 1758 /* ignore turbo channels for autoselect */ 1759 if (IEEE80211_IS_CHAN_TURBO(c)) 1760 continue; 1761 /* 1762 * XXX special-case 11b/g channels so we 1763 * always select the g channel if both 1764 * are present. 1765 * XXX prefer HT to non-HT? 1766 */ 1767 if (!IEEE80211_IS_CHAN_B(c) || 1768 !find11gchannel(ic, i, c->ic_freq)) 1769 return c; 1770 } else { 1771 /* must check HT specially */ 1772 if ((mode == IEEE80211_MODE_11NA || 1773 mode == IEEE80211_MODE_11NG) && 1774 !IEEE80211_IS_CHAN_HT(c)) 1775 continue; 1776 if ((c->ic_flags & modeflags) == modeflags) 1777 return c; 1778 } 1779 } 1780 return NULL; 1781} 1782 1783/* 1784 * Check the specified against any desired mode (aka netband). 1785 * This is only used (presently) when operating in hostap mode 1786 * to enforce consistency. 1787 */ 1788static int 1789check_mode_consistency(const struct ieee80211_channel *c, int mode) 1790{ 1791 KASSERT(c != IEEE80211_CHAN_ANYC, ("oops, no channel")); 1792 1793 switch (mode) { 1794 case IEEE80211_MODE_11B: 1795 return (IEEE80211_IS_CHAN_B(c)); 1796 case IEEE80211_MODE_11G: 1797 return (IEEE80211_IS_CHAN_ANYG(c) && !IEEE80211_IS_CHAN_HT(c)); 1798 case IEEE80211_MODE_11A: 1799 return (IEEE80211_IS_CHAN_A(c) && !IEEE80211_IS_CHAN_HT(c)); 1800 case IEEE80211_MODE_STURBO_A: 1801 return (IEEE80211_IS_CHAN_STURBO(c)); 1802 case IEEE80211_MODE_11NA: 1803 return (IEEE80211_IS_CHAN_HTA(c)); 1804 case IEEE80211_MODE_11NG: 1805 return (IEEE80211_IS_CHAN_HTG(c)); 1806 } 1807 return 1; 1808 1809} 1810 1811/* 1812 * Common code to set the current channel. If the device 1813 * is up and running this may result in an immediate channel 1814 * change or a kick of the state machine. 1815 */ 1816static int 1817setcurchan(struct ieee80211vap *vap, struct ieee80211_channel *c) 1818{ 1819 struct ieee80211com *ic = vap->iv_ic; 1820 int error; 1821 1822 if (c != IEEE80211_CHAN_ANYC) { 1823 if (IEEE80211_IS_CHAN_RADAR(c)) 1824 return EBUSY; /* XXX better code? */ 1825 if (vap->iv_opmode == IEEE80211_M_HOSTAP) { 1826 if (IEEE80211_IS_CHAN_NOHOSTAP(c)) 1827 return EINVAL; 1828 if (!check_mode_consistency(c, vap->iv_des_mode)) 1829 return EINVAL; 1830 } else if (vap->iv_opmode == IEEE80211_M_IBSS) { 1831 if (IEEE80211_IS_CHAN_NOADHOC(c)) 1832 return EINVAL; 1833 } 1834 if (vap->iv_state == IEEE80211_S_RUN && 1835 vap->iv_bss->ni_chan == c) 1836 return 0; /* NB: nothing to do */ 1837 } 1838 vap->iv_des_chan = c; 1839 1840 error = 0; 1841 if (vap->iv_opmode == IEEE80211_M_MONITOR && 1842 vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1843 /* 1844 * Monitor mode can switch directly. 1845 */ 1846 if (IFNET_IS_UP_RUNNING(vap->iv_ifp)) { 1847 /* XXX need state machine for other vap's to follow */ 1848 ieee80211_setcurchan(ic, vap->iv_des_chan); 1849 vap->iv_bss->ni_chan = ic->ic_curchan; 1850 } else 1851 ic->ic_curchan = vap->iv_des_chan; 1852 } else { 1853 /* 1854 * Need to go through the state machine in case we 1855 * need to reassociate or the like. The state machine 1856 * will pickup the desired channel and avoid scanning. 1857 */ 1858 if (IS_UP_AUTO(vap)) 1859 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 1860 else if (vap->iv_des_chan != IEEE80211_CHAN_ANYC) { 1861 /* 1862 * When not up+running and a real channel has 1863 * been specified fix the current channel so 1864 * there is immediate feedback; e.g. via ifconfig. 1865 */ 1866 ic->ic_curchan = vap->iv_des_chan; 1867 } 1868 } 1869 return error; 1870} 1871 1872/* 1873 * Old api for setting the current channel; this is 1874 * deprecated because channel numbers are ambiguous. 1875 */ 1876static __noinline int 1877ieee80211_ioctl_setchannel(struct ieee80211vap *vap, 1878 const struct ieee80211req *ireq) 1879{ 1880 struct ieee80211com *ic = vap->iv_ic; 1881 struct ieee80211_channel *c; 1882 1883 /* XXX 0xffff overflows 16-bit signed */ 1884 if (ireq->i_val == 0 || 1885 ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) { 1886 c = IEEE80211_CHAN_ANYC; 1887 } else { 1888 struct ieee80211_channel *c2; 1889 1890 c = findchannel(ic, ireq->i_val, vap->iv_des_mode); 1891 if (c == NULL) { 1892 c = findchannel(ic, ireq->i_val, 1893 IEEE80211_MODE_AUTO); 1894 if (c == NULL) 1895 return EINVAL; 1896 } 1897 /* 1898 * Fine tune channel selection based on desired mode: 1899 * if 11b is requested, find the 11b version of any 1900 * 11g channel returned, 1901 * if static turbo, find the turbo version of any 1902 * 11a channel return, 1903 * if 11na is requested, find the ht version of any 1904 * 11a channel returned, 1905 * if 11ng is requested, find the ht version of any 1906 * 11g channel returned, 1907 * otherwise we should be ok with what we've got. 1908 */ 1909 switch (vap->iv_des_mode) { 1910 case IEEE80211_MODE_11B: 1911 if (IEEE80211_IS_CHAN_ANYG(c)) { 1912 c2 = findchannel(ic, ireq->i_val, 1913 IEEE80211_MODE_11B); 1914 /* NB: should not happen, =>'s 11g w/o 11b */ 1915 if (c2 != NULL) 1916 c = c2; 1917 } 1918 break; 1919 case IEEE80211_MODE_TURBO_A: 1920 if (IEEE80211_IS_CHAN_A(c)) { 1921 c2 = findchannel(ic, ireq->i_val, 1922 IEEE80211_MODE_TURBO_A); 1923 if (c2 != NULL) 1924 c = c2; 1925 } 1926 break; 1927 case IEEE80211_MODE_11NA: 1928 if (IEEE80211_IS_CHAN_A(c)) { 1929 c2 = findchannel(ic, ireq->i_val, 1930 IEEE80211_MODE_11NA); 1931 if (c2 != NULL) 1932 c = c2; 1933 } 1934 break; 1935 case IEEE80211_MODE_11NG: 1936 if (IEEE80211_IS_CHAN_ANYG(c)) { 1937 c2 = findchannel(ic, ireq->i_val, 1938 IEEE80211_MODE_11NG); 1939 if (c2 != NULL) 1940 c = c2; 1941 } 1942 break; 1943 default: /* NB: no static turboG */ 1944 break; 1945 } 1946 } 1947 return setcurchan(vap, c); 1948} 1949 1950/* 1951 * New/current api for setting the current channel; a complete 1952 * channel description is provide so there is no ambiguity in 1953 * identifying the channel. 1954 */ 1955static __noinline int 1956ieee80211_ioctl_setcurchan(struct ieee80211vap *vap, 1957 const struct ieee80211req *ireq) 1958{ 1959 struct ieee80211com *ic = vap->iv_ic; 1960 struct ieee80211_channel chan, *c; 1961 int error; 1962 1963 if (ireq->i_len != sizeof(chan)) 1964 return EINVAL; 1965 error = copyin(ireq->i_data, &chan, sizeof(chan)); 1966 if (error != 0) 1967 return error; 1968 /* XXX 0xffff overflows 16-bit signed */ 1969 if (chan.ic_freq == 0 || chan.ic_freq == IEEE80211_CHAN_ANY) { 1970 c = IEEE80211_CHAN_ANYC; 1971 } else { 1972 c = ieee80211_find_channel(ic, chan.ic_freq, chan.ic_flags); 1973 if (c == NULL) 1974 return EINVAL; 1975 } 1976 return setcurchan(vap, c); 1977} 1978 1979static __noinline int 1980ieee80211_ioctl_setregdomain(struct ieee80211vap *vap, 1981 const struct ieee80211req *ireq) 1982{ 1983 struct ieee80211_regdomain_req *reg; 1984 int error; 1985 1986 if (ireq->i_len != sizeof(struct ieee80211_regdomain_req)) 1987 return EINVAL;
|
1988 MALLOC(reg, struct ieee80211_regdomain_req *,
| 1988 reg = (struct ieee80211_regdomain_req *) malloc(
|
1989 sizeof(struct ieee80211_regdomain_req), M_TEMP, M_NOWAIT); 1990 if (reg == NULL) 1991 return ENOMEM; 1992 error = copyin(ireq->i_data, reg, sizeof(*reg)); 1993 if (error == 0) 1994 error = ieee80211_setregdomain(vap, reg);
| 1989 sizeof(struct ieee80211_regdomain_req), M_TEMP, M_NOWAIT); 1990 if (reg == NULL) 1991 return ENOMEM; 1992 error = copyin(ireq->i_data, reg, sizeof(*reg)); 1993 if (error == 0) 1994 error = ieee80211_setregdomain(vap, reg);
|
1995 FREE(reg, M_TEMP);
| 1995 free(reg, M_TEMP);
|
1996 1997 return (error == 0 ? ENETRESET : error); 1998} 1999 2000static int 2001ieee80211_ioctl_setroam(struct ieee80211vap *vap, 2002 const struct ieee80211req *ireq) 2003{ 2004 if (ireq->i_len != sizeof(vap->iv_roamparms)) 2005 return EINVAL; 2006 /* XXX validate params */ 2007 /* XXX? ENETRESET to push to device? */ 2008 return copyin(ireq->i_data, vap->iv_roamparms, 2009 sizeof(vap->iv_roamparms)); 2010} 2011 2012static int 2013checkrate(const struct ieee80211_rateset *rs, int rate) 2014{ 2015 int i; 2016 2017 if (rate == IEEE80211_FIXED_RATE_NONE) 2018 return 1; 2019 for (i = 0; i < rs->rs_nrates; i++) 2020 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) 2021 return 1; 2022 return 0; 2023} 2024 2025static int 2026checkmcs(int mcs) 2027{ 2028 if (mcs == IEEE80211_FIXED_RATE_NONE) 2029 return 1; 2030 if ((mcs & IEEE80211_RATE_MCS) == 0) /* MCS always have 0x80 set */ 2031 return 0; 2032 return (mcs & 0x7f) <= 15; /* XXX could search ht rate set */ 2033} 2034 2035static __noinline int 2036ieee80211_ioctl_settxparams(struct ieee80211vap *vap, 2037 const struct ieee80211req *ireq) 2038{ 2039 struct ieee80211com *ic = vap->iv_ic; 2040 struct ieee80211_txparams_req parms; /* XXX stack use? */ 2041 struct ieee80211_txparam *src, *dst; 2042 const struct ieee80211_rateset *rs; 2043 int error, i, changed; 2044 2045 if (ireq->i_len != sizeof(parms)) 2046 return EINVAL; 2047 error = copyin(ireq->i_data, &parms, sizeof(parms)); 2048 if (error != 0) 2049 return error; 2050 changed = 0; 2051 /* validate parameters and check if anything changed */ 2052 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_11NA; i++) { 2053 if (isclr(ic->ic_modecaps, i)) 2054 continue; 2055 src = &parms.params[i]; 2056 dst = &vap->iv_txparms[i]; 2057 rs = &ic->ic_sup_rates[i]; 2058 if (src->ucastrate != dst->ucastrate) { 2059 if (!checkrate(rs, src->ucastrate)) 2060 return EINVAL; 2061 changed++; 2062 } 2063 if (src->mcastrate != dst->mcastrate) { 2064 if (!checkrate(rs, src->mcastrate)) 2065 return EINVAL; 2066 changed++; 2067 } 2068 if (src->mgmtrate != dst->mgmtrate) { 2069 if (!checkrate(rs, src->mgmtrate)) 2070 return EINVAL; 2071 changed++; 2072 } 2073 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2074 changed++; 2075 } 2076 /* 11n parameters are handled differently */ 2077 for (; i < IEEE80211_MODE_MAX; i++) { 2078 if (isclr(ic->ic_modecaps, i)) 2079 continue; 2080 src = &parms.params[i]; 2081 dst = &vap->iv_txparms[i]; 2082 rs = &ic->ic_sup_rates[i == IEEE80211_MODE_11NA ? 2083 IEEE80211_MODE_11A : IEEE80211_MODE_11G]; 2084 if (src->ucastrate != dst->ucastrate) { 2085 if (!checkmcs(src->ucastrate) && 2086 !checkrate(rs, src->ucastrate)) 2087 return EINVAL; 2088 changed++; 2089 } 2090 if (src->mcastrate != dst->mcastrate) { 2091 if (!checkmcs(src->mcastrate) && 2092 !checkrate(rs, src->mcastrate)) 2093 return EINVAL; 2094 changed++; 2095 } 2096 if (src->mgmtrate != dst->mgmtrate) { 2097 if (!checkmcs(src->mgmtrate) && 2098 !checkrate(rs, src->mgmtrate)) 2099 return EINVAL; 2100 changed++; 2101 } 2102 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2103 changed++; 2104 } 2105 if (changed) { 2106 /* 2107 * Copy new parameters in place and notify the 2108 * driver so it can push state to the device. 2109 */ 2110 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) { 2111 if (isset(ic->ic_modecaps, i)) 2112 vap->iv_txparms[i] = parms.params[i]; 2113 } 2114 /* XXX could be more intelligent, 2115 e.g. don't reset if setting not being used */ 2116 return ENETRESET; 2117 } 2118 return 0; 2119} 2120 2121/* 2122 * Application Information Element support. 2123 */ 2124static int 2125setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq) 2126{ 2127 struct ieee80211_appie *app = *aie; 2128 struct ieee80211_appie *napp; 2129 int error; 2130 2131 if (ireq->i_len == 0) { /* delete any existing ie */ 2132 if (app != NULL) { 2133 *aie = NULL; /* XXX racey */
| 1996 1997 return (error == 0 ? ENETRESET : error); 1998} 1999 2000static int 2001ieee80211_ioctl_setroam(struct ieee80211vap *vap, 2002 const struct ieee80211req *ireq) 2003{ 2004 if (ireq->i_len != sizeof(vap->iv_roamparms)) 2005 return EINVAL; 2006 /* XXX validate params */ 2007 /* XXX? ENETRESET to push to device? */ 2008 return copyin(ireq->i_data, vap->iv_roamparms, 2009 sizeof(vap->iv_roamparms)); 2010} 2011 2012static int 2013checkrate(const struct ieee80211_rateset *rs, int rate) 2014{ 2015 int i; 2016 2017 if (rate == IEEE80211_FIXED_RATE_NONE) 2018 return 1; 2019 for (i = 0; i < rs->rs_nrates; i++) 2020 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) 2021 return 1; 2022 return 0; 2023} 2024 2025static int 2026checkmcs(int mcs) 2027{ 2028 if (mcs == IEEE80211_FIXED_RATE_NONE) 2029 return 1; 2030 if ((mcs & IEEE80211_RATE_MCS) == 0) /* MCS always have 0x80 set */ 2031 return 0; 2032 return (mcs & 0x7f) <= 15; /* XXX could search ht rate set */ 2033} 2034 2035static __noinline int 2036ieee80211_ioctl_settxparams(struct ieee80211vap *vap, 2037 const struct ieee80211req *ireq) 2038{ 2039 struct ieee80211com *ic = vap->iv_ic; 2040 struct ieee80211_txparams_req parms; /* XXX stack use? */ 2041 struct ieee80211_txparam *src, *dst; 2042 const struct ieee80211_rateset *rs; 2043 int error, i, changed; 2044 2045 if (ireq->i_len != sizeof(parms)) 2046 return EINVAL; 2047 error = copyin(ireq->i_data, &parms, sizeof(parms)); 2048 if (error != 0) 2049 return error; 2050 changed = 0; 2051 /* validate parameters and check if anything changed */ 2052 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_11NA; i++) { 2053 if (isclr(ic->ic_modecaps, i)) 2054 continue; 2055 src = &parms.params[i]; 2056 dst = &vap->iv_txparms[i]; 2057 rs = &ic->ic_sup_rates[i]; 2058 if (src->ucastrate != dst->ucastrate) { 2059 if (!checkrate(rs, src->ucastrate)) 2060 return EINVAL; 2061 changed++; 2062 } 2063 if (src->mcastrate != dst->mcastrate) { 2064 if (!checkrate(rs, src->mcastrate)) 2065 return EINVAL; 2066 changed++; 2067 } 2068 if (src->mgmtrate != dst->mgmtrate) { 2069 if (!checkrate(rs, src->mgmtrate)) 2070 return EINVAL; 2071 changed++; 2072 } 2073 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2074 changed++; 2075 } 2076 /* 11n parameters are handled differently */ 2077 for (; i < IEEE80211_MODE_MAX; i++) { 2078 if (isclr(ic->ic_modecaps, i)) 2079 continue; 2080 src = &parms.params[i]; 2081 dst = &vap->iv_txparms[i]; 2082 rs = &ic->ic_sup_rates[i == IEEE80211_MODE_11NA ? 2083 IEEE80211_MODE_11A : IEEE80211_MODE_11G]; 2084 if (src->ucastrate != dst->ucastrate) { 2085 if (!checkmcs(src->ucastrate) && 2086 !checkrate(rs, src->ucastrate)) 2087 return EINVAL; 2088 changed++; 2089 } 2090 if (src->mcastrate != dst->mcastrate) { 2091 if (!checkmcs(src->mcastrate) && 2092 !checkrate(rs, src->mcastrate)) 2093 return EINVAL; 2094 changed++; 2095 } 2096 if (src->mgmtrate != dst->mgmtrate) { 2097 if (!checkmcs(src->mgmtrate) && 2098 !checkrate(rs, src->mgmtrate)) 2099 return EINVAL; 2100 changed++; 2101 } 2102 if (src->maxretry != dst->maxretry) /* NB: no bounds */ 2103 changed++; 2104 } 2105 if (changed) { 2106 /* 2107 * Copy new parameters in place and notify the 2108 * driver so it can push state to the device. 2109 */ 2110 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_MAX; i++) { 2111 if (isset(ic->ic_modecaps, i)) 2112 vap->iv_txparms[i] = parms.params[i]; 2113 } 2114 /* XXX could be more intelligent, 2115 e.g. don't reset if setting not being used */ 2116 return ENETRESET; 2117 } 2118 return 0; 2119} 2120 2121/* 2122 * Application Information Element support. 2123 */ 2124static int 2125setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq) 2126{ 2127 struct ieee80211_appie *app = *aie; 2128 struct ieee80211_appie *napp; 2129 int error; 2130 2131 if (ireq->i_len == 0) { /* delete any existing ie */ 2132 if (app != NULL) { 2133 *aie = NULL; /* XXX racey */
|
2134 FREE(app, M_80211_NODE_IE);
| 2134 free(app, M_80211_NODE_IE);
|
2135 } 2136 return 0; 2137 } 2138 if (!(2 <= ireq->i_len && ireq->i_len <= IEEE80211_MAX_APPIE)) 2139 return EINVAL; 2140 /* 2141 * Allocate a new appie structure and copy in the user data. 2142 * When done swap in the new structure. Note that we do not 2143 * guard against users holding a ref to the old structure; 2144 * this must be handled outside this code. 2145 * 2146 * XXX bad bad bad 2147 */
| 2135 } 2136 return 0; 2137 } 2138 if (!(2 <= ireq->i_len && ireq->i_len <= IEEE80211_MAX_APPIE)) 2139 return EINVAL; 2140 /* 2141 * Allocate a new appie structure and copy in the user data. 2142 * When done swap in the new structure. Note that we do not 2143 * guard against users holding a ref to the old structure; 2144 * this must be handled outside this code. 2145 * 2146 * XXX bad bad bad 2147 */
|
2148 MALLOC(napp, struct ieee80211_appie *,
| 2148 napp = (struct ieee80211_appie *) malloc(
|
2149 sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT); 2150 if (napp == NULL) 2151 return ENOMEM; 2152 /* XXX holding ic lock */ 2153 error = copyin(ireq->i_data, napp->ie_data, ireq->i_len); 2154 if (error) {
| 2149 sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT); 2150 if (napp == NULL) 2151 return ENOMEM; 2152 /* XXX holding ic lock */ 2153 error = copyin(ireq->i_data, napp->ie_data, ireq->i_len); 2154 if (error) {
|
2155 FREE(napp, M_80211_NODE_IE);
| 2155 free(napp, M_80211_NODE_IE);
|
2156 return error; 2157 } 2158 napp->ie_len = ireq->i_len; 2159 *aie = napp; 2160 if (app != NULL)
| 2156 return error; 2157 } 2158 napp->ie_len = ireq->i_len; 2159 *aie = napp; 2160 if (app != NULL)
|
2161 FREE(app, M_80211_NODE_IE);
| 2161 free(app, M_80211_NODE_IE);
|
2162 return 0; 2163} 2164 2165static void 2166setwparsnie(struct ieee80211vap *vap, uint8_t *ie, int space) 2167{ 2168 /* validate data is present as best we can */ 2169 if (space == 0 || 2+ie[1] > space) 2170 return; 2171 if (ie[0] == IEEE80211_ELEMID_VENDOR) 2172 vap->iv_wpa_ie = ie; 2173 else if (ie[0] == IEEE80211_ELEMID_RSN) 2174 vap->iv_rsn_ie = ie; 2175} 2176 2177static __noinline int 2178ieee80211_ioctl_setappie_locked(struct ieee80211vap *vap, 2179 const struct ieee80211req *ireq, int fc0) 2180{ 2181 int error; 2182 2183 IEEE80211_LOCK_ASSERT(vap->iv_ic); 2184 2185 switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { 2186 case IEEE80211_FC0_SUBTYPE_BEACON: 2187 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2188 vap->iv_opmode != IEEE80211_M_IBSS) { 2189 error = EINVAL; 2190 break; 2191 } 2192 error = setappie(&vap->iv_appie_beacon, ireq); 2193 if (error == 0) 2194 ieee80211_beacon_notify(vap, IEEE80211_BEACON_APPIE); 2195 break; 2196 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2197 error = setappie(&vap->iv_appie_proberesp, ireq); 2198 break; 2199 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2200 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2201 error = setappie(&vap->iv_appie_assocresp, ireq); 2202 else 2203 error = EINVAL; 2204 break; 2205 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2206 error = setappie(&vap->iv_appie_probereq, ireq); 2207 break; 2208 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2209 if (vap->iv_opmode == IEEE80211_M_STA) 2210 error = setappie(&vap->iv_appie_assocreq, ireq); 2211 else 2212 error = EINVAL; 2213 break; 2214 case (IEEE80211_APPIE_WPA & IEEE80211_FC0_SUBTYPE_MASK): 2215 error = setappie(&vap->iv_appie_wpa, ireq); 2216 if (error == 0) { 2217 /* 2218 * Must split single blob of data into separate 2219 * WPA and RSN ie's because they go in different 2220 * locations in the mgt frames. 2221 * XXX use IEEE80211_IOC_WPA2 so user code does split 2222 */ 2223 vap->iv_wpa_ie = NULL; 2224 vap->iv_rsn_ie = NULL; 2225 if (vap->iv_appie_wpa != NULL) { 2226 struct ieee80211_appie *appie = 2227 vap->iv_appie_wpa; 2228 uint8_t *data = appie->ie_data; 2229 2230 /* XXX ie length validate is painful, cheat */ 2231 setwparsnie(vap, data, appie->ie_len); 2232 setwparsnie(vap, data + 2 + data[1], 2233 appie->ie_len - (2 + data[1])); 2234 } 2235 if (vap->iv_opmode == IEEE80211_M_HOSTAP || 2236 vap->iv_opmode == IEEE80211_M_IBSS) { 2237 /* 2238 * Must rebuild beacon frame as the update 2239 * mechanism doesn't handle WPA/RSN ie's. 2240 * Could extend it but it doesn't normally 2241 * change; this is just to deal with hostapd 2242 * plumbing the ie after the interface is up. 2243 */ 2244 error = ENETRESET; 2245 } 2246 } 2247 break; 2248 default: 2249 error = EINVAL; 2250 break; 2251 } 2252 return error; 2253} 2254 2255static __noinline int 2256ieee80211_ioctl_setappie(struct ieee80211vap *vap, 2257 const struct ieee80211req *ireq) 2258{ 2259 struct ieee80211com *ic = vap->iv_ic; 2260 int error; 2261 uint8_t fc0; 2262 2263 fc0 = ireq->i_val & 0xff; 2264 if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) 2265 return EINVAL; 2266 /* NB: could check iv_opmode and reject but hardly worth the effort */ 2267 IEEE80211_LOCK(ic); 2268 error = ieee80211_ioctl_setappie_locked(vap, ireq, fc0); 2269 IEEE80211_UNLOCK(ic); 2270 return error; 2271} 2272 2273static __noinline int 2274ieee80211_ioctl_chanswitch(struct ieee80211vap *vap, struct ieee80211req *ireq) 2275{ 2276 struct ieee80211com *ic = vap->iv_ic; 2277 struct ieee80211_chanswitch_req csr; 2278 struct ieee80211_channel *c; 2279 int error; 2280 2281 if (ireq->i_len != sizeof(csr)) 2282 return EINVAL; 2283 error = copyin(ireq->i_data, &csr, sizeof(csr)); 2284 if (error != 0) 2285 return error; 2286 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 2287 return EINVAL; 2288 c = ieee80211_find_channel(ic, 2289 csr.csa_chan.ic_freq, csr.csa_chan.ic_flags); 2290 if (c == NULL) 2291 return ENOENT; 2292 IEEE80211_LOCK(ic); 2293 if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) 2294 ieee80211_csa_startswitch(ic, c, csr.csa_mode, csr.csa_count); 2295 else 2296 error = EBUSY; 2297 IEEE80211_UNLOCK(ic); 2298 return error; 2299} 2300 2301static __noinline int 2302ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq) 2303{ 2304#define IEEE80211_IOC_SCAN_FLAGS \ 2305 (IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \ 2306 IEEE80211_IOC_SCAN_PICK1ST | IEEE80211_IOC_SCAN_BGSCAN | \ 2307 IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOBCAST | \ 2308 IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \ 2309 IEEE80211_IOC_SCAN_CHECK) 2310 struct ieee80211com *ic = vap->iv_ic; 2311 struct ieee80211_scan_req sr; /* XXX off stack? */ 2312 int error, i; 2313 2314 /* NB: parent must be running */ 2315 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 2316 return ENXIO; 2317 2318 if (ireq->i_len != sizeof(sr)) 2319 return EINVAL; 2320 error = copyin(ireq->i_data, &sr, sizeof(sr)); 2321 if (error != 0) 2322 return error; 2323 /* convert duration */ 2324 if (sr.sr_duration == IEEE80211_IOC_SCAN_FOREVER) 2325 sr.sr_duration = IEEE80211_SCAN_FOREVER; 2326 else { 2327 if (sr.sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN || 2328 sr.sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX) 2329 return EINVAL; 2330 sr.sr_duration = msecs_to_ticks(sr.sr_duration); 2331 if (sr.sr_duration < 1) 2332 sr.sr_duration = 1; 2333 } 2334 /* convert min/max channel dwell */ 2335 if (sr.sr_mindwell != 0) { 2336 sr.sr_mindwell = msecs_to_ticks(sr.sr_mindwell); 2337 if (sr.sr_mindwell < 1) 2338 sr.sr_mindwell = 1; 2339 } 2340 if (sr.sr_maxdwell != 0) { 2341 sr.sr_maxdwell = msecs_to_ticks(sr.sr_maxdwell); 2342 if (sr.sr_maxdwell < 1) 2343 sr.sr_maxdwell = 1; 2344 } 2345 /* NB: silently reduce ssid count to what is supported */ 2346 if (sr.sr_nssid > IEEE80211_SCAN_MAX_SSID) 2347 sr.sr_nssid = IEEE80211_SCAN_MAX_SSID; 2348 for (i = 0; i < sr.sr_nssid; i++) 2349 if (sr.sr_ssid[i].len > IEEE80211_NWID_LEN) 2350 return EINVAL; 2351 /* cleanse flags just in case, could reject if invalid flags */ 2352 sr.sr_flags &= IEEE80211_IOC_SCAN_FLAGS; 2353 /* 2354 * Add an implicit NOPICK if the vap is not marked UP. This 2355 * allows applications to scan without joining a bss (or picking 2356 * a channel and setting up a bss) and without forcing manual 2357 * roaming mode--you just need to mark the parent device UP. 2358 */ 2359 if ((vap->iv_ifp->if_flags & IFF_UP) == 0) 2360 sr.sr_flags |= IEEE80211_IOC_SCAN_NOPICK; 2361 2362 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2363 "%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n", 2364 __func__, sr.sr_flags, 2365 (vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "", 2366 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, sr.sr_nssid); 2367 /* 2368 * If we are in INIT state then the driver has never had a chance 2369 * to setup hardware state to do a scan; we must use the state 2370 * machine to get us up to the SCAN state but once we reach SCAN 2371 * state we then want to use the supplied params. Stash the 2372 * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the 2373 * state machines will recognize this and use the stashed params 2374 * to issue the scan request. 2375 * 2376 * Otherwise just invoke the scan machinery directly. 2377 */ 2378 IEEE80211_LOCK(ic); 2379 if (vap->iv_state == IEEE80211_S_INIT) { 2380 /* NB: clobbers previous settings */ 2381 vap->iv_scanreq_flags = sr.sr_flags; 2382 vap->iv_scanreq_duration = sr.sr_duration; 2383 vap->iv_scanreq_nssid = sr.sr_nssid; 2384 for (i = 0; i < sr.sr_nssid; i++) { 2385 vap->iv_scanreq_ssid[i].len = sr.sr_ssid[i].len; 2386 memcpy(vap->iv_scanreq_ssid[i].ssid, sr.sr_ssid[i].ssid, 2387 sr.sr_ssid[i].len); 2388 } 2389 vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ; 2390 IEEE80211_UNLOCK(ic); 2391 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2392 } else { 2393 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; 2394 IEEE80211_UNLOCK(ic); 2395 /* XXX neeed error return codes */ 2396 if (sr.sr_flags & IEEE80211_IOC_SCAN_CHECK) { 2397 (void) ieee80211_check_scan(vap, sr.sr_flags, 2398 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2399 sr.sr_nssid, 2400 /* NB: cheat, we assume structures are compatible */ 2401 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2402 } else { 2403 (void) ieee80211_start_scan(vap, sr.sr_flags, 2404 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2405 sr.sr_nssid, 2406 /* NB: cheat, we assume structures are compatible */ 2407 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2408 } 2409 } 2410 return error; 2411#undef IEEE80211_IOC_SCAN_FLAGS 2412} 2413 2414static __noinline int 2415ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) 2416{ 2417 struct ieee80211_node *ni; 2418 struct ieee80211req_sta_vlan vlan; 2419 int error; 2420 2421 if (ireq->i_len != sizeof(vlan)) 2422 return EINVAL; 2423 error = copyin(ireq->i_data, &vlan, sizeof(vlan)); 2424 if (error != 0) 2425 return error; 2426 if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { 2427 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 2428 vlan.sv_macaddr); 2429 if (ni == NULL) 2430 return ENOENT; 2431 } else 2432 ni = ieee80211_ref_node(vap->iv_bss); 2433 ni->ni_vlan = vlan.sv_vlan; 2434 ieee80211_free_node(ni); 2435 return error; 2436} 2437 2438static int 2439isvap11g(const struct ieee80211vap *vap) 2440{ 2441 const struct ieee80211_node *bss = vap->iv_bss; 2442 return bss->ni_chan != IEEE80211_CHAN_ANYC && 2443 IEEE80211_IS_CHAN_ANYG(bss->ni_chan); 2444} 2445 2446static int 2447isvapht(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_HT(bss->ni_chan); 2452} 2453 2454static __noinline int 2455ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211req *ireq) 2456{ 2457 struct ieee80211com *ic = vap->iv_ic; 2458 int error; 2459 const struct ieee80211_authenticator *auth; 2460 uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 2461 char tmpssid[IEEE80211_NWID_LEN]; 2462 uint8_t tmpbssid[IEEE80211_ADDR_LEN]; 2463 struct ieee80211_key *k; 2464 u_int kid; 2465 uint32_t flags; 2466 2467 error = 0; 2468 switch (ireq->i_type) { 2469 case IEEE80211_IOC_SSID: 2470 if (ireq->i_val != 0 || 2471 ireq->i_len > IEEE80211_NWID_LEN) 2472 return EINVAL; 2473 error = copyin(ireq->i_data, tmpssid, ireq->i_len); 2474 if (error) 2475 break; 2476 memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN); 2477 vap->iv_des_ssid[0].len = ireq->i_len; 2478 memcpy(vap->iv_des_ssid[0].ssid, tmpssid, ireq->i_len); 2479 vap->iv_des_nssid = (ireq->i_len > 0); 2480 error = ENETRESET; 2481 break; 2482 case IEEE80211_IOC_WEP: 2483 switch (ireq->i_val) { 2484 case IEEE80211_WEP_OFF: 2485 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2486 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2487 break; 2488 case IEEE80211_WEP_ON: 2489 vap->iv_flags |= IEEE80211_F_PRIVACY; 2490 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2491 break; 2492 case IEEE80211_WEP_MIXED: 2493 vap->iv_flags |= IEEE80211_F_PRIVACY; 2494 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2495 break; 2496 } 2497 error = ENETRESET; 2498 break; 2499 case IEEE80211_IOC_WEPKEY: 2500 kid = (u_int) ireq->i_val; 2501 if (kid >= IEEE80211_WEP_NKID) 2502 return EINVAL; 2503 k = &vap->iv_nw_keys[kid]; 2504 if (ireq->i_len == 0) { 2505 /* zero-len =>'s delete any existing key */ 2506 (void) ieee80211_crypto_delkey(vap, k); 2507 break; 2508 } 2509 if (ireq->i_len > sizeof(tmpkey)) 2510 return EINVAL; 2511 memset(tmpkey, 0, sizeof(tmpkey)); 2512 error = copyin(ireq->i_data, tmpkey, ireq->i_len); 2513 if (error) 2514 break; 2515 ieee80211_key_update_begin(vap); 2516 k->wk_keyix = kid; /* NB: force fixed key id */ 2517 if (ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP, 2518 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) { 2519 k->wk_keylen = ireq->i_len; 2520 memcpy(k->wk_key, tmpkey, sizeof(tmpkey)); 2521 IEEE80211_ADDR_COPY(k->wk_macaddr, vap->iv_myaddr); 2522 if (!ieee80211_crypto_setkey(vap, k)) 2523 error = EINVAL; 2524 } else 2525 error = EINVAL; 2526 ieee80211_key_update_end(vap); 2527 break; 2528 case IEEE80211_IOC_WEPTXKEY: 2529 kid = (u_int) ireq->i_val; 2530 if (kid >= IEEE80211_WEP_NKID && 2531 (uint16_t) kid != IEEE80211_KEYIX_NONE) 2532 return EINVAL; 2533 vap->iv_def_txkey = kid; 2534 break; 2535 case IEEE80211_IOC_AUTHMODE: 2536 switch (ireq->i_val) { 2537 case IEEE80211_AUTH_WPA: 2538 case IEEE80211_AUTH_8021X: /* 802.1x */ 2539 case IEEE80211_AUTH_OPEN: /* open */ 2540 case IEEE80211_AUTH_SHARED: /* shared-key */ 2541 case IEEE80211_AUTH_AUTO: /* auto */ 2542 auth = ieee80211_authenticator_get(ireq->i_val); 2543 if (auth == NULL) 2544 return EINVAL; 2545 break; 2546 default: 2547 return EINVAL; 2548 } 2549 switch (ireq->i_val) { 2550 case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ 2551 vap->iv_flags |= IEEE80211_F_PRIVACY; 2552 ireq->i_val = IEEE80211_AUTH_8021X; 2553 break; 2554 case IEEE80211_AUTH_OPEN: /* open */ 2555 vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY); 2556 break; 2557 case IEEE80211_AUTH_SHARED: /* shared-key */ 2558 case IEEE80211_AUTH_8021X: /* 802.1x */ 2559 vap->iv_flags &= ~IEEE80211_F_WPA; 2560 /* both require a key so mark the PRIVACY capability */ 2561 vap->iv_flags |= IEEE80211_F_PRIVACY; 2562 break; 2563 case IEEE80211_AUTH_AUTO: /* auto */ 2564 vap->iv_flags &= ~IEEE80211_F_WPA; 2565 /* XXX PRIVACY handling? */ 2566 /* XXX what's the right way to do this? */ 2567 break; 2568 } 2569 /* NB: authenticator attach/detach happens on state change */ 2570 vap->iv_bss->ni_authmode = ireq->i_val; 2571 /* XXX mixed/mode/usage? */ 2572 vap->iv_auth = auth; 2573 error = ENETRESET; 2574 break; 2575 case IEEE80211_IOC_CHANNEL: 2576 error = ieee80211_ioctl_setchannel(vap, ireq); 2577 break; 2578 case IEEE80211_IOC_POWERSAVE: 2579 switch (ireq->i_val) { 2580 case IEEE80211_POWERSAVE_OFF: 2581 if (vap->iv_flags & IEEE80211_F_PMGTON) { 2582 ieee80211_syncflag(vap, -IEEE80211_F_PMGTON); 2583 error = ERESTART; 2584 } 2585 break; 2586 case IEEE80211_POWERSAVE_ON: 2587 if ((vap->iv_caps & IEEE80211_C_PMGT) == 0) 2588 error = EOPNOTSUPP; 2589 else if ((vap->iv_flags & IEEE80211_F_PMGTON) == 0) { 2590 ieee80211_syncflag(vap, IEEE80211_F_PMGTON); 2591 error = ERESTART; 2592 } 2593 break; 2594 default: 2595 error = EINVAL; 2596 break; 2597 } 2598 break; 2599 case IEEE80211_IOC_POWERSAVESLEEP: 2600 if (ireq->i_val < 0) 2601 return EINVAL; 2602 ic->ic_lintval = ireq->i_val; 2603 error = ERESTART; 2604 break; 2605 case IEEE80211_IOC_RTSTHRESHOLD: 2606 if (!(IEEE80211_RTS_MIN <= ireq->i_val && 2607 ireq->i_val <= IEEE80211_RTS_MAX)) 2608 return EINVAL; 2609 vap->iv_rtsthreshold = ireq->i_val; 2610 error = ERESTART; 2611 break; 2612 case IEEE80211_IOC_PROTMODE: 2613 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 2614 return EINVAL; 2615 ic->ic_protmode = ireq->i_val; 2616 /* NB: if not operating in 11g this can wait */ 2617 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && 2618 IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) 2619 error = ERESTART; 2620 break; 2621 case IEEE80211_IOC_TXPOWER: 2622 if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) 2623 return EOPNOTSUPP; 2624 if (!(IEEE80211_TXPOWER_MIN <= ireq->i_val && 2625 ireq->i_val <= IEEE80211_TXPOWER_MAX)) 2626 return EINVAL; 2627 ic->ic_txpowlimit = ireq->i_val; 2628 error = ERESTART; 2629 break; 2630 case IEEE80211_IOC_ROAMING: 2631 if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val && 2632 ireq->i_val <= IEEE80211_ROAMING_MANUAL)) 2633 return EINVAL; 2634 vap->iv_roaming = ireq->i_val; 2635 /* XXXX reset? */ 2636 break; 2637 case IEEE80211_IOC_PRIVACY: 2638 if (ireq->i_val) { 2639 /* XXX check for key state? */ 2640 vap->iv_flags |= IEEE80211_F_PRIVACY; 2641 } else 2642 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2643 /* XXX ERESTART? */ 2644 break; 2645 case IEEE80211_IOC_DROPUNENCRYPTED: 2646 if (ireq->i_val) 2647 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2648 else 2649 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2650 /* XXX ERESTART? */ 2651 break; 2652 case IEEE80211_IOC_WPAKEY: 2653 error = ieee80211_ioctl_setkey(vap, ireq); 2654 break; 2655 case IEEE80211_IOC_DELKEY: 2656 error = ieee80211_ioctl_delkey(vap, ireq); 2657 break; 2658 case IEEE80211_IOC_MLME: 2659 error = ieee80211_ioctl_setmlme(vap, ireq); 2660 break; 2661 case IEEE80211_IOC_COUNTERMEASURES: 2662 if (ireq->i_val) { 2663 if ((vap->iv_flags & IEEE80211_F_WPA) == 0) 2664 return EOPNOTSUPP; 2665 vap->iv_flags |= IEEE80211_F_COUNTERM; 2666 } else 2667 vap->iv_flags &= ~IEEE80211_F_COUNTERM; 2668 /* XXX ERESTART? */ 2669 break; 2670 case IEEE80211_IOC_WPA: 2671 if (ireq->i_val > 3) 2672 return EINVAL; 2673 /* XXX verify ciphers available */ 2674 flags = vap->iv_flags & ~IEEE80211_F_WPA; 2675 switch (ireq->i_val) { 2676 case 1: 2677 if (!(vap->iv_caps & IEEE80211_C_WPA1)) 2678 return EOPNOTSUPP; 2679 flags |= IEEE80211_F_WPA1; 2680 break; 2681 case 2: 2682 if (!(vap->iv_caps & IEEE80211_C_WPA2)) 2683 return EOPNOTSUPP; 2684 flags |= IEEE80211_F_WPA2; 2685 break; 2686 case 3: 2687 if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA) 2688 flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; 2689 break; 2690 default: /* Can't set any -> error */ 2691 return EOPNOTSUPP; 2692 } 2693 vap->iv_flags = flags; 2694 error = ERESTART; /* NB: can change beacon frame */ 2695 break; 2696 case IEEE80211_IOC_WME: 2697 if (ireq->i_val) { 2698 if ((vap->iv_caps & IEEE80211_C_WME) == 0) 2699 return EOPNOTSUPP; 2700 ieee80211_syncflag(vap, IEEE80211_F_WME); 2701 } else 2702 ieee80211_syncflag(vap, -IEEE80211_F_WME); 2703 error = ERESTART; /* NB: can change beacon frame */ 2704 break; 2705 case IEEE80211_IOC_HIDESSID: 2706 if (ireq->i_val) 2707 vap->iv_flags |= IEEE80211_F_HIDESSID; 2708 else 2709 vap->iv_flags &= ~IEEE80211_F_HIDESSID; 2710 error = ERESTART; /* XXX ENETRESET? */ 2711 break; 2712 case IEEE80211_IOC_APBRIDGE: 2713 if (ireq->i_val == 0) 2714 vap->iv_flags |= IEEE80211_F_NOBRIDGE; 2715 else 2716 vap->iv_flags &= ~IEEE80211_F_NOBRIDGE; 2717 break; 2718 case IEEE80211_IOC_BSSID: 2719 if (ireq->i_len != sizeof(tmpbssid)) 2720 return EINVAL; 2721 error = copyin(ireq->i_data, tmpbssid, ireq->i_len); 2722 if (error) 2723 break; 2724 IEEE80211_ADDR_COPY(vap->iv_des_bssid, tmpbssid); 2725 if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, zerobssid)) 2726 vap->iv_flags &= ~IEEE80211_F_DESBSSID; 2727 else 2728 vap->iv_flags |= IEEE80211_F_DESBSSID; 2729 error = ENETRESET; 2730 break; 2731 case IEEE80211_IOC_CHANLIST: 2732 error = ieee80211_ioctl_setchanlist(vap, ireq); 2733 break; 2734#define OLD_IEEE80211_IOC_SCAN_REQ 23 2735#ifdef OLD_IEEE80211_IOC_SCAN_REQ 2736 case OLD_IEEE80211_IOC_SCAN_REQ: 2737 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2738 "%s: active scan request\n", __func__); 2739 /* 2740 * If we are in INIT state then the driver has never 2741 * had a chance to setup hardware state to do a scan; 2742 * use the state machine to get us up the SCAN state. 2743 * Otherwise just invoke the scan machinery to start 2744 * a one-time scan. 2745 */ 2746 if (vap->iv_state == IEEE80211_S_INIT) 2747 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2748 else 2749 (void) ieee80211_start_scan(vap, 2750 IEEE80211_SCAN_ACTIVE | 2751 IEEE80211_SCAN_NOPICK | 2752 IEEE80211_SCAN_ONCE, 2753 IEEE80211_SCAN_FOREVER, 0, 0, 2754 /* XXX use ioctl params */ 2755 vap->iv_des_nssid, vap->iv_des_ssid); 2756 break; 2757#endif /* OLD_IEEE80211_IOC_SCAN_REQ */ 2758 case IEEE80211_IOC_SCAN_REQ: 2759 error = ieee80211_ioctl_scanreq(vap, ireq); 2760 break; 2761 case IEEE80211_IOC_SCAN_CANCEL: 2762 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2763 "%s: cancel scan\n", __func__); 2764 ieee80211_cancel_scan(vap); 2765 break; 2766 case IEEE80211_IOC_HTCONF: 2767 if (ireq->i_val & 1) 2768 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_HT); 2769 else 2770 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_HT); 2771 if (ireq->i_val & 2) 2772 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_USEHT40); 2773 else 2774 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_USEHT40); 2775 error = ENETRESET; 2776 break; 2777 case IEEE80211_IOC_ADDMAC: 2778 case IEEE80211_IOC_DELMAC: 2779 error = ieee80211_ioctl_macmac(vap, ireq); 2780 break; 2781 case IEEE80211_IOC_MACCMD: 2782 error = ieee80211_ioctl_setmaccmd(vap, ireq); 2783 break; 2784 case IEEE80211_IOC_STA_STATS: 2785 error = ieee80211_ioctl_setstastats(vap, ireq); 2786 break; 2787 case IEEE80211_IOC_STA_TXPOW: 2788 error = ieee80211_ioctl_setstatxpow(vap, ireq); 2789 break; 2790 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2791 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2792 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2793 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2794 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2795 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 2796 error = ieee80211_ioctl_setwmeparam(vap, ireq); 2797 break; 2798 case IEEE80211_IOC_DTIM_PERIOD: 2799 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2800 vap->iv_opmode != IEEE80211_M_IBSS) 2801 return EINVAL; 2802 if (IEEE80211_DTIM_MIN <= ireq->i_val && 2803 ireq->i_val <= IEEE80211_DTIM_MAX) { 2804 vap->iv_dtim_period = ireq->i_val; 2805 error = ENETRESET; /* requires restart */ 2806 } else 2807 error = EINVAL; 2808 break; 2809 case IEEE80211_IOC_BEACON_INTERVAL: 2810 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2811 vap->iv_opmode != IEEE80211_M_IBSS) 2812 return EINVAL; 2813 if (IEEE80211_BINTVAL_MIN <= ireq->i_val && 2814 ireq->i_val <= IEEE80211_BINTVAL_MAX) { 2815 ic->ic_bintval = ireq->i_val; 2816 error = ENETRESET; /* requires restart */ 2817 } else 2818 error = EINVAL; 2819 break; 2820 case IEEE80211_IOC_PUREG: 2821 if (ireq->i_val) 2822 vap->iv_flags |= IEEE80211_F_PUREG; 2823 else 2824 vap->iv_flags &= ~IEEE80211_F_PUREG; 2825 /* NB: reset only if we're operating on an 11g channel */ 2826 if (isvap11g(vap)) 2827 error = ENETRESET; 2828 break; 2829 case IEEE80211_IOC_FF: 2830 if (ireq->i_val) { 2831 if ((vap->iv_caps & IEEE80211_C_FF) == 0) 2832 return EOPNOTSUPP; 2833 vap->iv_flags |= IEEE80211_F_FF; 2834 } else 2835 vap->iv_flags &= ~IEEE80211_F_FF; 2836 error = ERESTART; 2837 break; 2838 case IEEE80211_IOC_TURBOP: 2839 if (ireq->i_val) { 2840 if ((vap->iv_caps & IEEE80211_C_TURBOP) == 0) 2841 return EOPNOTSUPP; 2842 vap->iv_flags |= IEEE80211_F_TURBOP; 2843 } else 2844 vap->iv_flags &= ~IEEE80211_F_TURBOP; 2845 error = ENETRESET; 2846 break; 2847 case IEEE80211_IOC_BGSCAN: 2848 if (ireq->i_val) { 2849 if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0) 2850 return EOPNOTSUPP; 2851 vap->iv_flags |= IEEE80211_F_BGSCAN; 2852 } else 2853 vap->iv_flags &= ~IEEE80211_F_BGSCAN; 2854 break; 2855 case IEEE80211_IOC_BGSCAN_IDLE: 2856 if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN) 2857 vap->iv_bgscanidle = ireq->i_val*hz/1000; 2858 else 2859 error = EINVAL; 2860 break; 2861 case IEEE80211_IOC_BGSCAN_INTERVAL: 2862 if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN) 2863 vap->iv_bgscanintvl = ireq->i_val*hz; 2864 else 2865 error = EINVAL; 2866 break; 2867 case IEEE80211_IOC_SCANVALID: 2868 if (ireq->i_val >= IEEE80211_SCAN_VALID_MIN) 2869 vap->iv_scanvalid = ireq->i_val*hz; 2870 else 2871 error = EINVAL; 2872 break; 2873 case IEEE80211_IOC_FRAGTHRESHOLD: 2874 if ((vap->iv_caps & IEEE80211_C_TXFRAG) == 0 && 2875 ireq->i_val != IEEE80211_FRAG_MAX) 2876 return EOPNOTSUPP; 2877 if (!(IEEE80211_FRAG_MIN <= ireq->i_val && 2878 ireq->i_val <= IEEE80211_FRAG_MAX)) 2879 return EINVAL; 2880 vap->iv_fragthreshold = ireq->i_val; 2881 error = ERESTART; 2882 break; 2883 case IEEE80211_IOC_BURST: 2884 if (ireq->i_val) { 2885 if ((vap->iv_caps & IEEE80211_C_BURST) == 0) 2886 return EOPNOTSUPP; 2887 ieee80211_syncflag(vap, IEEE80211_F_BURST); 2888 } else 2889 ieee80211_syncflag(vap, -IEEE80211_F_BURST); 2890 error = ERESTART; 2891 break; 2892 case IEEE80211_IOC_BMISSTHRESHOLD: 2893 if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val && 2894 ireq->i_val <= IEEE80211_HWBMISS_MAX)) 2895 return EINVAL; 2896 vap->iv_bmissthreshold = ireq->i_val; 2897 error = ERESTART; 2898 break; 2899 case IEEE80211_IOC_CURCHAN: 2900 error = ieee80211_ioctl_setcurchan(vap, ireq); 2901 break; 2902 case IEEE80211_IOC_SHORTGI: 2903 if (ireq->i_val) { 2904#define IEEE80211_HTCAP_SHORTGI \ 2905 (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40) 2906 if (((ireq->i_val ^ vap->iv_htcaps) & IEEE80211_HTCAP_SHORTGI) != 0) 2907 return EINVAL; 2908 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI20) 2909 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI20; 2910 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI40) 2911 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI40; 2912#undef IEEE80211_HTCAP_SHORTGI 2913 } else 2914 vap->iv_flags_ext &= 2915 ~(IEEE80211_FEXT_SHORTGI20 | IEEE80211_FEXT_SHORTGI40); 2916 error = ERESTART; 2917 break; 2918 case IEEE80211_IOC_AMPDU: 2919 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0) 2920 return EINVAL; 2921 if (ireq->i_val & 1) 2922 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_TX; 2923 else 2924 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_TX; 2925 if (ireq->i_val & 2) 2926 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_RX; 2927 else 2928 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_RX; 2929 /* NB: reset only if we're operating on an 11n channel */ 2930 if (isvapht(vap)) 2931 error = ERESTART; 2932 break; 2933 case IEEE80211_IOC_AMPDU_LIMIT: 2934 if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val && 2935 ireq->i_val <= IEEE80211_HTCAP_MAXRXAMPDU_64K)) 2936 return EINVAL; 2937 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2938 vap->iv_ampdu_rxmax = ireq->i_val; 2939 else 2940 vap->iv_ampdu_limit = ireq->i_val; 2941 error = ERESTART; 2942 break; 2943 case IEEE80211_IOC_AMPDU_DENSITY: 2944 if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val && 2945 ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16)) 2946 return EINVAL; 2947 vap->iv_ampdu_density = ireq->i_val; 2948 error = ERESTART; 2949 break; 2950 case IEEE80211_IOC_AMSDU: 2951 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0) 2952 return EINVAL; 2953 if (ireq->i_val & 1) 2954 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_TX; 2955 else 2956 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_TX; 2957 if (ireq->i_val & 2) 2958 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_RX; 2959 else 2960 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_RX; 2961 /* NB: reset only if we're operating on an 11n channel */ 2962 if (isvapht(vap)) 2963 error = ERESTART; 2964 break; 2965 case IEEE80211_IOC_AMSDU_LIMIT: 2966 /* XXX validate */ 2967 vap->iv_amsdu_limit = ireq->i_val; /* XXX truncation? */ 2968 break; 2969 case IEEE80211_IOC_PUREN: 2970 if (ireq->i_val) { 2971 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 2972 return EINVAL; 2973 vap->iv_flags_ext |= IEEE80211_FEXT_PUREN; 2974 } else 2975 vap->iv_flags_ext &= ~IEEE80211_FEXT_PUREN; 2976 /* NB: reset only if we're operating on an 11n channel */ 2977 if (isvapht(vap)) 2978 error = ERESTART; 2979 break; 2980 case IEEE80211_IOC_DOTH: 2981 if (ireq->i_val) { 2982#if 0 2983 /* XXX no capability */ 2984 if ((vap->iv_caps & IEEE80211_C_DOTH) == 0) 2985 return EOPNOTSUPP; 2986#endif 2987 vap->iv_flags |= IEEE80211_F_DOTH; 2988 } else 2989 vap->iv_flags &= ~IEEE80211_F_DOTH; 2990 error = ENETRESET; 2991 break; 2992 case IEEE80211_IOC_REGDOMAIN: 2993 error = ieee80211_ioctl_setregdomain(vap, ireq); 2994 break; 2995 case IEEE80211_IOC_ROAM: 2996 error = ieee80211_ioctl_setroam(vap, ireq); 2997 break; 2998 case IEEE80211_IOC_TXPARAMS: 2999 error = ieee80211_ioctl_settxparams(vap, ireq); 3000 break; 3001 case IEEE80211_IOC_HTCOMPAT: 3002 if (ireq->i_val) { 3003 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 3004 return EOPNOTSUPP; 3005 vap->iv_flags_ext |= IEEE80211_FEXT_HTCOMPAT; 3006 } else 3007 vap->iv_flags_ext &= ~IEEE80211_FEXT_HTCOMPAT; 3008 /* NB: reset only if we're operating on an 11n channel */ 3009 if (isvapht(vap)) 3010 error = ERESTART; 3011 break; 3012 case IEEE80211_IOC_DWDS: 3013 if (ireq->i_val) { 3014 /* NB: DWDS only makes sense for WDS-capable devices */ 3015 if ((ic->ic_caps & IEEE80211_C_WDS) == 0) 3016 return EOPNOTSUPP; 3017 /* NB: DWDS is used only with ap+sta vaps */ 3018 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 3019 vap->iv_opmode != IEEE80211_M_STA) 3020 return EINVAL; 3021 vap->iv_flags |= IEEE80211_F_DWDS; 3022 } else 3023 vap->iv_flags &= ~IEEE80211_F_DWDS; 3024 break; 3025 case IEEE80211_IOC_INACTIVITY: 3026 if (ireq->i_val) 3027 vap->iv_flags_ext |= IEEE80211_FEXT_INACT; 3028 else 3029 vap->iv_flags_ext &= ~IEEE80211_FEXT_INACT; 3030 break; 3031 case IEEE80211_IOC_APPIE: 3032 error = ieee80211_ioctl_setappie(vap, ireq); 3033 break; 3034 case IEEE80211_IOC_WPS: 3035 if (ireq->i_val) { 3036 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3037 return EOPNOTSUPP; 3038 vap->iv_flags_ext |= IEEE80211_FEXT_WPS; 3039 } else 3040 vap->iv_flags_ext &= ~IEEE80211_FEXT_WPS; 3041 break; 3042 case IEEE80211_IOC_TSN: 3043 if (ireq->i_val) { 3044 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3045 return EOPNOTSUPP; 3046 vap->iv_flags_ext |= IEEE80211_FEXT_TSN; 3047 } else 3048 vap->iv_flags_ext &= ~IEEE80211_FEXT_TSN; 3049 break; 3050 case IEEE80211_IOC_CHANSWITCH: 3051 error = ieee80211_ioctl_chanswitch(vap, ireq); 3052 break; 3053 case IEEE80211_IOC_DFS: 3054 if (ireq->i_val) { 3055 if ((vap->iv_caps & IEEE80211_C_DFS) == 0) 3056 return EOPNOTSUPP; 3057 /* NB: DFS requires 11h support */ 3058 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 3059 return EINVAL; 3060 vap->iv_flags_ext |= IEEE80211_FEXT_DFS; 3061 } else 3062 vap->iv_flags_ext &= ~IEEE80211_FEXT_DFS; 3063 break; 3064 case IEEE80211_IOC_DOTD: 3065 if (ireq->i_val) 3066 vap->iv_flags_ext |= IEEE80211_FEXT_DOTD; 3067 else 3068 vap->iv_flags_ext &= ~IEEE80211_FEXT_DOTD; 3069 if (vap->iv_opmode == IEEE80211_M_STA) 3070 error = ENETRESET; 3071 break; 3072 case IEEE80211_IOC_HTPROTMODE: 3073 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 3074 return EINVAL; 3075 ic->ic_htprotmode = ireq->i_val ? 3076 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE; 3077 /* NB: if not operating in 11n this can wait */ 3078 if (isvapht(vap)) 3079 error = ERESTART; 3080 break; 3081 case IEEE80211_IOC_STA_VLAN: 3082 error = ieee80211_ioctl_setstavlan(vap, ireq); 3083 break; 3084 case IEEE80211_IOC_SMPS: 3085 if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 || 3086 ireq->i_val == 0x0008) /* value of 2 is reserved */ 3087 return EINVAL; 3088 if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF && 3089 (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0) 3090 return EOPNOTSUPP; 3091 vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) | 3092 ireq->i_val; 3093 /* NB: if not operating in 11n this can wait */ 3094 if (isvapht(vap)) 3095 error = ERESTART; 3096 break; 3097 case IEEE80211_IOC_RIFS: 3098 if (ireq->i_val != 0) { 3099 if ((vap->iv_htcaps & IEEE80211_HTC_RIFS) == 0) 3100 return EOPNOTSUPP; 3101 vap->iv_flags_ext |= IEEE80211_FEXT_RIFS; 3102 } else 3103 vap->iv_flags_ext &= ~IEEE80211_FEXT_RIFS; 3104 /* NB: if not operating in 11n this can wait */ 3105 if (isvapht(vap)) 3106 error = ERESTART; 3107 break; 3108 default: 3109 error = EINVAL; 3110 break; 3111 } 3112 /* 3113 * The convention is that ENETRESET means an operation 3114 * requires a complete re-initialization of the device (e.g. 3115 * changing something that affects the association state). 3116 * ERESTART means the request may be handled with only a 3117 * reload of the hardware state. We hand ERESTART requests 3118 * to the iv_reset callback so the driver can decide. If 3119 * a device does not fillin iv_reset then it defaults to one 3120 * that returns ENETRESET. Otherwise a driver may return 3121 * ENETRESET (in which case a full reset will be done) or 3122 * 0 to mean there's no need to do anything (e.g. when the 3123 * change has no effect on the driver/device). 3124 */ 3125 if (error == ERESTART) 3126 error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ? 3127 vap->iv_reset(vap, ireq->i_type) : 0; 3128 if (error == ENETRESET) { 3129 /* XXX need to re-think AUTO handling */ 3130 if (IS_UP_AUTO(vap)) 3131 ieee80211_init(vap); 3132 error = 0; 3133 } 3134 return error; 3135} 3136 3137/* 3138 * Rebuild the parent's multicast address list after an add/del 3139 * of a multicast address for a vap. We have no way to tell 3140 * what happened above to optimize the work so we purge the entire 3141 * list and rebuild from scratch. This is way expensive. 3142 * Note also the half-baked workaround for if_addmulti calling 3143 * back to the parent device; there's no way to insert mcast 3144 * entries quietly and/or cheaply. 3145 */ 3146static void 3147ieee80211_ioctl_updatemulti(struct ieee80211com *ic) 3148{ 3149 struct ifnet *parent = ic->ic_ifp; 3150 struct ieee80211vap *vap; 3151 void *ioctl; 3152 3153 IEEE80211_LOCK(ic); 3154 if_purgemaddrs(parent); 3155 ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */ 3156 parent->if_ioctl = NULL; 3157 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 3158 struct ifnet *ifp = vap->iv_ifp; 3159 struct ifmultiaddr *ifma; 3160 3161 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) 3162 (void) if_addmulti(parent, ifma->ifma_addr, NULL); 3163 } 3164 parent->if_ioctl = ioctl; 3165 3166 ic->ic_update_mcast(ic->ic_ifp); 3167 IEEE80211_UNLOCK(ic); 3168} 3169 3170int 3171ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 3172{ 3173 struct ieee80211vap *vap; 3174 struct ieee80211com *ic; 3175 int error = 0; 3176 struct ifreq *ifr; 3177 struct ifaddr *ifa; /* XXX */ 3178 3179 vap = ifp->if_softc; 3180 if (vap == NULL) { 3181 /* 3182 * During detach we clear the backpointer in the softc 3183 * so any ioctl request through the ifnet that arrives 3184 * before teardown is ignored/rejected. In particular 3185 * this hack handles destroying a vap used by an app 3186 * like wpa_supplicant that will respond to the vap 3187 * being forced into INIT state by immediately trying 3188 * to force it back up. We can yank this hack if/when 3189 * we can destroy the ifnet before cleaning up vap state. 3190 */ 3191 return ENXIO; 3192 } 3193 switch (cmd) { 3194 case SIOCSIFFLAGS: 3195 ic = vap->iv_ic; 3196 IEEE80211_LOCK(ic); 3197 ieee80211_syncifflag_locked(ic, IFF_PROMISC); 3198 ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); 3199 if (ifp->if_flags & IFF_UP) { 3200 /* 3201 * Bring ourself up unless we're already operational. 3202 * If we're the first vap and the parent is not up 3203 * then it will automatically be brought up as a 3204 * side-effect of bringing ourself up. 3205 */ 3206 if (vap->iv_state == IEEE80211_S_INIT) 3207 ieee80211_start_locked(vap); 3208 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 3209 /* 3210 * Stop ourself. If we are the last vap to be 3211 * marked down the parent will also be taken down. 3212 */ 3213 ieee80211_stop_locked(vap); 3214 } 3215 IEEE80211_UNLOCK(ic); 3216 break; 3217 case SIOCADDMULTI: 3218 case SIOCDELMULTI: 3219 ieee80211_ioctl_updatemulti(vap->iv_ic); 3220 break; 3221 case SIOCSIFMEDIA: 3222 case SIOCGIFMEDIA: 3223 ifr = (struct ifreq *)data; 3224 error = ifmedia_ioctl(ifp, ifr, &vap->iv_media, cmd); 3225 break; 3226 case SIOCG80211: 3227 error = ieee80211_ioctl_get80211(vap, cmd, 3228 (struct ieee80211req *) data); 3229 break; 3230 case SIOCS80211: 3231 error = priv_check(curthread, PRIV_NET80211_MANAGE); 3232 if (error == 0) 3233 error = ieee80211_ioctl_set80211(vap, cmd, 3234 (struct ieee80211req *) data); 3235 break; 3236 case SIOCG80211STATS: 3237 ifr = (struct ifreq *)data; 3238 copyout(&vap->iv_stats, ifr->ifr_data, sizeof (vap->iv_stats)); 3239 break; 3240 case SIOCSIFMTU: 3241 ifr = (struct ifreq *)data; 3242 if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu && 3243 ifr->ifr_mtu <= IEEE80211_MTU_MAX)) 3244 error = EINVAL; 3245 else 3246 ifp->if_mtu = ifr->ifr_mtu; 3247 break; 3248 case SIOCSIFADDR: 3249 /* 3250 * XXX Handle this directly so we can supress if_init calls. 3251 * XXX This should be done in ether_ioctl but for the moment 3252 * XXX there are too many other parts of the system that 3253 * XXX set IFF_UP and so supress if_init being called when 3254 * XXX it should be. 3255 */ 3256 ifa = (struct ifaddr *) data; 3257 switch (ifa->ifa_addr->sa_family) { 3258#ifdef INET 3259 case AF_INET: 3260 if ((ifp->if_flags & IFF_UP) == 0) { 3261 ifp->if_flags |= IFF_UP; 3262 ifp->if_init(ifp->if_softc); 3263 } 3264 arp_ifinit(ifp, ifa); 3265 break; 3266#endif 3267#ifdef IPX 3268 /* 3269 * XXX - This code is probably wrong, 3270 * but has been copied many times. 3271 */ 3272 case AF_IPX: { 3273 struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 3274 3275 if (ipx_nullhost(*ina)) 3276 ina->x_host = *(union ipx_host *) 3277 IF_LLADDR(ifp); 3278 else 3279 bcopy((caddr_t) ina->x_host.c_host, 3280 (caddr_t) IF_LLADDR(ifp), 3281 ETHER_ADDR_LEN); 3282 /* fall thru... */ 3283 } 3284#endif 3285 default: 3286 if ((ifp->if_flags & IFF_UP) == 0) { 3287 ifp->if_flags |= IFF_UP; 3288 ifp->if_init(ifp->if_softc); 3289 } 3290 break; 3291 } 3292 break; 3293 /* Pass NDIS ioctls up to the driver */ 3294 case SIOCGDRVSPEC: 3295 case SIOCSDRVSPEC: 3296 case SIOCGPRIVATE_0: { 3297 struct ifnet *parent = vap->iv_ic->ic_ifp; 3298 error = parent->if_ioctl(parent, cmd, data); 3299 break; 3300 } 3301 default: 3302 error = ether_ioctl(ifp, cmd, data); 3303 break; 3304 } 3305 return error; 3306}
| 2162 return 0; 2163} 2164 2165static void 2166setwparsnie(struct ieee80211vap *vap, uint8_t *ie, int space) 2167{ 2168 /* validate data is present as best we can */ 2169 if (space == 0 || 2+ie[1] > space) 2170 return; 2171 if (ie[0] == IEEE80211_ELEMID_VENDOR) 2172 vap->iv_wpa_ie = ie; 2173 else if (ie[0] == IEEE80211_ELEMID_RSN) 2174 vap->iv_rsn_ie = ie; 2175} 2176 2177static __noinline int 2178ieee80211_ioctl_setappie_locked(struct ieee80211vap *vap, 2179 const struct ieee80211req *ireq, int fc0) 2180{ 2181 int error; 2182 2183 IEEE80211_LOCK_ASSERT(vap->iv_ic); 2184 2185 switch (fc0 & IEEE80211_FC0_SUBTYPE_MASK) { 2186 case IEEE80211_FC0_SUBTYPE_BEACON: 2187 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2188 vap->iv_opmode != IEEE80211_M_IBSS) { 2189 error = EINVAL; 2190 break; 2191 } 2192 error = setappie(&vap->iv_appie_beacon, ireq); 2193 if (error == 0) 2194 ieee80211_beacon_notify(vap, IEEE80211_BEACON_APPIE); 2195 break; 2196 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 2197 error = setappie(&vap->iv_appie_proberesp, ireq); 2198 break; 2199 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 2200 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2201 error = setappie(&vap->iv_appie_assocresp, ireq); 2202 else 2203 error = EINVAL; 2204 break; 2205 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 2206 error = setappie(&vap->iv_appie_probereq, ireq); 2207 break; 2208 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 2209 if (vap->iv_opmode == IEEE80211_M_STA) 2210 error = setappie(&vap->iv_appie_assocreq, ireq); 2211 else 2212 error = EINVAL; 2213 break; 2214 case (IEEE80211_APPIE_WPA & IEEE80211_FC0_SUBTYPE_MASK): 2215 error = setappie(&vap->iv_appie_wpa, ireq); 2216 if (error == 0) { 2217 /* 2218 * Must split single blob of data into separate 2219 * WPA and RSN ie's because they go in different 2220 * locations in the mgt frames. 2221 * XXX use IEEE80211_IOC_WPA2 so user code does split 2222 */ 2223 vap->iv_wpa_ie = NULL; 2224 vap->iv_rsn_ie = NULL; 2225 if (vap->iv_appie_wpa != NULL) { 2226 struct ieee80211_appie *appie = 2227 vap->iv_appie_wpa; 2228 uint8_t *data = appie->ie_data; 2229 2230 /* XXX ie length validate is painful, cheat */ 2231 setwparsnie(vap, data, appie->ie_len); 2232 setwparsnie(vap, data + 2 + data[1], 2233 appie->ie_len - (2 + data[1])); 2234 } 2235 if (vap->iv_opmode == IEEE80211_M_HOSTAP || 2236 vap->iv_opmode == IEEE80211_M_IBSS) { 2237 /* 2238 * Must rebuild beacon frame as the update 2239 * mechanism doesn't handle WPA/RSN ie's. 2240 * Could extend it but it doesn't normally 2241 * change; this is just to deal with hostapd 2242 * plumbing the ie after the interface is up. 2243 */ 2244 error = ENETRESET; 2245 } 2246 } 2247 break; 2248 default: 2249 error = EINVAL; 2250 break; 2251 } 2252 return error; 2253} 2254 2255static __noinline int 2256ieee80211_ioctl_setappie(struct ieee80211vap *vap, 2257 const struct ieee80211req *ireq) 2258{ 2259 struct ieee80211com *ic = vap->iv_ic; 2260 int error; 2261 uint8_t fc0; 2262 2263 fc0 = ireq->i_val & 0xff; 2264 if ((fc0 & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT) 2265 return EINVAL; 2266 /* NB: could check iv_opmode and reject but hardly worth the effort */ 2267 IEEE80211_LOCK(ic); 2268 error = ieee80211_ioctl_setappie_locked(vap, ireq, fc0); 2269 IEEE80211_UNLOCK(ic); 2270 return error; 2271} 2272 2273static __noinline int 2274ieee80211_ioctl_chanswitch(struct ieee80211vap *vap, struct ieee80211req *ireq) 2275{ 2276 struct ieee80211com *ic = vap->iv_ic; 2277 struct ieee80211_chanswitch_req csr; 2278 struct ieee80211_channel *c; 2279 int error; 2280 2281 if (ireq->i_len != sizeof(csr)) 2282 return EINVAL; 2283 error = copyin(ireq->i_data, &csr, sizeof(csr)); 2284 if (error != 0) 2285 return error; 2286 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 2287 return EINVAL; 2288 c = ieee80211_find_channel(ic, 2289 csr.csa_chan.ic_freq, csr.csa_chan.ic_flags); 2290 if (c == NULL) 2291 return ENOENT; 2292 IEEE80211_LOCK(ic); 2293 if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) 2294 ieee80211_csa_startswitch(ic, c, csr.csa_mode, csr.csa_count); 2295 else 2296 error = EBUSY; 2297 IEEE80211_UNLOCK(ic); 2298 return error; 2299} 2300 2301static __noinline int 2302ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq) 2303{ 2304#define IEEE80211_IOC_SCAN_FLAGS \ 2305 (IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \ 2306 IEEE80211_IOC_SCAN_PICK1ST | IEEE80211_IOC_SCAN_BGSCAN | \ 2307 IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOBCAST | \ 2308 IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \ 2309 IEEE80211_IOC_SCAN_CHECK) 2310 struct ieee80211com *ic = vap->iv_ic; 2311 struct ieee80211_scan_req sr; /* XXX off stack? */ 2312 int error, i; 2313 2314 /* NB: parent must be running */ 2315 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 2316 return ENXIO; 2317 2318 if (ireq->i_len != sizeof(sr)) 2319 return EINVAL; 2320 error = copyin(ireq->i_data, &sr, sizeof(sr)); 2321 if (error != 0) 2322 return error; 2323 /* convert duration */ 2324 if (sr.sr_duration == IEEE80211_IOC_SCAN_FOREVER) 2325 sr.sr_duration = IEEE80211_SCAN_FOREVER; 2326 else { 2327 if (sr.sr_duration < IEEE80211_IOC_SCAN_DURATION_MIN || 2328 sr.sr_duration > IEEE80211_IOC_SCAN_DURATION_MAX) 2329 return EINVAL; 2330 sr.sr_duration = msecs_to_ticks(sr.sr_duration); 2331 if (sr.sr_duration < 1) 2332 sr.sr_duration = 1; 2333 } 2334 /* convert min/max channel dwell */ 2335 if (sr.sr_mindwell != 0) { 2336 sr.sr_mindwell = msecs_to_ticks(sr.sr_mindwell); 2337 if (sr.sr_mindwell < 1) 2338 sr.sr_mindwell = 1; 2339 } 2340 if (sr.sr_maxdwell != 0) { 2341 sr.sr_maxdwell = msecs_to_ticks(sr.sr_maxdwell); 2342 if (sr.sr_maxdwell < 1) 2343 sr.sr_maxdwell = 1; 2344 } 2345 /* NB: silently reduce ssid count to what is supported */ 2346 if (sr.sr_nssid > IEEE80211_SCAN_MAX_SSID) 2347 sr.sr_nssid = IEEE80211_SCAN_MAX_SSID; 2348 for (i = 0; i < sr.sr_nssid; i++) 2349 if (sr.sr_ssid[i].len > IEEE80211_NWID_LEN) 2350 return EINVAL; 2351 /* cleanse flags just in case, could reject if invalid flags */ 2352 sr.sr_flags &= IEEE80211_IOC_SCAN_FLAGS; 2353 /* 2354 * Add an implicit NOPICK if the vap is not marked UP. This 2355 * allows applications to scan without joining a bss (or picking 2356 * a channel and setting up a bss) and without forcing manual 2357 * roaming mode--you just need to mark the parent device UP. 2358 */ 2359 if ((vap->iv_ifp->if_flags & IFF_UP) == 0) 2360 sr.sr_flags |= IEEE80211_IOC_SCAN_NOPICK; 2361 2362 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2363 "%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n", 2364 __func__, sr.sr_flags, 2365 (vap->iv_ifp->if_flags & IFF_UP) == 0 ? " (!IFF_UP)" : "", 2366 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, sr.sr_nssid); 2367 /* 2368 * If we are in INIT state then the driver has never had a chance 2369 * to setup hardware state to do a scan; we must use the state 2370 * machine to get us up to the SCAN state but once we reach SCAN 2371 * state we then want to use the supplied params. Stash the 2372 * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the 2373 * state machines will recognize this and use the stashed params 2374 * to issue the scan request. 2375 * 2376 * Otherwise just invoke the scan machinery directly. 2377 */ 2378 IEEE80211_LOCK(ic); 2379 if (vap->iv_state == IEEE80211_S_INIT) { 2380 /* NB: clobbers previous settings */ 2381 vap->iv_scanreq_flags = sr.sr_flags; 2382 vap->iv_scanreq_duration = sr.sr_duration; 2383 vap->iv_scanreq_nssid = sr.sr_nssid; 2384 for (i = 0; i < sr.sr_nssid; i++) { 2385 vap->iv_scanreq_ssid[i].len = sr.sr_ssid[i].len; 2386 memcpy(vap->iv_scanreq_ssid[i].ssid, sr.sr_ssid[i].ssid, 2387 sr.sr_ssid[i].len); 2388 } 2389 vap->iv_flags_ext |= IEEE80211_FEXT_SCANREQ; 2390 IEEE80211_UNLOCK(ic); 2391 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2392 } else { 2393 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; 2394 IEEE80211_UNLOCK(ic); 2395 /* XXX neeed error return codes */ 2396 if (sr.sr_flags & IEEE80211_IOC_SCAN_CHECK) { 2397 (void) ieee80211_check_scan(vap, sr.sr_flags, 2398 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2399 sr.sr_nssid, 2400 /* NB: cheat, we assume structures are compatible */ 2401 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2402 } else { 2403 (void) ieee80211_start_scan(vap, sr.sr_flags, 2404 sr.sr_duration, sr.sr_mindwell, sr.sr_maxdwell, 2405 sr.sr_nssid, 2406 /* NB: cheat, we assume structures are compatible */ 2407 (const struct ieee80211_scan_ssid *) &sr.sr_ssid[0]); 2408 } 2409 } 2410 return error; 2411#undef IEEE80211_IOC_SCAN_FLAGS 2412} 2413 2414static __noinline int 2415ieee80211_ioctl_setstavlan(struct ieee80211vap *vap, struct ieee80211req *ireq) 2416{ 2417 struct ieee80211_node *ni; 2418 struct ieee80211req_sta_vlan vlan; 2419 int error; 2420 2421 if (ireq->i_len != sizeof(vlan)) 2422 return EINVAL; 2423 error = copyin(ireq->i_data, &vlan, sizeof(vlan)); 2424 if (error != 0) 2425 return error; 2426 if (!IEEE80211_ADDR_EQ(vlan.sv_macaddr, zerobssid)) { 2427 ni = ieee80211_find_vap_node(&vap->iv_ic->ic_sta, vap, 2428 vlan.sv_macaddr); 2429 if (ni == NULL) 2430 return ENOENT; 2431 } else 2432 ni = ieee80211_ref_node(vap->iv_bss); 2433 ni->ni_vlan = vlan.sv_vlan; 2434 ieee80211_free_node(ni); 2435 return error; 2436} 2437 2438static int 2439isvap11g(const struct ieee80211vap *vap) 2440{ 2441 const struct ieee80211_node *bss = vap->iv_bss; 2442 return bss->ni_chan != IEEE80211_CHAN_ANYC && 2443 IEEE80211_IS_CHAN_ANYG(bss->ni_chan); 2444} 2445 2446static int 2447isvapht(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_HT(bss->ni_chan); 2452} 2453 2454static __noinline int 2455ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211req *ireq) 2456{ 2457 struct ieee80211com *ic = vap->iv_ic; 2458 int error; 2459 const struct ieee80211_authenticator *auth; 2460 uint8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 2461 char tmpssid[IEEE80211_NWID_LEN]; 2462 uint8_t tmpbssid[IEEE80211_ADDR_LEN]; 2463 struct ieee80211_key *k; 2464 u_int kid; 2465 uint32_t flags; 2466 2467 error = 0; 2468 switch (ireq->i_type) { 2469 case IEEE80211_IOC_SSID: 2470 if (ireq->i_val != 0 || 2471 ireq->i_len > IEEE80211_NWID_LEN) 2472 return EINVAL; 2473 error = copyin(ireq->i_data, tmpssid, ireq->i_len); 2474 if (error) 2475 break; 2476 memset(vap->iv_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN); 2477 vap->iv_des_ssid[0].len = ireq->i_len; 2478 memcpy(vap->iv_des_ssid[0].ssid, tmpssid, ireq->i_len); 2479 vap->iv_des_nssid = (ireq->i_len > 0); 2480 error = ENETRESET; 2481 break; 2482 case IEEE80211_IOC_WEP: 2483 switch (ireq->i_val) { 2484 case IEEE80211_WEP_OFF: 2485 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2486 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2487 break; 2488 case IEEE80211_WEP_ON: 2489 vap->iv_flags |= IEEE80211_F_PRIVACY; 2490 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2491 break; 2492 case IEEE80211_WEP_MIXED: 2493 vap->iv_flags |= IEEE80211_F_PRIVACY; 2494 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2495 break; 2496 } 2497 error = ENETRESET; 2498 break; 2499 case IEEE80211_IOC_WEPKEY: 2500 kid = (u_int) ireq->i_val; 2501 if (kid >= IEEE80211_WEP_NKID) 2502 return EINVAL; 2503 k = &vap->iv_nw_keys[kid]; 2504 if (ireq->i_len == 0) { 2505 /* zero-len =>'s delete any existing key */ 2506 (void) ieee80211_crypto_delkey(vap, k); 2507 break; 2508 } 2509 if (ireq->i_len > sizeof(tmpkey)) 2510 return EINVAL; 2511 memset(tmpkey, 0, sizeof(tmpkey)); 2512 error = copyin(ireq->i_data, tmpkey, ireq->i_len); 2513 if (error) 2514 break; 2515 ieee80211_key_update_begin(vap); 2516 k->wk_keyix = kid; /* NB: force fixed key id */ 2517 if (ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP, 2518 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) { 2519 k->wk_keylen = ireq->i_len; 2520 memcpy(k->wk_key, tmpkey, sizeof(tmpkey)); 2521 IEEE80211_ADDR_COPY(k->wk_macaddr, vap->iv_myaddr); 2522 if (!ieee80211_crypto_setkey(vap, k)) 2523 error = EINVAL; 2524 } else 2525 error = EINVAL; 2526 ieee80211_key_update_end(vap); 2527 break; 2528 case IEEE80211_IOC_WEPTXKEY: 2529 kid = (u_int) ireq->i_val; 2530 if (kid >= IEEE80211_WEP_NKID && 2531 (uint16_t) kid != IEEE80211_KEYIX_NONE) 2532 return EINVAL; 2533 vap->iv_def_txkey = kid; 2534 break; 2535 case IEEE80211_IOC_AUTHMODE: 2536 switch (ireq->i_val) { 2537 case IEEE80211_AUTH_WPA: 2538 case IEEE80211_AUTH_8021X: /* 802.1x */ 2539 case IEEE80211_AUTH_OPEN: /* open */ 2540 case IEEE80211_AUTH_SHARED: /* shared-key */ 2541 case IEEE80211_AUTH_AUTO: /* auto */ 2542 auth = ieee80211_authenticator_get(ireq->i_val); 2543 if (auth == NULL) 2544 return EINVAL; 2545 break; 2546 default: 2547 return EINVAL; 2548 } 2549 switch (ireq->i_val) { 2550 case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ 2551 vap->iv_flags |= IEEE80211_F_PRIVACY; 2552 ireq->i_val = IEEE80211_AUTH_8021X; 2553 break; 2554 case IEEE80211_AUTH_OPEN: /* open */ 2555 vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY); 2556 break; 2557 case IEEE80211_AUTH_SHARED: /* shared-key */ 2558 case IEEE80211_AUTH_8021X: /* 802.1x */ 2559 vap->iv_flags &= ~IEEE80211_F_WPA; 2560 /* both require a key so mark the PRIVACY capability */ 2561 vap->iv_flags |= IEEE80211_F_PRIVACY; 2562 break; 2563 case IEEE80211_AUTH_AUTO: /* auto */ 2564 vap->iv_flags &= ~IEEE80211_F_WPA; 2565 /* XXX PRIVACY handling? */ 2566 /* XXX what's the right way to do this? */ 2567 break; 2568 } 2569 /* NB: authenticator attach/detach happens on state change */ 2570 vap->iv_bss->ni_authmode = ireq->i_val; 2571 /* XXX mixed/mode/usage? */ 2572 vap->iv_auth = auth; 2573 error = ENETRESET; 2574 break; 2575 case IEEE80211_IOC_CHANNEL: 2576 error = ieee80211_ioctl_setchannel(vap, ireq); 2577 break; 2578 case IEEE80211_IOC_POWERSAVE: 2579 switch (ireq->i_val) { 2580 case IEEE80211_POWERSAVE_OFF: 2581 if (vap->iv_flags & IEEE80211_F_PMGTON) { 2582 ieee80211_syncflag(vap, -IEEE80211_F_PMGTON); 2583 error = ERESTART; 2584 } 2585 break; 2586 case IEEE80211_POWERSAVE_ON: 2587 if ((vap->iv_caps & IEEE80211_C_PMGT) == 0) 2588 error = EOPNOTSUPP; 2589 else if ((vap->iv_flags & IEEE80211_F_PMGTON) == 0) { 2590 ieee80211_syncflag(vap, IEEE80211_F_PMGTON); 2591 error = ERESTART; 2592 } 2593 break; 2594 default: 2595 error = EINVAL; 2596 break; 2597 } 2598 break; 2599 case IEEE80211_IOC_POWERSAVESLEEP: 2600 if (ireq->i_val < 0) 2601 return EINVAL; 2602 ic->ic_lintval = ireq->i_val; 2603 error = ERESTART; 2604 break; 2605 case IEEE80211_IOC_RTSTHRESHOLD: 2606 if (!(IEEE80211_RTS_MIN <= ireq->i_val && 2607 ireq->i_val <= IEEE80211_RTS_MAX)) 2608 return EINVAL; 2609 vap->iv_rtsthreshold = ireq->i_val; 2610 error = ERESTART; 2611 break; 2612 case IEEE80211_IOC_PROTMODE: 2613 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 2614 return EINVAL; 2615 ic->ic_protmode = ireq->i_val; 2616 /* NB: if not operating in 11g this can wait */ 2617 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && 2618 IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) 2619 error = ERESTART; 2620 break; 2621 case IEEE80211_IOC_TXPOWER: 2622 if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) 2623 return EOPNOTSUPP; 2624 if (!(IEEE80211_TXPOWER_MIN <= ireq->i_val && 2625 ireq->i_val <= IEEE80211_TXPOWER_MAX)) 2626 return EINVAL; 2627 ic->ic_txpowlimit = ireq->i_val; 2628 error = ERESTART; 2629 break; 2630 case IEEE80211_IOC_ROAMING: 2631 if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val && 2632 ireq->i_val <= IEEE80211_ROAMING_MANUAL)) 2633 return EINVAL; 2634 vap->iv_roaming = ireq->i_val; 2635 /* XXXX reset? */ 2636 break; 2637 case IEEE80211_IOC_PRIVACY: 2638 if (ireq->i_val) { 2639 /* XXX check for key state? */ 2640 vap->iv_flags |= IEEE80211_F_PRIVACY; 2641 } else 2642 vap->iv_flags &= ~IEEE80211_F_PRIVACY; 2643 /* XXX ERESTART? */ 2644 break; 2645 case IEEE80211_IOC_DROPUNENCRYPTED: 2646 if (ireq->i_val) 2647 vap->iv_flags |= IEEE80211_F_DROPUNENC; 2648 else 2649 vap->iv_flags &= ~IEEE80211_F_DROPUNENC; 2650 /* XXX ERESTART? */ 2651 break; 2652 case IEEE80211_IOC_WPAKEY: 2653 error = ieee80211_ioctl_setkey(vap, ireq); 2654 break; 2655 case IEEE80211_IOC_DELKEY: 2656 error = ieee80211_ioctl_delkey(vap, ireq); 2657 break; 2658 case IEEE80211_IOC_MLME: 2659 error = ieee80211_ioctl_setmlme(vap, ireq); 2660 break; 2661 case IEEE80211_IOC_COUNTERMEASURES: 2662 if (ireq->i_val) { 2663 if ((vap->iv_flags & IEEE80211_F_WPA) == 0) 2664 return EOPNOTSUPP; 2665 vap->iv_flags |= IEEE80211_F_COUNTERM; 2666 } else 2667 vap->iv_flags &= ~IEEE80211_F_COUNTERM; 2668 /* XXX ERESTART? */ 2669 break; 2670 case IEEE80211_IOC_WPA: 2671 if (ireq->i_val > 3) 2672 return EINVAL; 2673 /* XXX verify ciphers available */ 2674 flags = vap->iv_flags & ~IEEE80211_F_WPA; 2675 switch (ireq->i_val) { 2676 case 1: 2677 if (!(vap->iv_caps & IEEE80211_C_WPA1)) 2678 return EOPNOTSUPP; 2679 flags |= IEEE80211_F_WPA1; 2680 break; 2681 case 2: 2682 if (!(vap->iv_caps & IEEE80211_C_WPA2)) 2683 return EOPNOTSUPP; 2684 flags |= IEEE80211_F_WPA2; 2685 break; 2686 case 3: 2687 if ((vap->iv_caps & IEEE80211_C_WPA) != IEEE80211_C_WPA) 2688 flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; 2689 break; 2690 default: /* Can't set any -> error */ 2691 return EOPNOTSUPP; 2692 } 2693 vap->iv_flags = flags; 2694 error = ERESTART; /* NB: can change beacon frame */ 2695 break; 2696 case IEEE80211_IOC_WME: 2697 if (ireq->i_val) { 2698 if ((vap->iv_caps & IEEE80211_C_WME) == 0) 2699 return EOPNOTSUPP; 2700 ieee80211_syncflag(vap, IEEE80211_F_WME); 2701 } else 2702 ieee80211_syncflag(vap, -IEEE80211_F_WME); 2703 error = ERESTART; /* NB: can change beacon frame */ 2704 break; 2705 case IEEE80211_IOC_HIDESSID: 2706 if (ireq->i_val) 2707 vap->iv_flags |= IEEE80211_F_HIDESSID; 2708 else 2709 vap->iv_flags &= ~IEEE80211_F_HIDESSID; 2710 error = ERESTART; /* XXX ENETRESET? */ 2711 break; 2712 case IEEE80211_IOC_APBRIDGE: 2713 if (ireq->i_val == 0) 2714 vap->iv_flags |= IEEE80211_F_NOBRIDGE; 2715 else 2716 vap->iv_flags &= ~IEEE80211_F_NOBRIDGE; 2717 break; 2718 case IEEE80211_IOC_BSSID: 2719 if (ireq->i_len != sizeof(tmpbssid)) 2720 return EINVAL; 2721 error = copyin(ireq->i_data, tmpbssid, ireq->i_len); 2722 if (error) 2723 break; 2724 IEEE80211_ADDR_COPY(vap->iv_des_bssid, tmpbssid); 2725 if (IEEE80211_ADDR_EQ(vap->iv_des_bssid, zerobssid)) 2726 vap->iv_flags &= ~IEEE80211_F_DESBSSID; 2727 else 2728 vap->iv_flags |= IEEE80211_F_DESBSSID; 2729 error = ENETRESET; 2730 break; 2731 case IEEE80211_IOC_CHANLIST: 2732 error = ieee80211_ioctl_setchanlist(vap, ireq); 2733 break; 2734#define OLD_IEEE80211_IOC_SCAN_REQ 23 2735#ifdef OLD_IEEE80211_IOC_SCAN_REQ 2736 case OLD_IEEE80211_IOC_SCAN_REQ: 2737 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2738 "%s: active scan request\n", __func__); 2739 /* 2740 * If we are in INIT state then the driver has never 2741 * had a chance to setup hardware state to do a scan; 2742 * use the state machine to get us up the SCAN state. 2743 * Otherwise just invoke the scan machinery to start 2744 * a one-time scan. 2745 */ 2746 if (vap->iv_state == IEEE80211_S_INIT) 2747 ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); 2748 else 2749 (void) ieee80211_start_scan(vap, 2750 IEEE80211_SCAN_ACTIVE | 2751 IEEE80211_SCAN_NOPICK | 2752 IEEE80211_SCAN_ONCE, 2753 IEEE80211_SCAN_FOREVER, 0, 0, 2754 /* XXX use ioctl params */ 2755 vap->iv_des_nssid, vap->iv_des_ssid); 2756 break; 2757#endif /* OLD_IEEE80211_IOC_SCAN_REQ */ 2758 case IEEE80211_IOC_SCAN_REQ: 2759 error = ieee80211_ioctl_scanreq(vap, ireq); 2760 break; 2761 case IEEE80211_IOC_SCAN_CANCEL: 2762 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, 2763 "%s: cancel scan\n", __func__); 2764 ieee80211_cancel_scan(vap); 2765 break; 2766 case IEEE80211_IOC_HTCONF: 2767 if (ireq->i_val & 1) 2768 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_HT); 2769 else 2770 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_HT); 2771 if (ireq->i_val & 2) 2772 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_USEHT40); 2773 else 2774 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_USEHT40); 2775 error = ENETRESET; 2776 break; 2777 case IEEE80211_IOC_ADDMAC: 2778 case IEEE80211_IOC_DELMAC: 2779 error = ieee80211_ioctl_macmac(vap, ireq); 2780 break; 2781 case IEEE80211_IOC_MACCMD: 2782 error = ieee80211_ioctl_setmaccmd(vap, ireq); 2783 break; 2784 case IEEE80211_IOC_STA_STATS: 2785 error = ieee80211_ioctl_setstastats(vap, ireq); 2786 break; 2787 case IEEE80211_IOC_STA_TXPOW: 2788 error = ieee80211_ioctl_setstatxpow(vap, ireq); 2789 break; 2790 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2791 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2792 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2793 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2794 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2795 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 2796 error = ieee80211_ioctl_setwmeparam(vap, ireq); 2797 break; 2798 case IEEE80211_IOC_DTIM_PERIOD: 2799 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2800 vap->iv_opmode != IEEE80211_M_IBSS) 2801 return EINVAL; 2802 if (IEEE80211_DTIM_MIN <= ireq->i_val && 2803 ireq->i_val <= IEEE80211_DTIM_MAX) { 2804 vap->iv_dtim_period = ireq->i_val; 2805 error = ENETRESET; /* requires restart */ 2806 } else 2807 error = EINVAL; 2808 break; 2809 case IEEE80211_IOC_BEACON_INTERVAL: 2810 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 2811 vap->iv_opmode != IEEE80211_M_IBSS) 2812 return EINVAL; 2813 if (IEEE80211_BINTVAL_MIN <= ireq->i_val && 2814 ireq->i_val <= IEEE80211_BINTVAL_MAX) { 2815 ic->ic_bintval = ireq->i_val; 2816 error = ENETRESET; /* requires restart */ 2817 } else 2818 error = EINVAL; 2819 break; 2820 case IEEE80211_IOC_PUREG: 2821 if (ireq->i_val) 2822 vap->iv_flags |= IEEE80211_F_PUREG; 2823 else 2824 vap->iv_flags &= ~IEEE80211_F_PUREG; 2825 /* NB: reset only if we're operating on an 11g channel */ 2826 if (isvap11g(vap)) 2827 error = ENETRESET; 2828 break; 2829 case IEEE80211_IOC_FF: 2830 if (ireq->i_val) { 2831 if ((vap->iv_caps & IEEE80211_C_FF) == 0) 2832 return EOPNOTSUPP; 2833 vap->iv_flags |= IEEE80211_F_FF; 2834 } else 2835 vap->iv_flags &= ~IEEE80211_F_FF; 2836 error = ERESTART; 2837 break; 2838 case IEEE80211_IOC_TURBOP: 2839 if (ireq->i_val) { 2840 if ((vap->iv_caps & IEEE80211_C_TURBOP) == 0) 2841 return EOPNOTSUPP; 2842 vap->iv_flags |= IEEE80211_F_TURBOP; 2843 } else 2844 vap->iv_flags &= ~IEEE80211_F_TURBOP; 2845 error = ENETRESET; 2846 break; 2847 case IEEE80211_IOC_BGSCAN: 2848 if (ireq->i_val) { 2849 if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0) 2850 return EOPNOTSUPP; 2851 vap->iv_flags |= IEEE80211_F_BGSCAN; 2852 } else 2853 vap->iv_flags &= ~IEEE80211_F_BGSCAN; 2854 break; 2855 case IEEE80211_IOC_BGSCAN_IDLE: 2856 if (ireq->i_val >= IEEE80211_BGSCAN_IDLE_MIN) 2857 vap->iv_bgscanidle = ireq->i_val*hz/1000; 2858 else 2859 error = EINVAL; 2860 break; 2861 case IEEE80211_IOC_BGSCAN_INTERVAL: 2862 if (ireq->i_val >= IEEE80211_BGSCAN_INTVAL_MIN) 2863 vap->iv_bgscanintvl = ireq->i_val*hz; 2864 else 2865 error = EINVAL; 2866 break; 2867 case IEEE80211_IOC_SCANVALID: 2868 if (ireq->i_val >= IEEE80211_SCAN_VALID_MIN) 2869 vap->iv_scanvalid = ireq->i_val*hz; 2870 else 2871 error = EINVAL; 2872 break; 2873 case IEEE80211_IOC_FRAGTHRESHOLD: 2874 if ((vap->iv_caps & IEEE80211_C_TXFRAG) == 0 && 2875 ireq->i_val != IEEE80211_FRAG_MAX) 2876 return EOPNOTSUPP; 2877 if (!(IEEE80211_FRAG_MIN <= ireq->i_val && 2878 ireq->i_val <= IEEE80211_FRAG_MAX)) 2879 return EINVAL; 2880 vap->iv_fragthreshold = ireq->i_val; 2881 error = ERESTART; 2882 break; 2883 case IEEE80211_IOC_BURST: 2884 if (ireq->i_val) { 2885 if ((vap->iv_caps & IEEE80211_C_BURST) == 0) 2886 return EOPNOTSUPP; 2887 ieee80211_syncflag(vap, IEEE80211_F_BURST); 2888 } else 2889 ieee80211_syncflag(vap, -IEEE80211_F_BURST); 2890 error = ERESTART; 2891 break; 2892 case IEEE80211_IOC_BMISSTHRESHOLD: 2893 if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val && 2894 ireq->i_val <= IEEE80211_HWBMISS_MAX)) 2895 return EINVAL; 2896 vap->iv_bmissthreshold = ireq->i_val; 2897 error = ERESTART; 2898 break; 2899 case IEEE80211_IOC_CURCHAN: 2900 error = ieee80211_ioctl_setcurchan(vap, ireq); 2901 break; 2902 case IEEE80211_IOC_SHORTGI: 2903 if (ireq->i_val) { 2904#define IEEE80211_HTCAP_SHORTGI \ 2905 (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40) 2906 if (((ireq->i_val ^ vap->iv_htcaps) & IEEE80211_HTCAP_SHORTGI) != 0) 2907 return EINVAL; 2908 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI20) 2909 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI20; 2910 if (ireq->i_val & IEEE80211_HTCAP_SHORTGI40) 2911 vap->iv_flags_ext |= IEEE80211_FEXT_SHORTGI40; 2912#undef IEEE80211_HTCAP_SHORTGI 2913 } else 2914 vap->iv_flags_ext &= 2915 ~(IEEE80211_FEXT_SHORTGI20 | IEEE80211_FEXT_SHORTGI40); 2916 error = ERESTART; 2917 break; 2918 case IEEE80211_IOC_AMPDU: 2919 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0) 2920 return EINVAL; 2921 if (ireq->i_val & 1) 2922 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_TX; 2923 else 2924 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_TX; 2925 if (ireq->i_val & 2) 2926 vap->iv_flags_ext |= IEEE80211_FEXT_AMPDU_RX; 2927 else 2928 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_RX; 2929 /* NB: reset only if we're operating on an 11n channel */ 2930 if (isvapht(vap)) 2931 error = ERESTART; 2932 break; 2933 case IEEE80211_IOC_AMPDU_LIMIT: 2934 if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val && 2935 ireq->i_val <= IEEE80211_HTCAP_MAXRXAMPDU_64K)) 2936 return EINVAL; 2937 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 2938 vap->iv_ampdu_rxmax = ireq->i_val; 2939 else 2940 vap->iv_ampdu_limit = ireq->i_val; 2941 error = ERESTART; 2942 break; 2943 case IEEE80211_IOC_AMPDU_DENSITY: 2944 if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val && 2945 ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16)) 2946 return EINVAL; 2947 vap->iv_ampdu_density = ireq->i_val; 2948 error = ERESTART; 2949 break; 2950 case IEEE80211_IOC_AMSDU: 2951 if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0) 2952 return EINVAL; 2953 if (ireq->i_val & 1) 2954 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_TX; 2955 else 2956 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_TX; 2957 if (ireq->i_val & 2) 2958 vap->iv_flags_ext |= IEEE80211_FEXT_AMSDU_RX; 2959 else 2960 vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_RX; 2961 /* NB: reset only if we're operating on an 11n channel */ 2962 if (isvapht(vap)) 2963 error = ERESTART; 2964 break; 2965 case IEEE80211_IOC_AMSDU_LIMIT: 2966 /* XXX validate */ 2967 vap->iv_amsdu_limit = ireq->i_val; /* XXX truncation? */ 2968 break; 2969 case IEEE80211_IOC_PUREN: 2970 if (ireq->i_val) { 2971 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 2972 return EINVAL; 2973 vap->iv_flags_ext |= IEEE80211_FEXT_PUREN; 2974 } else 2975 vap->iv_flags_ext &= ~IEEE80211_FEXT_PUREN; 2976 /* NB: reset only if we're operating on an 11n channel */ 2977 if (isvapht(vap)) 2978 error = ERESTART; 2979 break; 2980 case IEEE80211_IOC_DOTH: 2981 if (ireq->i_val) { 2982#if 0 2983 /* XXX no capability */ 2984 if ((vap->iv_caps & IEEE80211_C_DOTH) == 0) 2985 return EOPNOTSUPP; 2986#endif 2987 vap->iv_flags |= IEEE80211_F_DOTH; 2988 } else 2989 vap->iv_flags &= ~IEEE80211_F_DOTH; 2990 error = ENETRESET; 2991 break; 2992 case IEEE80211_IOC_REGDOMAIN: 2993 error = ieee80211_ioctl_setregdomain(vap, ireq); 2994 break; 2995 case IEEE80211_IOC_ROAM: 2996 error = ieee80211_ioctl_setroam(vap, ireq); 2997 break; 2998 case IEEE80211_IOC_TXPARAMS: 2999 error = ieee80211_ioctl_settxparams(vap, ireq); 3000 break; 3001 case IEEE80211_IOC_HTCOMPAT: 3002 if (ireq->i_val) { 3003 if ((vap->iv_flags_ext & IEEE80211_FEXT_HT) == 0) 3004 return EOPNOTSUPP; 3005 vap->iv_flags_ext |= IEEE80211_FEXT_HTCOMPAT; 3006 } else 3007 vap->iv_flags_ext &= ~IEEE80211_FEXT_HTCOMPAT; 3008 /* NB: reset only if we're operating on an 11n channel */ 3009 if (isvapht(vap)) 3010 error = ERESTART; 3011 break; 3012 case IEEE80211_IOC_DWDS: 3013 if (ireq->i_val) { 3014 /* NB: DWDS only makes sense for WDS-capable devices */ 3015 if ((ic->ic_caps & IEEE80211_C_WDS) == 0) 3016 return EOPNOTSUPP; 3017 /* NB: DWDS is used only with ap+sta vaps */ 3018 if (vap->iv_opmode != IEEE80211_M_HOSTAP && 3019 vap->iv_opmode != IEEE80211_M_STA) 3020 return EINVAL; 3021 vap->iv_flags |= IEEE80211_F_DWDS; 3022 } else 3023 vap->iv_flags &= ~IEEE80211_F_DWDS; 3024 break; 3025 case IEEE80211_IOC_INACTIVITY: 3026 if (ireq->i_val) 3027 vap->iv_flags_ext |= IEEE80211_FEXT_INACT; 3028 else 3029 vap->iv_flags_ext &= ~IEEE80211_FEXT_INACT; 3030 break; 3031 case IEEE80211_IOC_APPIE: 3032 error = ieee80211_ioctl_setappie(vap, ireq); 3033 break; 3034 case IEEE80211_IOC_WPS: 3035 if (ireq->i_val) { 3036 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3037 return EOPNOTSUPP; 3038 vap->iv_flags_ext |= IEEE80211_FEXT_WPS; 3039 } else 3040 vap->iv_flags_ext &= ~IEEE80211_FEXT_WPS; 3041 break; 3042 case IEEE80211_IOC_TSN: 3043 if (ireq->i_val) { 3044 if ((vap->iv_caps & IEEE80211_C_WPA) == 0) 3045 return EOPNOTSUPP; 3046 vap->iv_flags_ext |= IEEE80211_FEXT_TSN; 3047 } else 3048 vap->iv_flags_ext &= ~IEEE80211_FEXT_TSN; 3049 break; 3050 case IEEE80211_IOC_CHANSWITCH: 3051 error = ieee80211_ioctl_chanswitch(vap, ireq); 3052 break; 3053 case IEEE80211_IOC_DFS: 3054 if (ireq->i_val) { 3055 if ((vap->iv_caps & IEEE80211_C_DFS) == 0) 3056 return EOPNOTSUPP; 3057 /* NB: DFS requires 11h support */ 3058 if ((vap->iv_flags & IEEE80211_F_DOTH) == 0) 3059 return EINVAL; 3060 vap->iv_flags_ext |= IEEE80211_FEXT_DFS; 3061 } else 3062 vap->iv_flags_ext &= ~IEEE80211_FEXT_DFS; 3063 break; 3064 case IEEE80211_IOC_DOTD: 3065 if (ireq->i_val) 3066 vap->iv_flags_ext |= IEEE80211_FEXT_DOTD; 3067 else 3068 vap->iv_flags_ext &= ~IEEE80211_FEXT_DOTD; 3069 if (vap->iv_opmode == IEEE80211_M_STA) 3070 error = ENETRESET; 3071 break; 3072 case IEEE80211_IOC_HTPROTMODE: 3073 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 3074 return EINVAL; 3075 ic->ic_htprotmode = ireq->i_val ? 3076 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_NONE; 3077 /* NB: if not operating in 11n this can wait */ 3078 if (isvapht(vap)) 3079 error = ERESTART; 3080 break; 3081 case IEEE80211_IOC_STA_VLAN: 3082 error = ieee80211_ioctl_setstavlan(vap, ireq); 3083 break; 3084 case IEEE80211_IOC_SMPS: 3085 if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 || 3086 ireq->i_val == 0x0008) /* value of 2 is reserved */ 3087 return EINVAL; 3088 if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF && 3089 (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0) 3090 return EOPNOTSUPP; 3091 vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) | 3092 ireq->i_val; 3093 /* NB: if not operating in 11n this can wait */ 3094 if (isvapht(vap)) 3095 error = ERESTART; 3096 break; 3097 case IEEE80211_IOC_RIFS: 3098 if (ireq->i_val != 0) { 3099 if ((vap->iv_htcaps & IEEE80211_HTC_RIFS) == 0) 3100 return EOPNOTSUPP; 3101 vap->iv_flags_ext |= IEEE80211_FEXT_RIFS; 3102 } else 3103 vap->iv_flags_ext &= ~IEEE80211_FEXT_RIFS; 3104 /* NB: if not operating in 11n this can wait */ 3105 if (isvapht(vap)) 3106 error = ERESTART; 3107 break; 3108 default: 3109 error = EINVAL; 3110 break; 3111 } 3112 /* 3113 * The convention is that ENETRESET means an operation 3114 * requires a complete re-initialization of the device (e.g. 3115 * changing something that affects the association state). 3116 * ERESTART means the request may be handled with only a 3117 * reload of the hardware state. We hand ERESTART requests 3118 * to the iv_reset callback so the driver can decide. If 3119 * a device does not fillin iv_reset then it defaults to one 3120 * that returns ENETRESET. Otherwise a driver may return 3121 * ENETRESET (in which case a full reset will be done) or 3122 * 0 to mean there's no need to do anything (e.g. when the 3123 * change has no effect on the driver/device). 3124 */ 3125 if (error == ERESTART) 3126 error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ? 3127 vap->iv_reset(vap, ireq->i_type) : 0; 3128 if (error == ENETRESET) { 3129 /* XXX need to re-think AUTO handling */ 3130 if (IS_UP_AUTO(vap)) 3131 ieee80211_init(vap); 3132 error = 0; 3133 } 3134 return error; 3135} 3136 3137/* 3138 * Rebuild the parent's multicast address list after an add/del 3139 * of a multicast address for a vap. We have no way to tell 3140 * what happened above to optimize the work so we purge the entire 3141 * list and rebuild from scratch. This is way expensive. 3142 * Note also the half-baked workaround for if_addmulti calling 3143 * back to the parent device; there's no way to insert mcast 3144 * entries quietly and/or cheaply. 3145 */ 3146static void 3147ieee80211_ioctl_updatemulti(struct ieee80211com *ic) 3148{ 3149 struct ifnet *parent = ic->ic_ifp; 3150 struct ieee80211vap *vap; 3151 void *ioctl; 3152 3153 IEEE80211_LOCK(ic); 3154 if_purgemaddrs(parent); 3155 ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */ 3156 parent->if_ioctl = NULL; 3157 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 3158 struct ifnet *ifp = vap->iv_ifp; 3159 struct ifmultiaddr *ifma; 3160 3161 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) 3162 (void) if_addmulti(parent, ifma->ifma_addr, NULL); 3163 } 3164 parent->if_ioctl = ioctl; 3165 3166 ic->ic_update_mcast(ic->ic_ifp); 3167 IEEE80211_UNLOCK(ic); 3168} 3169 3170int 3171ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 3172{ 3173 struct ieee80211vap *vap; 3174 struct ieee80211com *ic; 3175 int error = 0; 3176 struct ifreq *ifr; 3177 struct ifaddr *ifa; /* XXX */ 3178 3179 vap = ifp->if_softc; 3180 if (vap == NULL) { 3181 /* 3182 * During detach we clear the backpointer in the softc 3183 * so any ioctl request through the ifnet that arrives 3184 * before teardown is ignored/rejected. In particular 3185 * this hack handles destroying a vap used by an app 3186 * like wpa_supplicant that will respond to the vap 3187 * being forced into INIT state by immediately trying 3188 * to force it back up. We can yank this hack if/when 3189 * we can destroy the ifnet before cleaning up vap state. 3190 */ 3191 return ENXIO; 3192 } 3193 switch (cmd) { 3194 case SIOCSIFFLAGS: 3195 ic = vap->iv_ic; 3196 IEEE80211_LOCK(ic); 3197 ieee80211_syncifflag_locked(ic, IFF_PROMISC); 3198 ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); 3199 if (ifp->if_flags & IFF_UP) { 3200 /* 3201 * Bring ourself up unless we're already operational. 3202 * If we're the first vap and the parent is not up 3203 * then it will automatically be brought up as a 3204 * side-effect of bringing ourself up. 3205 */ 3206 if (vap->iv_state == IEEE80211_S_INIT) 3207 ieee80211_start_locked(vap); 3208 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 3209 /* 3210 * Stop ourself. If we are the last vap to be 3211 * marked down the parent will also be taken down. 3212 */ 3213 ieee80211_stop_locked(vap); 3214 } 3215 IEEE80211_UNLOCK(ic); 3216 break; 3217 case SIOCADDMULTI: 3218 case SIOCDELMULTI: 3219 ieee80211_ioctl_updatemulti(vap->iv_ic); 3220 break; 3221 case SIOCSIFMEDIA: 3222 case SIOCGIFMEDIA: 3223 ifr = (struct ifreq *)data; 3224 error = ifmedia_ioctl(ifp, ifr, &vap->iv_media, cmd); 3225 break; 3226 case SIOCG80211: 3227 error = ieee80211_ioctl_get80211(vap, cmd, 3228 (struct ieee80211req *) data); 3229 break; 3230 case SIOCS80211: 3231 error = priv_check(curthread, PRIV_NET80211_MANAGE); 3232 if (error == 0) 3233 error = ieee80211_ioctl_set80211(vap, cmd, 3234 (struct ieee80211req *) data); 3235 break; 3236 case SIOCG80211STATS: 3237 ifr = (struct ifreq *)data; 3238 copyout(&vap->iv_stats, ifr->ifr_data, sizeof (vap->iv_stats)); 3239 break; 3240 case SIOCSIFMTU: 3241 ifr = (struct ifreq *)data; 3242 if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu && 3243 ifr->ifr_mtu <= IEEE80211_MTU_MAX)) 3244 error = EINVAL; 3245 else 3246 ifp->if_mtu = ifr->ifr_mtu; 3247 break; 3248 case SIOCSIFADDR: 3249 /* 3250 * XXX Handle this directly so we can supress if_init calls. 3251 * XXX This should be done in ether_ioctl but for the moment 3252 * XXX there are too many other parts of the system that 3253 * XXX set IFF_UP and so supress if_init being called when 3254 * XXX it should be. 3255 */ 3256 ifa = (struct ifaddr *) data; 3257 switch (ifa->ifa_addr->sa_family) { 3258#ifdef INET 3259 case AF_INET: 3260 if ((ifp->if_flags & IFF_UP) == 0) { 3261 ifp->if_flags |= IFF_UP; 3262 ifp->if_init(ifp->if_softc); 3263 } 3264 arp_ifinit(ifp, ifa); 3265 break; 3266#endif 3267#ifdef IPX 3268 /* 3269 * XXX - This code is probably wrong, 3270 * but has been copied many times. 3271 */ 3272 case AF_IPX: { 3273 struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 3274 3275 if (ipx_nullhost(*ina)) 3276 ina->x_host = *(union ipx_host *) 3277 IF_LLADDR(ifp); 3278 else 3279 bcopy((caddr_t) ina->x_host.c_host, 3280 (caddr_t) IF_LLADDR(ifp), 3281 ETHER_ADDR_LEN); 3282 /* fall thru... */ 3283 } 3284#endif 3285 default: 3286 if ((ifp->if_flags & IFF_UP) == 0) { 3287 ifp->if_flags |= IFF_UP; 3288 ifp->if_init(ifp->if_softc); 3289 } 3290 break; 3291 } 3292 break; 3293 /* Pass NDIS ioctls up to the driver */ 3294 case SIOCGDRVSPEC: 3295 case SIOCSDRVSPEC: 3296 case SIOCGPRIVATE_0: { 3297 struct ifnet *parent = vap->iv_ic->ic_ifp; 3298 error = parent->if_ioctl(parent, cmd, data); 3299 break; 3300 } 3301 default: 3302 error = ether_ioctl(ifp, cmd, data); 3303 break; 3304 } 3305 return error; 3306}
|