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