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