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