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