1 /*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002-2005 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 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * Alternatively, this software may be distributed under the terms of the 18 * GNU General Public License ("GPL") version 2 as published by the Free 19 * Software Foundation. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 /* 37 * IEEE 802.11 ioctl support (FreeBSD-specific) 38 */ 39 40 #include "opt_inet.h" 41 #include "opt_ipx.h" 42 43 #include <sys/endian.h> 44 #include <sys/param.h> 45 #include <sys/kernel.h> 46 #include <sys/socket.h> 47 #include <sys/sockio.h> 48 #include <sys/systm.h> 49 50 #include <net/if.h> 51 #include <net/if_dl.h> 52 #include <net/if_media.h> 53 #include <net/ethernet.h> 54 55 #ifdef INET 56 #include <netinet/in.h> 57 #include <netinet/if_ether.h> 58 #endif 59 60 #ifdef IPX 61 #include <netipx/ipx.h> 62 #include <netipx/ipx_if.h> 63 #endif 64 65 #include <net80211/ieee80211_var.h> 66 #include <net80211/ieee80211_ioctl.h> 67 68 #include <dev/wi/if_wavelan_ieee.h> 69 70 #define IS_UP(_ic) \ 71 (((_ic)->ic_ifp->if_flags & IFF_UP) && \ 72 ((_ic)->ic_ifp->if_drv_flags & IFF_DRV_RUNNING)) 73 #define IS_UP_AUTO(_ic) \ 74 (IS_UP(_ic) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO) 75 76 /* 77 * XXX 78 * Wireless LAN specific configuration interface, which is compatible 79 * with wicontrol(8). 80 */ 81 82 struct wi_read_ap_args { 83 int i; /* result count */ 84 struct wi_apinfo *ap; /* current entry in result buffer */ 85 caddr_t max; /* result buffer bound */ 86 }; 87 88 static void 89 wi_read_ap_result(void *arg, struct ieee80211_node *ni) 90 { 91 struct ieee80211com *ic = ni->ni_ic; 92 struct wi_read_ap_args *sa = arg; 93 struct wi_apinfo *ap = sa->ap; 94 struct ieee80211_rateset *rs; 95 int j; 96 97 if ((caddr_t)(ap + 1) > sa->max) 98 return; 99 memset(ap, 0, sizeof(struct wi_apinfo)); 100 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 101 IEEE80211_ADDR_COPY(ap->bssid, ni->ni_macaddr); 102 ap->namelen = ic->ic_des_esslen; 103 if (ic->ic_des_esslen) 104 memcpy(ap->name, ic->ic_des_essid, 105 ic->ic_des_esslen); 106 } else { 107 IEEE80211_ADDR_COPY(ap->bssid, ni->ni_bssid); 108 ap->namelen = ni->ni_esslen; 109 if (ni->ni_esslen) 110 memcpy(ap->name, ni->ni_essid, 111 ni->ni_esslen); 112 } 113 ap->channel = ieee80211_chan2ieee(ic, ni->ni_chan); 114 ap->signal = ic->ic_node_getrssi(ni); 115 ap->capinfo = ni->ni_capinfo; 116 ap->interval = ni->ni_intval; 117 rs = &ni->ni_rates; 118 for (j = 0; j < rs->rs_nrates; j++) { 119 if (rs->rs_rates[j] & IEEE80211_RATE_BASIC) { 120 ap->rate = (rs->rs_rates[j] & 121 IEEE80211_RATE_VAL) * 5; /* XXX */ 122 } 123 } 124 sa->i++; 125 sa->ap++; 126 } 127 128 struct wi_read_prism2_args { 129 int i; /* result count */ 130 struct wi_scan_res *res;/* current entry in result buffer */ 131 caddr_t max; /* result buffer bound */ 132 }; 133 134 static void 135 wi_read_prism2_result(void *arg, struct ieee80211_node *ni) 136 { 137 struct ieee80211com *ic = ni->ni_ic; 138 struct wi_read_prism2_args *sa = arg; 139 struct wi_scan_res *res = sa->res; 140 141 if ((caddr_t)(res + 1) > sa->max) 142 return; 143 res->wi_chan = ieee80211_chan2ieee(ic, ni->ni_chan); 144 res->wi_noise = 0; 145 res->wi_signal = ic->ic_node_getrssi(ni); 146 IEEE80211_ADDR_COPY(res->wi_bssid, ni->ni_bssid); 147 res->wi_interval = ni->ni_intval; 148 res->wi_capinfo = ni->ni_capinfo; 149 res->wi_ssid_len = ni->ni_esslen; 150 memcpy(res->wi_ssid, ni->ni_essid, IEEE80211_NWID_LEN); 151 /* NB: assumes wi_srates holds <= ni->ni_rates */ 152 memcpy(res->wi_srates, ni->ni_rates.rs_rates, 153 sizeof(res->wi_srates)); 154 if (ni->ni_rates.rs_nrates < 10) 155 res->wi_srates[ni->ni_rates.rs_nrates] = 0; 156 res->wi_rate = ni->ni_rates.rs_rates[ni->ni_txrate]; 157 res->wi_rsvd = 0; 158 159 sa->i++; 160 sa->res++; 161 } 162 163 struct wi_read_sigcache_args { 164 int i; /* result count */ 165 struct wi_sigcache *wsc;/* current entry in result buffer */ 166 caddr_t max; /* result buffer bound */ 167 }; 168 169 static void 170 wi_read_sigcache(void *arg, struct ieee80211_node *ni) 171 { 172 struct ieee80211com *ic = ni->ni_ic; 173 struct wi_read_sigcache_args *sa = arg; 174 struct wi_sigcache *wsc = sa->wsc; 175 176 if ((caddr_t)(wsc + 1) > sa->max) 177 return; 178 memset(wsc, 0, sizeof(struct wi_sigcache)); 179 IEEE80211_ADDR_COPY(wsc->macsrc, ni->ni_macaddr); 180 wsc->signal = ic->ic_node_getrssi(ni); 181 182 sa->wsc++; 183 sa->i++; 184 } 185 186 int 187 ieee80211_cfgget(struct ieee80211com *ic, u_long cmd, caddr_t data) 188 { 189 struct ifnet *ifp = ic->ic_ifp; 190 int i, j, error; 191 struct ifreq *ifr = (struct ifreq *)data; 192 struct wi_req wreq; 193 struct wi_ltv_keys *keys; 194 195 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 196 if (error) 197 return error; 198 wreq.wi_len = 0; 199 switch (wreq.wi_type) { 200 case WI_RID_SERIALNO: 201 /* nothing appropriate */ 202 break; 203 case WI_RID_NODENAME: 204 strcpy((char *)&wreq.wi_val[1], hostname); 205 wreq.wi_val[0] = htole16(strlen(hostname)); 206 wreq.wi_len = (1 + strlen(hostname) + 1) / 2; 207 break; 208 case WI_RID_CURRENT_SSID: 209 if (ic->ic_state != IEEE80211_S_RUN) { 210 wreq.wi_val[0] = 0; 211 wreq.wi_len = 1; 212 break; 213 } 214 wreq.wi_val[0] = htole16(ic->ic_bss->ni_esslen); 215 memcpy(&wreq.wi_val[1], ic->ic_bss->ni_essid, 216 ic->ic_bss->ni_esslen); 217 wreq.wi_len = (1 + ic->ic_bss->ni_esslen + 1) / 2; 218 break; 219 case WI_RID_OWN_SSID: 220 case WI_RID_DESIRED_SSID: 221 wreq.wi_val[0] = htole16(ic->ic_des_esslen); 222 memcpy(&wreq.wi_val[1], ic->ic_des_essid, ic->ic_des_esslen); 223 wreq.wi_len = (1 + ic->ic_des_esslen + 1) / 2; 224 break; 225 case WI_RID_CURRENT_BSSID: 226 if (ic->ic_state == IEEE80211_S_RUN) 227 IEEE80211_ADDR_COPY(wreq.wi_val, ic->ic_bss->ni_bssid); 228 else 229 memset(wreq.wi_val, 0, IEEE80211_ADDR_LEN); 230 wreq.wi_len = IEEE80211_ADDR_LEN / 2; 231 break; 232 case WI_RID_CHANNEL_LIST: 233 memset(wreq.wi_val, 0, sizeof(wreq.wi_val)); 234 /* 235 * Since channel 0 is not available for DS, channel 1 236 * is assigned to LSB on WaveLAN. 237 */ 238 if (ic->ic_phytype == IEEE80211_T_DS) 239 i = 1; 240 else 241 i = 0; 242 for (j = 0; i <= IEEE80211_CHAN_MAX; i++, j++) 243 if (isset(ic->ic_chan_active, i)) { 244 setbit((u_int8_t *)wreq.wi_val, j); 245 wreq.wi_len = j / 16 + 1; 246 } 247 break; 248 case WI_RID_OWN_CHNL: 249 wreq.wi_val[0] = htole16( 250 ieee80211_chan2ieee(ic, ic->ic_ibss_chan)); 251 wreq.wi_len = 1; 252 break; 253 case WI_RID_CURRENT_CHAN: 254 wreq.wi_val[0] = htole16( 255 ieee80211_chan2ieee(ic, ic->ic_curchan)); 256 wreq.wi_len = 1; 257 break; 258 case WI_RID_COMMS_QUALITY: 259 wreq.wi_val[0] = 0; /* quality */ 260 wreq.wi_val[1] = htole16(ic->ic_node_getrssi(ic->ic_bss)); 261 wreq.wi_val[2] = 0; /* noise */ 262 wreq.wi_len = 3; 263 break; 264 case WI_RID_PROMISC: 265 wreq.wi_val[0] = htole16((ifp->if_flags & IFF_PROMISC) ? 1 : 0); 266 wreq.wi_len = 1; 267 break; 268 case WI_RID_PORTTYPE: 269 wreq.wi_val[0] = htole16(ic->ic_opmode); 270 wreq.wi_len = 1; 271 break; 272 case WI_RID_MAC_NODE: 273 IEEE80211_ADDR_COPY(wreq.wi_val, ic->ic_myaddr); 274 wreq.wi_len = IEEE80211_ADDR_LEN / 2; 275 break; 276 case WI_RID_TX_RATE: 277 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) 278 wreq.wi_val[0] = 0; /* auto */ 279 else 280 wreq.wi_val[0] = htole16( 281 (ic->ic_sup_rates[ic->ic_curmode].rs_rates[ic->ic_fixed_rate] & 282 IEEE80211_RATE_VAL) / 2); 283 wreq.wi_len = 1; 284 break; 285 case WI_RID_CUR_TX_RATE: 286 wreq.wi_val[0] = htole16( 287 (ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] & 288 IEEE80211_RATE_VAL) / 2); 289 wreq.wi_len = 1; 290 break; 291 case WI_RID_RTS_THRESH: 292 wreq.wi_val[0] = htole16(ic->ic_rtsthreshold); 293 wreq.wi_len = 1; 294 break; 295 case WI_RID_CREATE_IBSS: 296 wreq.wi_val[0] = 297 htole16((ic->ic_flags & IEEE80211_F_IBSSON) ? 1 : 0); 298 wreq.wi_len = 1; 299 break; 300 case WI_RID_MICROWAVE_OVEN: 301 wreq.wi_val[0] = 0; /* no ... not supported */ 302 wreq.wi_len = 1; 303 break; 304 case WI_RID_ROAMING_MODE: 305 wreq.wi_val[0] = htole16(ic->ic_roaming); /* XXX map */ 306 wreq.wi_len = 1; 307 break; 308 case WI_RID_SYSTEM_SCALE: 309 wreq.wi_val[0] = htole16(1); /* low density ... not supp */ 310 wreq.wi_len = 1; 311 break; 312 case WI_RID_PM_ENABLED: 313 wreq.wi_val[0] = 314 htole16((ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0); 315 wreq.wi_len = 1; 316 break; 317 case WI_RID_MAX_SLEEP: 318 wreq.wi_val[0] = htole16(ic->ic_lintval); 319 wreq.wi_len = 1; 320 break; 321 case WI_RID_CUR_BEACON_INT: 322 wreq.wi_val[0] = htole16(ic->ic_bss->ni_intval); 323 wreq.wi_len = 1; 324 break; 325 case WI_RID_WEP_AVAIL: 326 wreq.wi_val[0] = htole16(1); /* always available */ 327 wreq.wi_len = 1; 328 break; 329 case WI_RID_CNFAUTHMODE: 330 wreq.wi_val[0] = htole16(1); /* TODO: open system only */ 331 wreq.wi_len = 1; 332 break; 333 case WI_RID_ENCRYPTION: 334 wreq.wi_val[0] = 335 htole16((ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0); 336 wreq.wi_len = 1; 337 break; 338 case WI_RID_TX_CRYPT_KEY: 339 wreq.wi_val[0] = htole16(ic->ic_def_txkey); 340 wreq.wi_len = 1; 341 break; 342 case WI_RID_DEFLT_CRYPT_KEYS: 343 keys = (struct wi_ltv_keys *)&wreq; 344 /* do not show keys to non-root user */ 345 error = suser(curthread); 346 if (error) { 347 memset(keys, 0, sizeof(*keys)); 348 error = 0; 349 break; 350 } 351 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 352 keys->wi_keys[i].wi_keylen = 353 htole16(ic->ic_nw_keys[i].wk_keylen); 354 memcpy(keys->wi_keys[i].wi_keydat, 355 ic->ic_nw_keys[i].wk_key, 356 ic->ic_nw_keys[i].wk_keylen); 357 } 358 wreq.wi_len = sizeof(*keys) / 2; 359 break; 360 case WI_RID_MAX_DATALEN: 361 wreq.wi_val[0] = htole16(ic->ic_fragthreshold); 362 wreq.wi_len = 1; 363 break; 364 case WI_RID_IFACE_STATS: 365 /* XXX: should be implemented in lower drivers */ 366 break; 367 case WI_RID_READ_APS: 368 /* 369 * Don't return results until active scan completes. 370 */ 371 if ((ic->ic_flags & (IEEE80211_F_SCAN|IEEE80211_F_ASCAN)) == 0) { 372 struct wi_read_ap_args args; 373 374 args.i = 0; 375 args.ap = (void *)((char *)wreq.wi_val + sizeof(i)); 376 args.max = (void *)(&wreq + 1); 377 ieee80211_iterate_nodes(&ic->ic_scan, 378 wi_read_ap_result, &args); 379 memcpy(wreq.wi_val, &args.i, sizeof(args.i)); 380 wreq.wi_len = (sizeof(int) + 381 sizeof(struct wi_apinfo) * args.i) / 2; 382 } else 383 error = EINPROGRESS; 384 break; 385 case WI_RID_PRISM2: 386 /* NB: we lie so WI_RID_SCAN_RES can include rates */ 387 wreq.wi_val[0] = 1; 388 wreq.wi_len = sizeof(u_int16_t) / 2; 389 break; 390 case WI_RID_SCAN_RES: /* compatibility interface */ 391 if ((ic->ic_flags & (IEEE80211_F_SCAN|IEEE80211_F_ASCAN)) == 0) { 392 struct wi_read_prism2_args args; 393 struct wi_scan_p2_hdr *p2; 394 395 /* NB: use Prism2 format so we can include rate info */ 396 p2 = (struct wi_scan_p2_hdr *)wreq.wi_val; 397 args.i = 0; 398 args.res = (void *)&p2[1]; 399 args.max = (void *)(&wreq + 1); 400 ieee80211_iterate_nodes(&ic->ic_scan, 401 wi_read_prism2_result, &args); 402 p2->wi_rsvd = 0; 403 p2->wi_reason = args.i; 404 wreq.wi_len = (sizeof(*p2) + 405 sizeof(struct wi_scan_res) * args.i) / 2; 406 } else 407 error = EINPROGRESS; 408 break; 409 case WI_RID_READ_CACHE: { 410 struct wi_read_sigcache_args args; 411 args.i = 0; 412 args.wsc = (struct wi_sigcache *) wreq.wi_val; 413 args.max = (void *)(&wreq + 1); 414 ieee80211_iterate_nodes(&ic->ic_scan, wi_read_sigcache, &args); 415 wreq.wi_len = sizeof(struct wi_sigcache) * args.i / 2; 416 break; 417 } 418 default: 419 error = EINVAL; 420 break; 421 } 422 if (error == 0) { 423 wreq.wi_len++; 424 error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); 425 } 426 return error; 427 } 428 429 static int 430 findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate) 431 { 432 #define IEEERATE(_ic,_m,_i) \ 433 ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL) 434 int i, nrates = ic->ic_sup_rates[mode].rs_nrates; 435 for (i = 0; i < nrates; i++) 436 if (IEEERATE(ic, mode, i) == rate) 437 return i; 438 return -1; 439 #undef IEEERATE 440 } 441 442 /* 443 * Prepare to do a user-initiated scan for AP's. If no 444 * current/default channel is setup or the current channel 445 * is invalid then pick the first available channel from 446 * the active list as the place to start the scan. 447 */ 448 static int 449 ieee80211_setupscan(struct ieee80211com *ic, const u_int8_t chanlist[]) 450 { 451 452 /* 453 * XXX don't permit a scan to be started unless we 454 * know the device is ready. For the moment this means 455 * the device is marked up as this is the required to 456 * initialize the hardware. It would be better to permit 457 * scanning prior to being up but that'll require some 458 * changes to the infrastructure. 459 */ 460 if (!IS_UP(ic)) 461 return EINVAL; 462 memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); 463 /* 464 * We force the state to INIT before calling ieee80211_new_state 465 * to get ieee80211_begin_scan called. We really want to scan w/o 466 * altering the current state but that's not possible right now. 467 */ 468 /* XXX handle proberequest case */ 469 ic->ic_state = IEEE80211_S_INIT; /* XXX bypass state machine */ 470 return 0; 471 } 472 473 int 474 ieee80211_cfgset(struct ieee80211com *ic, u_long cmd, caddr_t data) 475 { 476 struct ifnet *ifp = ic->ic_ifp; 477 int i, j, len, error, rate; 478 struct ifreq *ifr = (struct ifreq *)data; 479 struct wi_ltv_keys *keys; 480 struct wi_req wreq; 481 u_char chanlist[roundup(IEEE80211_CHAN_MAX, NBBY)]; 482 483 error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); 484 if (error) 485 return error; 486 len = wreq.wi_len ? (wreq.wi_len - 1) * 2 : 0; 487 switch (wreq.wi_type) { 488 case WI_RID_SERIALNO: 489 case WI_RID_NODENAME: 490 return EPERM; 491 case WI_RID_CURRENT_SSID: 492 return EPERM; 493 case WI_RID_OWN_SSID: 494 case WI_RID_DESIRED_SSID: 495 if (le16toh(wreq.wi_val[0]) * 2 > len || 496 le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN) { 497 error = ENOSPC; 498 break; 499 } 500 memset(ic->ic_des_essid, 0, sizeof(ic->ic_des_essid)); 501 ic->ic_des_esslen = le16toh(wreq.wi_val[0]) * 2; 502 memcpy(ic->ic_des_essid, &wreq.wi_val[1], ic->ic_des_esslen); 503 error = ENETRESET; 504 break; 505 case WI_RID_CURRENT_BSSID: 506 return EPERM; 507 case WI_RID_OWN_CHNL: 508 if (len != 2) 509 return EINVAL; 510 i = le16toh(wreq.wi_val[0]); 511 if (i < 0 || 512 i > IEEE80211_CHAN_MAX || 513 isclr(ic->ic_chan_active, i)) 514 return EINVAL; 515 ic->ic_ibss_chan = &ic->ic_channels[i]; 516 if (ic->ic_opmode == IEEE80211_M_MONITOR) 517 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 518 else 519 error = ENETRESET; 520 break; 521 case WI_RID_CURRENT_CHAN: 522 return EPERM; 523 case WI_RID_COMMS_QUALITY: 524 return EPERM; 525 case WI_RID_PROMISC: 526 if (len != 2) 527 return EINVAL; 528 if (ifp->if_flags & IFF_PROMISC) { 529 if (wreq.wi_val[0] == 0) { 530 ifp->if_flags &= ~IFF_PROMISC; 531 error = ENETRESET; 532 } 533 } else { 534 if (wreq.wi_val[0] != 0) { 535 ifp->if_flags |= IFF_PROMISC; 536 error = ENETRESET; 537 } 538 } 539 break; 540 case WI_RID_PORTTYPE: 541 if (len != 2) 542 return EINVAL; 543 switch (le16toh(wreq.wi_val[0])) { 544 case IEEE80211_M_STA: 545 break; 546 case IEEE80211_M_IBSS: 547 if (!(ic->ic_caps & IEEE80211_C_IBSS)) 548 return EINVAL; 549 break; 550 case IEEE80211_M_AHDEMO: 551 if (ic->ic_phytype != IEEE80211_T_DS || 552 !(ic->ic_caps & IEEE80211_C_AHDEMO)) 553 return EINVAL; 554 break; 555 case IEEE80211_M_HOSTAP: 556 if (!(ic->ic_caps & IEEE80211_C_HOSTAP)) 557 return EINVAL; 558 break; 559 default: 560 return EINVAL; 561 } 562 if (le16toh(wreq.wi_val[0]) != ic->ic_opmode) { 563 ic->ic_opmode = le16toh(wreq.wi_val[0]); 564 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 565 } 566 break; 567 #if 0 568 case WI_RID_MAC_NODE: 569 if (len != IEEE80211_ADDR_LEN) 570 return EINVAL; 571 IEEE80211_ADDR_COPY(LLADDR(ifp->if_sadl), wreq.wi_val); 572 /* if_init will copy lladdr into ic_myaddr */ 573 error = ENETRESET; 574 break; 575 #endif 576 case WI_RID_TX_RATE: 577 if (len != 2) 578 return EINVAL; 579 if (wreq.wi_val[0] == 0) { 580 /* auto */ 581 ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE; 582 break; 583 } 584 rate = 2 * le16toh(wreq.wi_val[0]); 585 if (ic->ic_curmode == IEEE80211_MODE_AUTO) { 586 /* 587 * In autoselect mode search for the rate. We take 588 * the first instance which may not be right, but we 589 * are limited by the interface. Note that we also 590 * lock the mode to insure the rate is meaningful 591 * when it is used. 592 */ 593 for (j = IEEE80211_MODE_11A; 594 j < IEEE80211_MODE_MAX; j++) { 595 if ((ic->ic_modecaps & (1<<j)) == 0) 596 continue; 597 i = findrate(ic, j, rate); 598 if (i != -1) { 599 /* lock mode too */ 600 ic->ic_curmode = j; 601 goto setrate; 602 } 603 } 604 } else { 605 i = findrate(ic, ic->ic_curmode, rate); 606 if (i != -1) 607 goto setrate; 608 } 609 return EINVAL; 610 setrate: 611 ic->ic_fixed_rate = i; 612 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 613 break; 614 case WI_RID_CUR_TX_RATE: 615 return EPERM; 616 case WI_RID_RTS_THRESH: 617 if (len != 2) 618 return EINVAL; 619 if (le16toh(wreq.wi_val[0]) != IEEE80211_MAX_LEN) 620 return EINVAL; /* TODO: RTS */ 621 break; 622 case WI_RID_CREATE_IBSS: 623 if (len != 2) 624 return EINVAL; 625 if (wreq.wi_val[0] != 0) { 626 if ((ic->ic_caps & IEEE80211_C_IBSS) == 0) 627 return EINVAL; 628 if ((ic->ic_flags & IEEE80211_F_IBSSON) == 0) { 629 ic->ic_flags |= IEEE80211_F_IBSSON; 630 if (ic->ic_opmode == IEEE80211_M_IBSS && 631 ic->ic_state == IEEE80211_S_SCAN) 632 error = IS_UP_AUTO(ic) ? ENETRESET : 0; 633 } 634 } else { 635 if (ic->ic_flags & IEEE80211_F_IBSSON) { 636 ic->ic_flags &= ~IEEE80211_F_IBSSON; 637 if (ic->ic_flags & IEEE80211_F_SIBSS) { 638 ic->ic_flags &= ~IEEE80211_F_SIBSS; 639 error = IS_UP_AUTO(ic) ? ENETRESET : 0; 640 } 641 } 642 } 643 break; 644 case WI_RID_MICROWAVE_OVEN: 645 if (len != 2) 646 return EINVAL; 647 if (wreq.wi_val[0] != 0) 648 return EINVAL; /* not supported */ 649 break; 650 case WI_RID_ROAMING_MODE: 651 if (len != 2) 652 return EINVAL; 653 i = le16toh(wreq.wi_val[0]); 654 if (i > IEEE80211_ROAMING_MANUAL) 655 return EINVAL; /* not supported */ 656 ic->ic_roaming = i; 657 break; 658 case WI_RID_SYSTEM_SCALE: 659 if (len != 2) 660 return EINVAL; 661 if (le16toh(wreq.wi_val[0]) != 1) 662 return EINVAL; /* not supported */ 663 break; 664 case WI_RID_PM_ENABLED: 665 if (len != 2) 666 return EINVAL; 667 if (wreq.wi_val[0] != 0) { 668 if ((ic->ic_caps & IEEE80211_C_PMGT) == 0) 669 return EINVAL; 670 if ((ic->ic_flags & IEEE80211_F_PMGTON) == 0) { 671 ic->ic_flags |= IEEE80211_F_PMGTON; 672 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 673 } 674 } else { 675 if (ic->ic_flags & IEEE80211_F_PMGTON) { 676 ic->ic_flags &= ~IEEE80211_F_PMGTON; 677 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 678 } 679 } 680 break; 681 case WI_RID_MAX_SLEEP: 682 if (len != 2) 683 return EINVAL; 684 ic->ic_lintval = le16toh(wreq.wi_val[0]); 685 if (ic->ic_flags & IEEE80211_F_PMGTON) 686 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 687 break; 688 case WI_RID_CUR_BEACON_INT: 689 return EPERM; 690 case WI_RID_WEP_AVAIL: 691 return EPERM; 692 case WI_RID_CNFAUTHMODE: 693 if (len != 2) 694 return EINVAL; 695 i = le16toh(wreq.wi_val[0]); 696 if (i > IEEE80211_AUTH_WPA) 697 return EINVAL; 698 ic->ic_bss->ni_authmode = i; /* XXX ENETRESET? */ 699 error = ENETRESET; 700 break; 701 case WI_RID_ENCRYPTION: 702 if (len != 2) 703 return EINVAL; 704 if (wreq.wi_val[0] != 0) { 705 if ((ic->ic_caps & IEEE80211_C_WEP) == 0) 706 return EINVAL; 707 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 708 ic->ic_flags |= IEEE80211_F_PRIVACY; 709 error = ENETRESET; 710 } 711 } else { 712 if (ic->ic_flags & IEEE80211_F_PRIVACY) { 713 ic->ic_flags &= ~IEEE80211_F_PRIVACY; 714 error = ENETRESET; 715 } 716 } 717 break; 718 case WI_RID_TX_CRYPT_KEY: 719 if (len != 2) 720 return EINVAL; 721 i = le16toh(wreq.wi_val[0]); 722 if (i >= IEEE80211_WEP_NKID) 723 return EINVAL; 724 ic->ic_def_txkey = i; 725 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 726 break; 727 case WI_RID_DEFLT_CRYPT_KEYS: 728 if (len != sizeof(struct wi_ltv_keys)) 729 return EINVAL; 730 keys = (struct wi_ltv_keys *)&wreq; 731 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 732 len = le16toh(keys->wi_keys[i].wi_keylen); 733 if (len != 0 && len < IEEE80211_WEP_KEYLEN) 734 return EINVAL; 735 if (len > IEEE80211_KEYBUF_SIZE) 736 return EINVAL; 737 } 738 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 739 struct ieee80211_key *k = &ic->ic_nw_keys[i]; 740 741 len = le16toh(keys->wi_keys[i].wi_keylen); 742 k->wk_keylen = len; 743 k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV; 744 memset(k->wk_key, 0, sizeof(k->wk_key)); 745 memcpy(k->wk_key, keys->wi_keys[i].wi_keydat, len); 746 #if 0 747 k->wk_type = IEEE80211_CIPHER_WEP; 748 #endif 749 } 750 error = ENETRESET; 751 break; 752 case WI_RID_MAX_DATALEN: 753 if (len != 2) 754 return EINVAL; 755 len = le16toh(wreq.wi_val[0]); 756 if (len < 350 /* ? */ || len > IEEE80211_MAX_LEN) 757 return EINVAL; 758 ic->ic_fragthreshold = len; 759 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 760 break; 761 case WI_RID_IFACE_STATS: 762 error = EPERM; 763 break; 764 case WI_RID_SCAN_REQ: /* XXX wicontrol */ 765 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 766 break; 767 error = ieee80211_setupscan(ic, ic->ic_chan_avail); 768 if (error == 0) 769 error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 770 break; 771 case WI_RID_SCAN_APS: 772 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 773 break; 774 len--; /* XXX: tx rate? */ 775 /* FALLTHRU */ 776 case WI_RID_CHANNEL_LIST: 777 memset(chanlist, 0, sizeof(chanlist)); 778 /* 779 * Since channel 0 is not available for DS, channel 1 780 * is assigned to LSB on WaveLAN. 781 */ 782 if (ic->ic_phytype == IEEE80211_T_DS) 783 i = 1; 784 else 785 i = 0; 786 for (j = 0; i <= IEEE80211_CHAN_MAX; i++, j++) { 787 if ((j / 8) >= len) 788 break; 789 if (isclr((u_int8_t *)wreq.wi_val, j)) 790 continue; 791 if (isclr(ic->ic_chan_active, i)) { 792 if (wreq.wi_type != WI_RID_CHANNEL_LIST) 793 continue; 794 if (isclr(ic->ic_chan_avail, i)) 795 return EPERM; 796 } 797 setbit(chanlist, i); 798 } 799 error = ieee80211_setupscan(ic, chanlist); 800 if (wreq.wi_type == WI_RID_CHANNEL_LIST) { 801 /* NB: ignore error from ieee80211_setupscan */ 802 error = ENETRESET; 803 } else if (error == 0) 804 error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 805 break; 806 default: 807 error = EINVAL; 808 break; 809 } 810 if (error == ENETRESET && !IS_UP_AUTO(ic)) 811 error = 0; 812 return error; 813 } 814 815 static int 816 cap2cipher(int flag) 817 { 818 switch (flag) { 819 case IEEE80211_C_WEP: return IEEE80211_CIPHER_WEP; 820 case IEEE80211_C_AES: return IEEE80211_CIPHER_AES_OCB; 821 case IEEE80211_C_AES_CCM: return IEEE80211_CIPHER_AES_CCM; 822 case IEEE80211_C_CKIP: return IEEE80211_CIPHER_CKIP; 823 case IEEE80211_C_TKIP: return IEEE80211_CIPHER_TKIP; 824 } 825 return -1; 826 } 827 828 static int 829 ieee80211_ioctl_getkey(struct ieee80211com *ic, struct ieee80211req *ireq) 830 { 831 struct ieee80211_node *ni; 832 struct ieee80211req_key ik; 833 struct ieee80211_key *wk; 834 const struct ieee80211_cipher *cip; 835 u_int kid; 836 int error; 837 838 if (ireq->i_len != sizeof(ik)) 839 return EINVAL; 840 error = copyin(ireq->i_data, &ik, sizeof(ik)); 841 if (error) 842 return error; 843 kid = ik.ik_keyix; 844 if (kid == IEEE80211_KEYIX_NONE) { 845 ni = ieee80211_find_node(&ic->ic_sta, ik.ik_macaddr); 846 if (ni == NULL) 847 return EINVAL; /* XXX */ 848 wk = &ni->ni_ucastkey; 849 } else { 850 if (kid >= IEEE80211_WEP_NKID) 851 return EINVAL; 852 wk = &ic->ic_nw_keys[kid]; 853 IEEE80211_ADDR_COPY(&ik.ik_macaddr, ic->ic_bss->ni_macaddr); 854 ni = NULL; 855 } 856 cip = wk->wk_cipher; 857 ik.ik_type = cip->ic_cipher; 858 ik.ik_keylen = wk->wk_keylen; 859 ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV); 860 if (wk->wk_keyix == ic->ic_def_txkey) 861 ik.ik_flags |= IEEE80211_KEY_DEFAULT; 862 if (suser(curthread) == 0) { 863 /* NB: only root can read key data */ 864 ik.ik_keyrsc = wk->wk_keyrsc; 865 ik.ik_keytsc = wk->wk_keytsc; 866 memcpy(ik.ik_keydata, wk->wk_key, wk->wk_keylen); 867 if (cip->ic_cipher == IEEE80211_CIPHER_TKIP) { 868 memcpy(ik.ik_keydata+wk->wk_keylen, 869 wk->wk_key + IEEE80211_KEYBUF_SIZE, 870 IEEE80211_MICBUF_SIZE); 871 ik.ik_keylen += IEEE80211_MICBUF_SIZE; 872 } 873 } else { 874 ik.ik_keyrsc = 0; 875 ik.ik_keytsc = 0; 876 memset(ik.ik_keydata, 0, sizeof(ik.ik_keydata)); 877 } 878 if (ni != NULL) 879 ieee80211_free_node(ni); 880 return copyout(&ik, ireq->i_data, sizeof(ik)); 881 } 882 883 static int 884 ieee80211_ioctl_getchanlist(struct ieee80211com *ic, struct ieee80211req *ireq) 885 { 886 887 if (sizeof(ic->ic_chan_active) < ireq->i_len) 888 ireq->i_len = sizeof(ic->ic_chan_active); 889 return copyout(&ic->ic_chan_active, ireq->i_data, ireq->i_len); 890 } 891 892 static int 893 ieee80211_ioctl_getchaninfo(struct ieee80211com *ic, struct ieee80211req *ireq) 894 { 895 struct ieee80211req_chaninfo chans; /* XXX off stack? */ 896 int i, space; 897 898 /* 899 * Since channel 0 is not available for DS, channel 1 900 * is assigned to LSB on WaveLAN. 901 */ 902 if (ic->ic_phytype == IEEE80211_T_DS) 903 i = 1; 904 else 905 i = 0; 906 memset(&chans, 0, sizeof(chans)); 907 for (; i <= IEEE80211_CHAN_MAX; i++) 908 if (isset(ic->ic_chan_avail, i)) { 909 struct ieee80211_channel *c = &ic->ic_channels[i]; 910 chans.ic_chans[chans.ic_nchans].ic_freq = c->ic_freq; 911 chans.ic_chans[chans.ic_nchans].ic_flags = c->ic_flags; 912 chans.ic_nchans++; 913 } 914 space = __offsetof(struct ieee80211req_chaninfo, 915 ic_chans[chans.ic_nchans]); 916 if (space > ireq->i_len) 917 space = ireq->i_len; 918 return copyout(&chans, ireq->i_data, space); 919 } 920 921 static int 922 ieee80211_ioctl_getwpaie(struct ieee80211com *ic, struct ieee80211req *ireq) 923 { 924 struct ieee80211_node *ni; 925 struct ieee80211req_wpaie wpaie; 926 int error; 927 928 if (ireq->i_len < IEEE80211_ADDR_LEN) 929 return EINVAL; 930 error = copyin(ireq->i_data, wpaie.wpa_macaddr, IEEE80211_ADDR_LEN); 931 if (error != 0) 932 return error; 933 ni = ieee80211_find_node(&ic->ic_sta, wpaie.wpa_macaddr); 934 if (ni == NULL) 935 return EINVAL; /* XXX */ 936 memset(wpaie.wpa_ie, 0, sizeof(wpaie.wpa_ie)); 937 if (ni->ni_wpa_ie != NULL) { 938 int ielen = ni->ni_wpa_ie[1] + 2; 939 if (ielen > sizeof(wpaie.wpa_ie)) 940 ielen = sizeof(wpaie.wpa_ie); 941 memcpy(wpaie.wpa_ie, ni->ni_wpa_ie, ielen); 942 } 943 ieee80211_free_node(ni); 944 if (ireq->i_len > sizeof(wpaie)) 945 ireq->i_len = sizeof(wpaie); 946 return copyout(&wpaie, ireq->i_data, ireq->i_len); 947 } 948 949 static int 950 ieee80211_ioctl_getstastats(struct ieee80211com *ic, struct ieee80211req *ireq) 951 { 952 struct ieee80211_node *ni; 953 u_int8_t macaddr[IEEE80211_ADDR_LEN]; 954 const int off = __offsetof(struct ieee80211req_sta_stats, is_stats); 955 int error; 956 957 if (ireq->i_len < off) 958 return EINVAL; 959 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 960 if (error != 0) 961 return error; 962 ni = ieee80211_find_node(&ic->ic_sta, macaddr); 963 if (ni == NULL) 964 return EINVAL; /* XXX */ 965 if (ireq->i_len > sizeof(struct ieee80211req_sta_stats)) 966 ireq->i_len = sizeof(struct ieee80211req_sta_stats); 967 /* NB: copy out only the statistics */ 968 error = copyout(&ni->ni_stats, (u_int8_t *) ireq->i_data + off, 969 ireq->i_len - off); 970 ieee80211_free_node(ni); 971 return error; 972 } 973 974 #define COMPAT_FREEBSD6 975 #ifdef COMPAT_FREEBSD6 976 #define IEEE80211_IOC_SCAN_RESULTS_OLD 24 977 978 struct scan_result_old { 979 u_int16_t isr_len; /* length (mult of 4) */ 980 u_int16_t isr_freq; /* MHz */ 981 u_int16_t isr_flags; /* channel flags */ 982 u_int8_t isr_noise; 983 u_int8_t isr_rssi; 984 u_int8_t isr_intval; /* beacon interval */ 985 u_int8_t isr_capinfo; /* capabilities */ 986 u_int8_t isr_erp; /* ERP element */ 987 u_int8_t isr_bssid[IEEE80211_ADDR_LEN]; 988 u_int8_t isr_nrates; 989 u_int8_t isr_rates[IEEE80211_RATE_MAXSIZE]; 990 u_int8_t isr_ssid_len; /* SSID length */ 991 u_int8_t isr_ie_len; /* IE length */ 992 u_int8_t isr_pad[5]; 993 /* variable length SSID followed by IE data */ 994 }; 995 996 static void 997 old_get_scan_result(struct scan_result_old *sr, 998 const struct ieee80211_node *ni) 999 { 1000 struct ieee80211com *ic = ni->ni_ic; 1001 u_int ielen; 1002 1003 memset(sr, 0, sizeof(*sr)); 1004 sr->isr_ssid_len = ni->ni_esslen; 1005 ielen = 0; 1006 if (ni->ni_wpa_ie != NULL) 1007 ielen += 2+ni->ni_wpa_ie[1]; 1008 if (ni->ni_wme_ie != NULL) 1009 ielen += 2+ni->ni_wme_ie[1]; 1010 /* NB: beware of overflow, isr_ie_len is 8 bits */ 1011 sr->isr_ie_len = (ielen > 255 ? 0 : ielen); 1012 sr->isr_len = sizeof(*sr) + sr->isr_ssid_len + sr->isr_ie_len; 1013 sr->isr_len = roundup(sr->isr_len, sizeof(u_int32_t)); 1014 if (ni->ni_chan != IEEE80211_CHAN_ANYC) { 1015 sr->isr_freq = ni->ni_chan->ic_freq; 1016 sr->isr_flags = ni->ni_chan->ic_flags; 1017 } 1018 sr->isr_rssi = ic->ic_node_getrssi(ni); 1019 sr->isr_intval = ni->ni_intval; 1020 sr->isr_capinfo = ni->ni_capinfo; 1021 sr->isr_erp = ni->ni_erp; 1022 IEEE80211_ADDR_COPY(sr->isr_bssid, ni->ni_bssid); 1023 sr->isr_nrates = ni->ni_rates.rs_nrates; 1024 if (sr->isr_nrates > 15) 1025 sr->isr_nrates = 15; 1026 memcpy(sr->isr_rates, ni->ni_rates.rs_rates, sr->isr_nrates); 1027 } 1028 1029 static int 1030 old_getscanresults(struct ieee80211com *ic, struct ieee80211req *ireq) 1031 { 1032 union { 1033 struct scan_result_old res; 1034 char data[512]; /* XXX shrink? */ 1035 } u; 1036 struct scan_result_old *sr = &u.res; 1037 struct ieee80211_node_table *nt; 1038 struct ieee80211_node *ni; 1039 int error, space; 1040 u_int8_t *p, *cp; 1041 1042 p = ireq->i_data; 1043 space = ireq->i_len; 1044 error = 0; 1045 /* XXX locking */ 1046 nt = &ic->ic_scan; 1047 TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 1048 /* NB: skip pre-scan node state */ 1049 if (ni->ni_chan == IEEE80211_CHAN_ANYC) 1050 continue; 1051 old_get_scan_result(sr, ni); 1052 if (sr->isr_len > sizeof(u)) 1053 continue; /* XXX */ 1054 if (space < sr->isr_len) 1055 break; 1056 cp = (u_int8_t *)(sr+1); 1057 memcpy(cp, ni->ni_essid, ni->ni_esslen); 1058 cp += ni->ni_esslen; 1059 if (sr->isr_ie_len) { 1060 if (ni->ni_wpa_ie != NULL) { 1061 memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]); 1062 cp += 2+ni->ni_wpa_ie[1]; 1063 } 1064 if (ni->ni_wme_ie != NULL) { 1065 memcpy(cp, ni->ni_wme_ie, 2+ni->ni_wme_ie[1]); 1066 cp += 2+ni->ni_wme_ie[1]; 1067 } 1068 } 1069 error = copyout(sr, p, sr->isr_len); 1070 if (error) 1071 break; 1072 p += sr->isr_len; 1073 space -= sr->isr_len; 1074 } 1075 ireq->i_len -= space; 1076 return error; 1077 } 1078 #endif /* COMPAT_FREEBSD6 */ 1079 1080 struct scanresultsreq { 1081 struct ieee80211req_scan_result *sr; 1082 size_t space; 1083 }; 1084 1085 static size_t 1086 scan_space(const struct ieee80211_node *ni, size_t *ielen) 1087 { 1088 size_t len; 1089 1090 *ielen = 0; 1091 if (ni->ni_wpa_ie != NULL) 1092 *ielen += 2+ni->ni_wpa_ie[1]; 1093 if (ni->ni_wme_ie != NULL) 1094 *ielen += 2+ni->ni_wme_ie[1]; 1095 /* 1096 * NB: ie's can be no more than 255 bytes and the max 802.11 1097 * packet is <3Kbytes so we are sure this doesn't overflow 1098 * 16-bits; if this is a concern we can drop the ie's. 1099 */ 1100 len = sizeof(struct ieee80211req_scan_result) + ni->ni_esslen + *ielen; 1101 return roundup(len, sizeof(u_int32_t)); 1102 } 1103 1104 static void 1105 get_scan_space(void *arg, struct ieee80211_node *ni) 1106 { 1107 struct scanresultsreq *req = arg; 1108 size_t ielen; 1109 1110 req->space += scan_space(ni, &ielen); 1111 } 1112 1113 static void 1114 get_scan_result(void *arg, struct ieee80211_node *ni) 1115 { 1116 struct scanresultsreq *req = arg; 1117 struct ieee80211com *ic = ni->ni_ic; 1118 struct ieee80211req_scan_result *sr; 1119 size_t ielen, len; 1120 u_int8_t *cp; 1121 1122 len = scan_space(ni, &ielen); 1123 if (len > req->space) 1124 return; 1125 sr = req->sr; 1126 KASSERT(len <= 65535 && ielen <= 65535, 1127 ("len %zu ssid %u ie %zu", len, ni->ni_esslen, ielen)); 1128 sr->isr_len = len; 1129 sr->isr_ssid_len = ni->ni_esslen; 1130 sr->isr_ie_len = ielen; 1131 if (ni->ni_chan != IEEE80211_CHAN_ANYC) { 1132 sr->isr_freq = ni->ni_chan->ic_freq; 1133 sr->isr_flags = ni->ni_chan->ic_flags; 1134 } 1135 /* XXX need to rev driver apis for signal data */ 1136 sr->isr_rssi = (int8_t) ic->ic_node_getrssi(ni); 1137 sr->isr_intval = ni->ni_intval; 1138 sr->isr_capinfo = ni->ni_capinfo; 1139 sr->isr_erp = ni->ni_erp; 1140 IEEE80211_ADDR_COPY(sr->isr_bssid, ni->ni_bssid); 1141 sr->isr_nrates = ni->ni_rates.rs_nrates; 1142 if (sr->isr_nrates > 15) 1143 sr->isr_nrates = 15; 1144 memcpy(sr->isr_rates, ni->ni_rates.rs_rates, sr->isr_nrates); 1145 cp = (u_int8_t *)(sr+1); 1146 memcpy(cp, ni->ni_essid, ni->ni_esslen); 1147 cp += ni->ni_esslen; 1148 if (sr->isr_ie_len) { 1149 if (ni->ni_wpa_ie != NULL) { 1150 memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]); 1151 cp += 2+ni->ni_wpa_ie[1]; 1152 } 1153 if (ni->ni_wme_ie != NULL) { 1154 memcpy(cp, ni->ni_wme_ie, 2+ni->ni_wme_ie[1]); 1155 cp += 2+ni->ni_wme_ie[1]; 1156 } 1157 } 1158 1159 req->sr = (struct ieee80211req_scan_result *)(((u_int8_t *)sr) + len); 1160 req->space -= len; 1161 } 1162 1163 static int 1164 ieee80211_ioctl_getscanresults(struct ieee80211com *ic, struct ieee80211req *ireq) 1165 { 1166 struct scanresultsreq req; 1167 int error; 1168 1169 if (ireq->i_len < sizeof(struct scanresultsreq)) 1170 return EFAULT; 1171 1172 error = 0; 1173 req.space = 0; 1174 ieee80211_iterate_nodes(&ic->ic_scan, get_scan_space, &req); 1175 if (req.space > ireq->i_len) 1176 req.space = ireq->i_len; 1177 if (req.space > 0) { 1178 size_t space; 1179 void *p; 1180 1181 space = req.space; 1182 /* XXX M_WAITOK after driver lock released */ 1183 MALLOC(p, void *, space, M_TEMP, M_NOWAIT | M_ZERO); 1184 if (p == NULL) 1185 return ENOMEM; 1186 req.sr = p; 1187 ieee80211_iterate_nodes(&ic->ic_scan, get_scan_result, &req); 1188 ireq->i_len = space - req.space; 1189 error = copyout(p, ireq->i_data, ireq->i_len); 1190 FREE(p, M_TEMP); 1191 } else 1192 ireq->i_len = 0; 1193 1194 return error; 1195 } 1196 1197 struct stainforeq { 1198 struct ieee80211com *ic; 1199 struct ieee80211req_sta_info *si; 1200 size_t space; 1201 }; 1202 1203 static size_t 1204 sta_space(const struct ieee80211_node *ni, size_t *ielen) 1205 { 1206 *ielen = 0; 1207 if (ni->ni_wpa_ie != NULL) 1208 *ielen += 2+ni->ni_wpa_ie[1]; 1209 if (ni->ni_wme_ie != NULL) 1210 *ielen += 2+ni->ni_wme_ie[1]; 1211 return roundup(sizeof(struct ieee80211req_sta_info) + *ielen, 1212 sizeof(u_int32_t)); 1213 } 1214 1215 static void 1216 get_sta_space(void *arg, struct ieee80211_node *ni) 1217 { 1218 struct stainforeq *req = arg; 1219 struct ieee80211com *ic = ni->ni_ic; 1220 size_t ielen; 1221 1222 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 1223 ni->ni_associd == 0) /* only associated stations */ 1224 return; 1225 req->space += sta_space(ni, &ielen); 1226 } 1227 1228 static void 1229 get_sta_info(void *arg, struct ieee80211_node *ni) 1230 { 1231 struct stainforeq *req = arg; 1232 struct ieee80211com *ic = ni->ni_ic; 1233 struct ieee80211req_sta_info *si; 1234 size_t ielen, len; 1235 u_int8_t *cp; 1236 1237 if (ic->ic_opmode == IEEE80211_M_HOSTAP && 1238 ni->ni_associd == 0) /* only associated stations */ 1239 return; 1240 if (ni->ni_chan == IEEE80211_CHAN_ANYC) /* XXX bogus entry */ 1241 return; 1242 len = sta_space(ni, &ielen); 1243 if (len > req->space) 1244 return; 1245 si = req->si; 1246 KASSERT(len <= 65535 && ielen <= 65535, ("len %zu ie %zu", len, ielen)); 1247 si->isi_len = len; 1248 si->isi_ie_len = ielen; 1249 si->isi_freq = ni->ni_chan->ic_freq; 1250 si->isi_flags = ni->ni_chan->ic_flags; 1251 si->isi_state = ni->ni_flags; 1252 si->isi_authmode = ni->ni_authmode; 1253 si->isi_rssi = ic->ic_node_getrssi(ni); 1254 si->isi_capinfo = ni->ni_capinfo; 1255 si->isi_erp = ni->ni_erp; 1256 IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); 1257 si->isi_nrates = ni->ni_rates.rs_nrates; 1258 if (si->isi_nrates > 15) 1259 si->isi_nrates = 15; 1260 memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates); 1261 si->isi_txrate = ni->ni_txrate; 1262 si->isi_associd = ni->ni_associd; 1263 si->isi_txpower = ni->ni_txpower; 1264 si->isi_vlan = ni->ni_vlan; 1265 if (ni->ni_flags & IEEE80211_NODE_QOS) { 1266 memcpy(si->isi_txseqs, ni->ni_txseqs, sizeof(ni->ni_txseqs)); 1267 memcpy(si->isi_rxseqs, ni->ni_rxseqs, sizeof(ni->ni_rxseqs)); 1268 } else { 1269 si->isi_txseqs[0] = ni->ni_txseqs[0]; 1270 si->isi_rxseqs[0] = ni->ni_rxseqs[0]; 1271 } 1272 /* NB: leave all cases in case we relax ni_associd == 0 check */ 1273 if (ieee80211_node_is_authorized(ni)) 1274 si->isi_inact = ic->ic_inact_run; 1275 else if (ni->ni_associd != 0) 1276 si->isi_inact = ic->ic_inact_auth; 1277 else 1278 si->isi_inact = ic->ic_inact_init; 1279 si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT; 1280 1281 cp = (u_int8_t *)(si+1); 1282 if (ni->ni_wpa_ie != NULL) { 1283 memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]); 1284 cp += 2+ni->ni_wpa_ie[1]; 1285 } 1286 if (ni->ni_wme_ie != NULL) { 1287 memcpy(cp, ni->ni_wme_ie, 2+ni->ni_wme_ie[1]); 1288 cp += 2+ni->ni_wme_ie[1]; 1289 } 1290 1291 req->si = (struct ieee80211req_sta_info *)(((u_int8_t *)si) + len); 1292 req->space -= len; 1293 } 1294 1295 static int 1296 ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq) 1297 { 1298 struct stainforeq req; 1299 int error; 1300 1301 if (ireq->i_len < sizeof(struct stainforeq)) 1302 return EFAULT; 1303 1304 error = 0; 1305 req.space = 0; 1306 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); 1307 if (req.space > ireq->i_len) 1308 req.space = ireq->i_len; 1309 if (req.space > 0) { 1310 size_t space; 1311 void *p; 1312 1313 space = req.space; 1314 /* XXX M_WAITOK after driver lock released */ 1315 MALLOC(p, void *, space, M_TEMP, M_NOWAIT); 1316 if (p == NULL) 1317 return ENOMEM; 1318 req.si = p; 1319 ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); 1320 ireq->i_len = space - req.space; 1321 error = copyout(p, ireq->i_data, ireq->i_len); 1322 FREE(p, M_TEMP); 1323 } else 1324 ireq->i_len = 0; 1325 1326 return error; 1327 } 1328 1329 static int 1330 ieee80211_ioctl_getstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq) 1331 { 1332 struct ieee80211_node *ni; 1333 struct ieee80211req_sta_txpow txpow; 1334 int error; 1335 1336 if (ireq->i_len != sizeof(txpow)) 1337 return EINVAL; 1338 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 1339 if (error != 0) 1340 return error; 1341 ni = ieee80211_find_node(&ic->ic_sta, txpow.it_macaddr); 1342 if (ni == NULL) 1343 return EINVAL; /* XXX */ 1344 txpow.it_txpow = ni->ni_txpower; 1345 error = copyout(&txpow, ireq->i_data, sizeof(txpow)); 1346 ieee80211_free_node(ni); 1347 return error; 1348 } 1349 1350 static int 1351 ieee80211_ioctl_getwmeparam(struct ieee80211com *ic, struct ieee80211req *ireq) 1352 { 1353 struct ieee80211_wme_state *wme = &ic->ic_wme; 1354 struct wmeParams *wmep; 1355 int ac; 1356 1357 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 1358 return EINVAL; 1359 1360 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 1361 if (ac >= WME_NUM_AC) 1362 ac = WME_AC_BE; 1363 if (ireq->i_len & IEEE80211_WMEPARAM_BSS) 1364 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 1365 else 1366 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 1367 switch (ireq->i_type) { 1368 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1369 ireq->i_val = wmep->wmep_logcwmin; 1370 break; 1371 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1372 ireq->i_val = wmep->wmep_logcwmax; 1373 break; 1374 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1375 ireq->i_val = wmep->wmep_aifsn; 1376 break; 1377 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1378 ireq->i_val = wmep->wmep_txopLimit; 1379 break; 1380 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 1381 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 1382 ireq->i_val = wmep->wmep_acm; 1383 break; 1384 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 1385 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 1386 ireq->i_val = !wmep->wmep_noackPolicy; 1387 break; 1388 } 1389 return 0; 1390 } 1391 1392 static int 1393 ieee80211_ioctl_getmaccmd(struct ieee80211com *ic, struct ieee80211req *ireq) 1394 { 1395 const struct ieee80211_aclator *acl = ic->ic_acl; 1396 1397 return (acl == NULL ? EINVAL : acl->iac_getioctl(ic, ireq)); 1398 } 1399 1400 /* 1401 * When building the kernel with -O2 on the i386 architecture, gcc 1402 * seems to want to inline this function into ieee80211_ioctl() 1403 * (which is the only routine that calls it). When this happens, 1404 * ieee80211_ioctl() ends up consuming an additional 2K of stack 1405 * space. (Exactly why it needs so much is unclear.) The problem 1406 * is that it's possible for ieee80211_ioctl() to invoke other 1407 * routines (including driver init functions) which could then find 1408 * themselves perilously close to exhausting the stack. 1409 * 1410 * To avoid this, we deliberately prevent gcc from inlining this 1411 * routine. Another way to avoid this is to use less agressive 1412 * optimization when compiling this file (i.e. -O instead of -O2) 1413 * but special-casing the compilation of this one module in the 1414 * build system would be awkward. 1415 */ 1416 #ifdef __GNUC__ 1417 __attribute__ ((noinline)) 1418 #endif 1419 static int 1420 ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211req *ireq) 1421 { 1422 const struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn; 1423 int error = 0; 1424 u_int kid, len, m; 1425 u_int8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 1426 char tmpssid[IEEE80211_NWID_LEN]; 1427 1428 switch (ireq->i_type) { 1429 case IEEE80211_IOC_SSID: 1430 switch (ic->ic_state) { 1431 case IEEE80211_S_INIT: 1432 case IEEE80211_S_SCAN: 1433 ireq->i_len = ic->ic_des_esslen; 1434 memcpy(tmpssid, ic->ic_des_essid, ireq->i_len); 1435 break; 1436 default: 1437 ireq->i_len = ic->ic_bss->ni_esslen; 1438 memcpy(tmpssid, ic->ic_bss->ni_essid, 1439 ireq->i_len); 1440 break; 1441 } 1442 error = copyout(tmpssid, ireq->i_data, ireq->i_len); 1443 break; 1444 case IEEE80211_IOC_NUMSSIDS: 1445 ireq->i_val = 1; 1446 break; 1447 case IEEE80211_IOC_WEP: 1448 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) 1449 ireq->i_val = IEEE80211_WEP_OFF; 1450 else if (ic->ic_flags & IEEE80211_F_DROPUNENC) 1451 ireq->i_val = IEEE80211_WEP_ON; 1452 else 1453 ireq->i_val = IEEE80211_WEP_MIXED; 1454 break; 1455 case IEEE80211_IOC_WEPKEY: 1456 kid = (u_int) ireq->i_val; 1457 if (kid >= IEEE80211_WEP_NKID) 1458 return EINVAL; 1459 len = (u_int) ic->ic_nw_keys[kid].wk_keylen; 1460 /* NB: only root can read WEP keys */ 1461 if (suser(curthread) == 0) { 1462 bcopy(ic->ic_nw_keys[kid].wk_key, tmpkey, len); 1463 } else { 1464 bzero(tmpkey, len); 1465 } 1466 ireq->i_len = len; 1467 error = copyout(tmpkey, ireq->i_data, len); 1468 break; 1469 case IEEE80211_IOC_NUMWEPKEYS: 1470 ireq->i_val = IEEE80211_WEP_NKID; 1471 break; 1472 case IEEE80211_IOC_WEPTXKEY: 1473 ireq->i_val = ic->ic_def_txkey; 1474 break; 1475 case IEEE80211_IOC_AUTHMODE: 1476 if (ic->ic_flags & IEEE80211_F_WPA) 1477 ireq->i_val = IEEE80211_AUTH_WPA; 1478 else 1479 ireq->i_val = ic->ic_bss->ni_authmode; 1480 break; 1481 case IEEE80211_IOC_CHANNEL: 1482 ireq->i_val = ieee80211_chan2ieee(ic, ic->ic_curchan); 1483 break; 1484 case IEEE80211_IOC_POWERSAVE: 1485 if (ic->ic_flags & IEEE80211_F_PMGTON) 1486 ireq->i_val = IEEE80211_POWERSAVE_ON; 1487 else 1488 ireq->i_val = IEEE80211_POWERSAVE_OFF; 1489 break; 1490 case IEEE80211_IOC_POWERSAVESLEEP: 1491 ireq->i_val = ic->ic_lintval; 1492 break; 1493 case IEEE80211_IOC_RTSTHRESHOLD: 1494 ireq->i_val = ic->ic_rtsthreshold; 1495 break; 1496 case IEEE80211_IOC_PROTMODE: 1497 ireq->i_val = ic->ic_protmode; 1498 break; 1499 case IEEE80211_IOC_TXPOWER: 1500 if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) 1501 return EINVAL; 1502 ireq->i_val = ic->ic_txpowlimit; 1503 break; 1504 case IEEE80211_IOC_MCASTCIPHER: 1505 ireq->i_val = rsn->rsn_mcastcipher; 1506 break; 1507 case IEEE80211_IOC_MCASTKEYLEN: 1508 ireq->i_val = rsn->rsn_mcastkeylen; 1509 break; 1510 case IEEE80211_IOC_UCASTCIPHERS: 1511 ireq->i_val = 0; 1512 for (m = 0x1; m != 0; m <<= 1) 1513 if (rsn->rsn_ucastcipherset & m) 1514 ireq->i_val |= 1<<cap2cipher(m); 1515 break; 1516 case IEEE80211_IOC_UCASTCIPHER: 1517 ireq->i_val = rsn->rsn_ucastcipher; 1518 break; 1519 case IEEE80211_IOC_UCASTKEYLEN: 1520 ireq->i_val = rsn->rsn_ucastkeylen; 1521 break; 1522 case IEEE80211_IOC_KEYMGTALGS: 1523 ireq->i_val = rsn->rsn_keymgmtset; 1524 break; 1525 case IEEE80211_IOC_RSNCAPS: 1526 ireq->i_val = rsn->rsn_caps; 1527 break; 1528 case IEEE80211_IOC_WPA: 1529 switch (ic->ic_flags & IEEE80211_F_WPA) { 1530 case IEEE80211_F_WPA1: 1531 ireq->i_val = 1; 1532 break; 1533 case IEEE80211_F_WPA2: 1534 ireq->i_val = 2; 1535 break; 1536 case IEEE80211_F_WPA1 | IEEE80211_F_WPA2: 1537 ireq->i_val = 3; 1538 break; 1539 default: 1540 ireq->i_val = 0; 1541 break; 1542 } 1543 break; 1544 case IEEE80211_IOC_CHANLIST: 1545 error = ieee80211_ioctl_getchanlist(ic, ireq); 1546 break; 1547 case IEEE80211_IOC_ROAMING: 1548 ireq->i_val = ic->ic_roaming; 1549 break; 1550 case IEEE80211_IOC_PRIVACY: 1551 ireq->i_val = (ic->ic_flags & IEEE80211_F_PRIVACY) != 0; 1552 break; 1553 case IEEE80211_IOC_DROPUNENCRYPTED: 1554 ireq->i_val = (ic->ic_flags & IEEE80211_F_DROPUNENC) != 0; 1555 break; 1556 case IEEE80211_IOC_COUNTERMEASURES: 1557 ireq->i_val = (ic->ic_flags & IEEE80211_F_COUNTERM) != 0; 1558 break; 1559 case IEEE80211_IOC_DRIVER_CAPS: 1560 ireq->i_val = ic->ic_caps>>16; 1561 ireq->i_len = ic->ic_caps&0xffff; 1562 break; 1563 case IEEE80211_IOC_WME: 1564 ireq->i_val = (ic->ic_flags & IEEE80211_F_WME) != 0; 1565 break; 1566 case IEEE80211_IOC_HIDESSID: 1567 ireq->i_val = (ic->ic_flags & IEEE80211_F_HIDESSID) != 0; 1568 break; 1569 case IEEE80211_IOC_APBRIDGE: 1570 ireq->i_val = (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0; 1571 break; 1572 case IEEE80211_IOC_OPTIE: 1573 if (ic->ic_opt_ie == NULL) 1574 return EINVAL; 1575 /* NB: truncate, caller can check length */ 1576 if (ireq->i_len > ic->ic_opt_ie_len) 1577 ireq->i_len = ic->ic_opt_ie_len; 1578 error = copyout(ic->ic_opt_ie, ireq->i_data, ireq->i_len); 1579 break; 1580 case IEEE80211_IOC_WPAKEY: 1581 error = ieee80211_ioctl_getkey(ic, ireq); 1582 break; 1583 case IEEE80211_IOC_CHANINFO: 1584 error = ieee80211_ioctl_getchaninfo(ic, ireq); 1585 break; 1586 case IEEE80211_IOC_BSSID: 1587 if (ireq->i_len != IEEE80211_ADDR_LEN) 1588 return EINVAL; 1589 error = copyout(ic->ic_state == IEEE80211_S_RUN ? 1590 ic->ic_bss->ni_bssid : 1591 ic->ic_des_bssid, 1592 ireq->i_data, ireq->i_len); 1593 break; 1594 case IEEE80211_IOC_WPAIE: 1595 error = ieee80211_ioctl_getwpaie(ic, ireq); 1596 break; 1597 #ifdef COMPAT_FREEBSD6 1598 case IEEE80211_IOC_SCAN_RESULTS_OLD: 1599 error = old_getscanresults(ic, ireq); 1600 break; 1601 #endif 1602 case IEEE80211_IOC_SCAN_RESULTS: 1603 error = ieee80211_ioctl_getscanresults(ic, ireq); 1604 break; 1605 case IEEE80211_IOC_STA_STATS: 1606 error = ieee80211_ioctl_getstastats(ic, ireq); 1607 break; 1608 case IEEE80211_IOC_TXPOWMAX: 1609 ireq->i_val = ic->ic_bss->ni_txpower; 1610 break; 1611 case IEEE80211_IOC_STA_TXPOW: 1612 error = ieee80211_ioctl_getstatxpow(ic, ireq); 1613 break; 1614 case IEEE80211_IOC_STA_INFO: 1615 error = ieee80211_ioctl_getstainfo(ic, ireq); 1616 break; 1617 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 1618 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 1619 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 1620 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 1621 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 1622 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 1623 error = ieee80211_ioctl_getwmeparam(ic, ireq); 1624 break; 1625 case IEEE80211_IOC_DTIM_PERIOD: 1626 ireq->i_val = ic->ic_dtim_period; 1627 break; 1628 case IEEE80211_IOC_BEACON_INTERVAL: 1629 /* NB: get from ic_bss for station mode */ 1630 ireq->i_val = ic->ic_bss->ni_intval; 1631 break; 1632 case IEEE80211_IOC_PUREG: 1633 ireq->i_val = (ic->ic_flags & IEEE80211_F_PUREG) != 0; 1634 break; 1635 case IEEE80211_IOC_MCAST_RATE: 1636 ireq->i_val = ic->ic_mcast_rate; 1637 break; 1638 case IEEE80211_IOC_FRAGTHRESHOLD: 1639 ireq->i_val = ic->ic_fragthreshold; 1640 break; 1641 case IEEE80211_IOC_MACCMD: 1642 error = ieee80211_ioctl_getmaccmd(ic, ireq); 1643 break; 1644 case IEEE80211_IOC_BURST: 1645 ireq->i_val = (ic->ic_flags & IEEE80211_F_BURST) != 0; 1646 break; 1647 default: 1648 error = EINVAL; 1649 break; 1650 } 1651 return error; 1652 } 1653 1654 static int 1655 ieee80211_ioctl_setoptie(struct ieee80211com *ic, struct ieee80211req *ireq) 1656 { 1657 int error; 1658 void *ie, *oie; 1659 1660 /* 1661 * NB: Doing this for ap operation could be useful (e.g. for 1662 * WPA and/or WME) except that it typically is worthless 1663 * without being able to intervene when processing 1664 * association response frames--so disallow it for now. 1665 */ 1666 if (ic->ic_opmode != IEEE80211_M_STA) 1667 return EINVAL; 1668 if (ireq->i_len > IEEE80211_MAX_OPT_IE) 1669 return EINVAL; 1670 if (ireq->i_len > 0) { 1671 MALLOC(ie, void *, ireq->i_len, M_DEVBUF, M_NOWAIT); 1672 if (ie == NULL) 1673 return ENOMEM; 1674 error = copyin(ireq->i_data, ie, ireq->i_len); 1675 if (error) { 1676 FREE(ie, M_DEVBUF); 1677 return error; 1678 } 1679 } else { 1680 ie = NULL; 1681 ireq->i_len = 0; 1682 } 1683 /* XXX sanity check data? */ 1684 oie = ic->ic_opt_ie; 1685 ic->ic_opt_ie = ie; 1686 ic->ic_opt_ie_len = ireq->i_len; 1687 if (oie != NULL) 1688 FREE(oie, M_DEVBUF); 1689 return 0; 1690 } 1691 1692 static int 1693 ieee80211_ioctl_setkey(struct ieee80211com *ic, struct ieee80211req *ireq) 1694 { 1695 struct ieee80211req_key ik; 1696 struct ieee80211_node *ni; 1697 struct ieee80211_key *wk; 1698 u_int16_t kid; 1699 int error; 1700 1701 if (ireq->i_len != sizeof(ik)) 1702 return EINVAL; 1703 error = copyin(ireq->i_data, &ik, sizeof(ik)); 1704 if (error) 1705 return error; 1706 /* NB: cipher support is verified by ieee80211_crypt_newkey */ 1707 /* NB: this also checks ik->ik_keylen > sizeof(wk->wk_key) */ 1708 if (ik.ik_keylen > sizeof(ik.ik_keydata)) 1709 return E2BIG; 1710 kid = ik.ik_keyix; 1711 if (kid == IEEE80211_KEYIX_NONE) { 1712 /* XXX unicast keys currently must be tx/rx */ 1713 if (ik.ik_flags != (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV)) 1714 return EINVAL; 1715 if (ic->ic_opmode == IEEE80211_M_STA) { 1716 ni = ieee80211_ref_node(ic->ic_bss); 1717 if (!IEEE80211_ADDR_EQ(ik.ik_macaddr, ni->ni_bssid)) { 1718 ieee80211_free_node(ni); 1719 return EADDRNOTAVAIL; 1720 } 1721 } else { 1722 ni = ieee80211_find_node(&ic->ic_sta, ik.ik_macaddr); 1723 if (ni == NULL) 1724 return ENOENT; 1725 } 1726 wk = &ni->ni_ucastkey; 1727 } else { 1728 if (kid >= IEEE80211_WEP_NKID) 1729 return EINVAL; 1730 wk = &ic->ic_nw_keys[kid]; 1731 /* 1732 * Global slots start off w/o any assigned key index. 1733 * Force one here for consistency with IEEE80211_IOC_WEPKEY. 1734 */ 1735 if (wk->wk_keyix == IEEE80211_KEYIX_NONE) 1736 wk->wk_keyix = kid; 1737 ni = NULL; 1738 } 1739 error = 0; 1740 ieee80211_key_update_begin(ic); 1741 if (ieee80211_crypto_newkey(ic, ik.ik_type, ik.ik_flags, wk)) { 1742 wk->wk_keylen = ik.ik_keylen; 1743 /* NB: MIC presence is implied by cipher type */ 1744 if (wk->wk_keylen > IEEE80211_KEYBUF_SIZE) 1745 wk->wk_keylen = IEEE80211_KEYBUF_SIZE; 1746 wk->wk_keyrsc = ik.ik_keyrsc; 1747 wk->wk_keytsc = 0; /* new key, reset */ 1748 memset(wk->wk_key, 0, sizeof(wk->wk_key)); 1749 memcpy(wk->wk_key, ik.ik_keydata, ik.ik_keylen); 1750 if (!ieee80211_crypto_setkey(ic, wk, 1751 ni != NULL ? ni->ni_macaddr : ik.ik_macaddr)) 1752 error = EIO; 1753 else if ((ik.ik_flags & IEEE80211_KEY_DEFAULT)) 1754 ic->ic_def_txkey = kid; 1755 } else 1756 error = ENXIO; 1757 ieee80211_key_update_end(ic); 1758 if (ni != NULL) 1759 ieee80211_free_node(ni); 1760 return error; 1761 } 1762 1763 static int 1764 ieee80211_ioctl_delkey(struct ieee80211com *ic, struct ieee80211req *ireq) 1765 { 1766 struct ieee80211req_del_key dk; 1767 int kid, error; 1768 1769 if (ireq->i_len != sizeof(dk)) 1770 return EINVAL; 1771 error = copyin(ireq->i_data, &dk, sizeof(dk)); 1772 if (error) 1773 return error; 1774 kid = dk.idk_keyix; 1775 /* XXX u_int8_t -> u_int16_t */ 1776 if (dk.idk_keyix == (u_int8_t) IEEE80211_KEYIX_NONE) { 1777 struct ieee80211_node *ni; 1778 1779 if (ic->ic_opmode == IEEE80211_M_STA) { 1780 ni = ieee80211_ref_node(ic->ic_bss); 1781 if (!IEEE80211_ADDR_EQ(dk.idk_macaddr, ni->ni_bssid)) { 1782 ieee80211_free_node(ni); 1783 return EADDRNOTAVAIL; 1784 } 1785 } else { 1786 ni = ieee80211_find_node(&ic->ic_sta, dk.idk_macaddr); 1787 if (ni == NULL) 1788 return ENOENT; 1789 } 1790 /* XXX error return */ 1791 ieee80211_node_delucastkey(ni); 1792 ieee80211_free_node(ni); 1793 } else { 1794 if (kid >= IEEE80211_WEP_NKID) 1795 return EINVAL; 1796 /* XXX error return */ 1797 ieee80211_crypto_delkey(ic, &ic->ic_nw_keys[kid]); 1798 } 1799 return 0; 1800 } 1801 1802 static void 1803 domlme(void *arg, struct ieee80211_node *ni) 1804 { 1805 struct ieee80211com *ic = ni->ni_ic; 1806 struct ieee80211req_mlme *mlme = arg; 1807 1808 if (ni->ni_associd != 0) { 1809 IEEE80211_SEND_MGMT(ic, ni, 1810 mlme->im_op == IEEE80211_MLME_DEAUTH ? 1811 IEEE80211_FC0_SUBTYPE_DEAUTH : 1812 IEEE80211_FC0_SUBTYPE_DISASSOC, 1813 mlme->im_reason); 1814 } 1815 ieee80211_node_leave(ic, ni); 1816 } 1817 1818 static int 1819 ieee80211_ioctl_setmlme(struct ieee80211com *ic, struct ieee80211req *ireq) 1820 { 1821 struct ieee80211req_mlme mlme; 1822 struct ieee80211_node *ni; 1823 int error; 1824 1825 if (ireq->i_len != sizeof(mlme)) 1826 return EINVAL; 1827 error = copyin(ireq->i_data, &mlme, sizeof(mlme)); 1828 if (error) 1829 return error; 1830 switch (mlme.im_op) { 1831 case IEEE80211_MLME_ASSOC: 1832 if (ic->ic_opmode != IEEE80211_M_STA) 1833 return EINVAL; 1834 /* XXX must be in S_SCAN state? */ 1835 1836 if (mlme.im_ssid_len != 0) { 1837 /* 1838 * Desired ssid specified; must match both bssid and 1839 * ssid to distinguish ap advertising multiple ssid's. 1840 */ 1841 ni = ieee80211_find_node_with_ssid(&ic->ic_scan, 1842 mlme.im_macaddr, 1843 mlme.im_ssid_len, mlme.im_ssid); 1844 } else { 1845 /* 1846 * Normal case; just match bssid. 1847 */ 1848 ni = ieee80211_find_node(&ic->ic_scan, mlme.im_macaddr); 1849 } 1850 if (ni == NULL) 1851 return EINVAL; 1852 if (!ieee80211_sta_join(ic, ni)) { 1853 ieee80211_free_node(ni); 1854 return EINVAL; 1855 } 1856 break; 1857 case IEEE80211_MLME_DISASSOC: 1858 case IEEE80211_MLME_DEAUTH: 1859 switch (ic->ic_opmode) { 1860 case IEEE80211_M_STA: 1861 /* XXX not quite right */ 1862 ieee80211_new_state(ic, IEEE80211_S_INIT, 1863 mlme.im_reason); 1864 break; 1865 case IEEE80211_M_HOSTAP: 1866 /* NB: the broadcast address means do 'em all */ 1867 if (!IEEE80211_ADDR_EQ(mlme.im_macaddr, ic->ic_ifp->if_broadcastaddr)) { 1868 if ((ni = ieee80211_find_node(&ic->ic_sta, 1869 mlme.im_macaddr)) == NULL) 1870 return EINVAL; 1871 domlme(&mlme, ni); 1872 ieee80211_free_node(ni); 1873 } else { 1874 ieee80211_iterate_nodes(&ic->ic_sta, 1875 domlme, &mlme); 1876 } 1877 break; 1878 default: 1879 return EINVAL; 1880 } 1881 break; 1882 case IEEE80211_MLME_AUTHORIZE: 1883 case IEEE80211_MLME_UNAUTHORIZE: 1884 if (ic->ic_opmode != IEEE80211_M_HOSTAP) 1885 return EINVAL; 1886 ni = ieee80211_find_node(&ic->ic_sta, mlme.im_macaddr); 1887 if (ni == NULL) 1888 return EINVAL; 1889 if (mlme.im_op == IEEE80211_MLME_AUTHORIZE) 1890 ieee80211_node_authorize(ni); 1891 else 1892 ieee80211_node_unauthorize(ni); 1893 ieee80211_free_node(ni); 1894 break; 1895 default: 1896 return EINVAL; 1897 } 1898 return 0; 1899 } 1900 1901 static int 1902 ieee80211_ioctl_macmac(struct ieee80211com *ic, struct ieee80211req *ireq) 1903 { 1904 u_int8_t mac[IEEE80211_ADDR_LEN]; 1905 const struct ieee80211_aclator *acl = ic->ic_acl; 1906 int error; 1907 1908 if (ireq->i_len != sizeof(mac)) 1909 return EINVAL; 1910 error = copyin(ireq->i_data, mac, ireq->i_len); 1911 if (error) 1912 return error; 1913 if (acl == NULL) { 1914 acl = ieee80211_aclator_get("mac"); 1915 if (acl == NULL || !acl->iac_attach(ic)) 1916 return EINVAL; 1917 ic->ic_acl = acl; 1918 } 1919 if (ireq->i_type == IEEE80211_IOC_ADDMAC) 1920 acl->iac_add(ic, mac); 1921 else 1922 acl->iac_remove(ic, mac); 1923 return 0; 1924 } 1925 1926 static int 1927 ieee80211_ioctl_setmaccmd(struct ieee80211com *ic, struct ieee80211req *ireq) 1928 { 1929 const struct ieee80211_aclator *acl = ic->ic_acl; 1930 1931 switch (ireq->i_val) { 1932 case IEEE80211_MACCMD_POLICY_OPEN: 1933 case IEEE80211_MACCMD_POLICY_ALLOW: 1934 case IEEE80211_MACCMD_POLICY_DENY: 1935 if (acl == NULL) { 1936 acl = ieee80211_aclator_get("mac"); 1937 if (acl == NULL || !acl->iac_attach(ic)) 1938 return EINVAL; 1939 ic->ic_acl = acl; 1940 } 1941 acl->iac_setpolicy(ic, ireq->i_val); 1942 break; 1943 case IEEE80211_MACCMD_FLUSH: 1944 if (acl != NULL) 1945 acl->iac_flush(ic); 1946 /* NB: silently ignore when not in use */ 1947 break; 1948 case IEEE80211_MACCMD_DETACH: 1949 if (acl != NULL) { 1950 ic->ic_acl = NULL; 1951 acl->iac_detach(ic); 1952 } 1953 break; 1954 default: 1955 if (acl == NULL) 1956 return EINVAL; 1957 else 1958 return acl->iac_setioctl(ic, ireq); 1959 } 1960 return 0; 1961 } 1962 1963 static int 1964 ieee80211_ioctl_setchanlist(struct ieee80211com *ic, struct ieee80211req *ireq) 1965 { 1966 struct ieee80211req_chanlist list; 1967 u_char chanlist[IEEE80211_CHAN_BYTES]; 1968 int i, j, error; 1969 1970 if (ireq->i_len != sizeof(list)) 1971 return EINVAL; 1972 error = copyin(ireq->i_data, &list, sizeof(list)); 1973 if (error) 1974 return error; 1975 memset(chanlist, 0, sizeof(chanlist)); 1976 /* 1977 * Since channel 0 is not available for DS, channel 1 1978 * is assigned to LSB on WaveLAN. 1979 */ 1980 if (ic->ic_phytype == IEEE80211_T_DS) 1981 i = 1; 1982 else 1983 i = 0; 1984 for (j = 0; i <= IEEE80211_CHAN_MAX; i++, j++) { 1985 /* 1986 * NB: silently discard unavailable channels so users 1987 * can specify 1-255 to get all available channels. 1988 */ 1989 if (isset(list.ic_channels, j) && isset(ic->ic_chan_avail, i)) 1990 setbit(chanlist, i); 1991 } 1992 if (ic->ic_ibss_chan == NULL || 1993 isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) { 1994 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) 1995 if (isset(chanlist, i)) { 1996 ic->ic_ibss_chan = &ic->ic_channels[i]; 1997 goto found; 1998 } 1999 return EINVAL; /* no active channels */ 2000 found: 2001 ; 2002 } 2003 memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active)); 2004 return IS_UP_AUTO(ic) ? ENETRESET : 0; 2005 } 2006 2007 static int 2008 ieee80211_ioctl_setstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq) 2009 { 2010 struct ieee80211_node *ni; 2011 struct ieee80211req_sta_txpow txpow; 2012 int error; 2013 2014 if (ireq->i_len != sizeof(txpow)) 2015 return EINVAL; 2016 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 2017 if (error != 0) 2018 return error; 2019 ni = ieee80211_find_node(&ic->ic_sta, txpow.it_macaddr); 2020 if (ni == NULL) 2021 return EINVAL; /* XXX */ 2022 ni->ni_txpower = txpow.it_txpow; 2023 ieee80211_free_node(ni); 2024 return error; 2025 } 2026 2027 static int 2028 ieee80211_ioctl_setwmeparam(struct ieee80211com *ic, struct ieee80211req *ireq) 2029 { 2030 struct ieee80211_wme_state *wme = &ic->ic_wme; 2031 struct wmeParams *wmep, *chanp; 2032 int isbss, ac; 2033 2034 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 2035 return EINVAL; 2036 2037 isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); 2038 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 2039 if (ac >= WME_NUM_AC) 2040 ac = WME_AC_BE; 2041 if (isbss) { 2042 chanp = &wme->wme_bssChanParams.cap_wmeParams[ac]; 2043 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 2044 } else { 2045 chanp = &wme->wme_chanParams.cap_wmeParams[ac]; 2046 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 2047 } 2048 switch (ireq->i_type) { 2049 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2050 if (isbss) { 2051 wmep->wmep_logcwmin = ireq->i_val; 2052 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2053 chanp->wmep_logcwmin = ireq->i_val; 2054 } else { 2055 wmep->wmep_logcwmin = chanp->wmep_logcwmin = 2056 ireq->i_val; 2057 } 2058 break; 2059 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2060 if (isbss) { 2061 wmep->wmep_logcwmax = ireq->i_val; 2062 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2063 chanp->wmep_logcwmax = ireq->i_val; 2064 } else { 2065 wmep->wmep_logcwmax = chanp->wmep_logcwmax = 2066 ireq->i_val; 2067 } 2068 break; 2069 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2070 if (isbss) { 2071 wmep->wmep_aifsn = ireq->i_val; 2072 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2073 chanp->wmep_aifsn = ireq->i_val; 2074 } else { 2075 wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; 2076 } 2077 break; 2078 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2079 if (isbss) { 2080 wmep->wmep_txopLimit = ireq->i_val; 2081 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2082 chanp->wmep_txopLimit = ireq->i_val; 2083 } else { 2084 wmep->wmep_txopLimit = chanp->wmep_txopLimit = 2085 ireq->i_val; 2086 } 2087 break; 2088 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2089 wmep->wmep_acm = ireq->i_val; 2090 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2091 chanp->wmep_acm = ireq->i_val; 2092 break; 2093 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 2094 wmep->wmep_noackPolicy = chanp->wmep_noackPolicy = 2095 (ireq->i_val) == 0; 2096 break; 2097 } 2098 ieee80211_wme_updateparams(ic); 2099 return 0; 2100 } 2101 2102 static int 2103 cipher2cap(int cipher) 2104 { 2105 switch (cipher) { 2106 case IEEE80211_CIPHER_WEP: return IEEE80211_C_WEP; 2107 case IEEE80211_CIPHER_AES_OCB: return IEEE80211_C_AES; 2108 case IEEE80211_CIPHER_AES_CCM: return IEEE80211_C_AES_CCM; 2109 case IEEE80211_CIPHER_CKIP: return IEEE80211_C_CKIP; 2110 case IEEE80211_CIPHER_TKIP: return IEEE80211_C_TKIP; 2111 } 2112 return 0; 2113 } 2114 2115 static int 2116 ieee80211_ioctl_set80211(struct ieee80211com *ic, u_long cmd, struct ieee80211req *ireq) 2117 { 2118 static const u_int8_t zerobssid[IEEE80211_ADDR_LEN]; 2119 struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn; 2120 int error; 2121 const struct ieee80211_authenticator *auth; 2122 u_int8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 2123 char tmpssid[IEEE80211_NWID_LEN]; 2124 u_int8_t tmpbssid[IEEE80211_ADDR_LEN]; 2125 struct ieee80211_key *k; 2126 int j, caps; 2127 u_int kid; 2128 2129 error = 0; 2130 switch (ireq->i_type) { 2131 case IEEE80211_IOC_SSID: 2132 if (ireq->i_val != 0 || 2133 ireq->i_len > IEEE80211_NWID_LEN) 2134 return EINVAL; 2135 error = copyin(ireq->i_data, tmpssid, ireq->i_len); 2136 if (error) 2137 break; 2138 memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN); 2139 ic->ic_des_esslen = ireq->i_len; 2140 memcpy(ic->ic_des_essid, tmpssid, ireq->i_len); 2141 error = ENETRESET; 2142 break; 2143 case IEEE80211_IOC_WEP: 2144 switch (ireq->i_val) { 2145 case IEEE80211_WEP_OFF: 2146 ic->ic_flags &= ~IEEE80211_F_PRIVACY; 2147 ic->ic_flags &= ~IEEE80211_F_DROPUNENC; 2148 break; 2149 case IEEE80211_WEP_ON: 2150 ic->ic_flags |= IEEE80211_F_PRIVACY; 2151 ic->ic_flags |= IEEE80211_F_DROPUNENC; 2152 break; 2153 case IEEE80211_WEP_MIXED: 2154 ic->ic_flags |= IEEE80211_F_PRIVACY; 2155 ic->ic_flags &= ~IEEE80211_F_DROPUNENC; 2156 break; 2157 } 2158 error = ENETRESET; 2159 break; 2160 case IEEE80211_IOC_WEPKEY: 2161 kid = (u_int) ireq->i_val; 2162 if (kid >= IEEE80211_WEP_NKID) 2163 return EINVAL; 2164 k = &ic->ic_nw_keys[kid]; 2165 if (ireq->i_len == 0) { 2166 /* zero-len =>'s delete any existing key */ 2167 (void) ieee80211_crypto_delkey(ic, k); 2168 break; 2169 } 2170 if (ireq->i_len > sizeof(tmpkey)) 2171 return EINVAL; 2172 memset(tmpkey, 0, sizeof(tmpkey)); 2173 error = copyin(ireq->i_data, tmpkey, ireq->i_len); 2174 if (error) 2175 break; 2176 ieee80211_key_update_begin(ic); 2177 k->wk_keyix = kid; /* NB: force fixed key id */ 2178 if (ieee80211_crypto_newkey(ic, IEEE80211_CIPHER_WEP, 2179 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) { 2180 k->wk_keylen = ireq->i_len; 2181 memcpy(k->wk_key, tmpkey, sizeof(tmpkey)); 2182 if (!ieee80211_crypto_setkey(ic, k, ic->ic_myaddr)) 2183 error = EINVAL; 2184 } else 2185 error = EINVAL; 2186 ieee80211_key_update_end(ic); 2187 if (!error) /* NB: for compatibility */ 2188 error = ENETRESET; 2189 break; 2190 case IEEE80211_IOC_WEPTXKEY: 2191 kid = (u_int) ireq->i_val; 2192 if (kid >= IEEE80211_WEP_NKID && 2193 (u_int16_t) kid != IEEE80211_KEYIX_NONE) 2194 return EINVAL; 2195 ic->ic_def_txkey = kid; 2196 error = ENETRESET; /* push to hardware */ 2197 break; 2198 case IEEE80211_IOC_AUTHMODE: 2199 switch (ireq->i_val) { 2200 case IEEE80211_AUTH_WPA: 2201 case IEEE80211_AUTH_8021X: /* 802.1x */ 2202 case IEEE80211_AUTH_OPEN: /* open */ 2203 case IEEE80211_AUTH_SHARED: /* shared-key */ 2204 case IEEE80211_AUTH_AUTO: /* auto */ 2205 auth = ieee80211_authenticator_get(ireq->i_val); 2206 if (auth == NULL) 2207 return EINVAL; 2208 break; 2209 default: 2210 return EINVAL; 2211 } 2212 switch (ireq->i_val) { 2213 case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ 2214 ic->ic_flags |= IEEE80211_F_PRIVACY; 2215 ireq->i_val = IEEE80211_AUTH_8021X; 2216 break; 2217 case IEEE80211_AUTH_OPEN: /* open */ 2218 ic->ic_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY); 2219 break; 2220 case IEEE80211_AUTH_SHARED: /* shared-key */ 2221 case IEEE80211_AUTH_8021X: /* 802.1x */ 2222 ic->ic_flags &= ~IEEE80211_F_WPA; 2223 /* both require a key so mark the PRIVACY capability */ 2224 ic->ic_flags |= IEEE80211_F_PRIVACY; 2225 break; 2226 case IEEE80211_AUTH_AUTO: /* auto */ 2227 ic->ic_flags &= ~IEEE80211_F_WPA; 2228 /* XXX PRIVACY handling? */ 2229 /* XXX what's the right way to do this? */ 2230 break; 2231 } 2232 /* NB: authenticator attach/detach happens on state change */ 2233 ic->ic_bss->ni_authmode = ireq->i_val; 2234 /* XXX mixed/mode/usage? */ 2235 ic->ic_auth = auth; 2236 error = ENETRESET; 2237 break; 2238 case IEEE80211_IOC_CHANNEL: 2239 /* XXX 0xffff overflows 16-bit signed */ 2240 if (ireq->i_val == 0 || 2241 ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) 2242 ic->ic_des_chan = IEEE80211_CHAN_ANYC; 2243 else if ((u_int) ireq->i_val > IEEE80211_CHAN_MAX || 2244 isclr(ic->ic_chan_active, ireq->i_val)) { 2245 return EINVAL; 2246 } else 2247 ic->ic_ibss_chan = ic->ic_des_chan = 2248 &ic->ic_channels[ireq->i_val]; 2249 switch (ic->ic_state) { 2250 case IEEE80211_S_INIT: 2251 case IEEE80211_S_SCAN: 2252 error = ENETRESET; 2253 break; 2254 default: 2255 /* 2256 * If the desired channel has changed (to something 2257 * other than any) and we're not already scanning, 2258 * then kick the state machine. 2259 */ 2260 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC && 2261 ic->ic_bss->ni_chan != ic->ic_des_chan && 2262 (ic->ic_flags & IEEE80211_F_SCAN) == 0) 2263 error = ENETRESET; 2264 break; 2265 } 2266 if (error == ENETRESET && 2267 ic->ic_opmode == IEEE80211_M_MONITOR) { 2268 if (IS_UP(ic)) { 2269 /* 2270 * Monitor mode can switch directly. 2271 */ 2272 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) 2273 ic->ic_curchan = ic->ic_des_chan; 2274 error = ic->ic_reset(ic->ic_ifp); 2275 } else 2276 error = 0; 2277 } 2278 break; 2279 case IEEE80211_IOC_POWERSAVE: 2280 switch (ireq->i_val) { 2281 case IEEE80211_POWERSAVE_OFF: 2282 if (ic->ic_flags & IEEE80211_F_PMGTON) { 2283 ic->ic_flags &= ~IEEE80211_F_PMGTON; 2284 error = ENETRESET; 2285 } 2286 break; 2287 case IEEE80211_POWERSAVE_ON: 2288 if ((ic->ic_caps & IEEE80211_C_PMGT) == 0) 2289 error = EINVAL; 2290 else if ((ic->ic_flags & IEEE80211_F_PMGTON) == 0) { 2291 ic->ic_flags |= IEEE80211_F_PMGTON; 2292 error = ENETRESET; 2293 } 2294 break; 2295 default: 2296 error = EINVAL; 2297 break; 2298 } 2299 break; 2300 case IEEE80211_IOC_POWERSAVESLEEP: 2301 if (ireq->i_val < 0) 2302 return EINVAL; 2303 ic->ic_lintval = ireq->i_val; 2304 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2305 break; 2306 case IEEE80211_IOC_RTSTHRESHOLD: 2307 if (!(IEEE80211_RTS_MIN <= ireq->i_val && 2308 ireq->i_val <= IEEE80211_RTS_MAX)) 2309 return EINVAL; 2310 ic->ic_rtsthreshold = ireq->i_val; 2311 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2312 break; 2313 case IEEE80211_IOC_PROTMODE: 2314 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 2315 return EINVAL; 2316 ic->ic_protmode = ireq->i_val; 2317 /* NB: if not operating in 11g this can wait */ 2318 if (ic->ic_curmode == IEEE80211_MODE_11G) 2319 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2320 break; 2321 case IEEE80211_IOC_TXPOWER: 2322 if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) 2323 return EINVAL; 2324 if (!(IEEE80211_TXPOWER_MIN < ireq->i_val && 2325 ireq->i_val < IEEE80211_TXPOWER_MAX)) 2326 return EINVAL; 2327 ic->ic_txpowlimit = ireq->i_val; 2328 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2329 break; 2330 case IEEE80211_IOC_ROAMING: 2331 if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val && 2332 ireq->i_val <= IEEE80211_ROAMING_MANUAL)) 2333 return EINVAL; 2334 ic->ic_roaming = ireq->i_val; 2335 /* XXXX reset? */ 2336 break; 2337 case IEEE80211_IOC_PRIVACY: 2338 if (ireq->i_val) { 2339 /* XXX check for key state? */ 2340 ic->ic_flags |= IEEE80211_F_PRIVACY; 2341 } else 2342 ic->ic_flags &= ~IEEE80211_F_PRIVACY; 2343 break; 2344 case IEEE80211_IOC_DROPUNENCRYPTED: 2345 if (ireq->i_val) 2346 ic->ic_flags |= IEEE80211_F_DROPUNENC; 2347 else 2348 ic->ic_flags &= ~IEEE80211_F_DROPUNENC; 2349 break; 2350 case IEEE80211_IOC_WPAKEY: 2351 error = ieee80211_ioctl_setkey(ic, ireq); 2352 break; 2353 case IEEE80211_IOC_DELKEY: 2354 error = ieee80211_ioctl_delkey(ic, ireq); 2355 break; 2356 case IEEE80211_IOC_MLME: 2357 error = ieee80211_ioctl_setmlme(ic, ireq); 2358 break; 2359 case IEEE80211_IOC_OPTIE: 2360 error = ieee80211_ioctl_setoptie(ic, ireq); 2361 break; 2362 case IEEE80211_IOC_COUNTERMEASURES: 2363 if (ireq->i_val) { 2364 if ((ic->ic_flags & IEEE80211_F_WPA) == 0) 2365 return EINVAL; 2366 ic->ic_flags |= IEEE80211_F_COUNTERM; 2367 } else 2368 ic->ic_flags &= ~IEEE80211_F_COUNTERM; 2369 break; 2370 case IEEE80211_IOC_WPA: 2371 if (ireq->i_val > 3) 2372 return EINVAL; 2373 /* XXX verify ciphers available */ 2374 ic->ic_flags &= ~IEEE80211_F_WPA; 2375 switch (ireq->i_val) { 2376 case 1: 2377 ic->ic_flags |= IEEE80211_F_WPA1; 2378 break; 2379 case 2: 2380 ic->ic_flags |= IEEE80211_F_WPA2; 2381 break; 2382 case 3: 2383 ic->ic_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; 2384 break; 2385 } 2386 error = ENETRESET; /* XXX? */ 2387 break; 2388 case IEEE80211_IOC_WME: 2389 if (ireq->i_val) { 2390 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 2391 return EINVAL; 2392 ic->ic_flags |= IEEE80211_F_WME; 2393 } else 2394 ic->ic_flags &= ~IEEE80211_F_WME; 2395 error = ENETRESET; /* XXX maybe not for station? */ 2396 break; 2397 case IEEE80211_IOC_HIDESSID: 2398 if (ireq->i_val) 2399 ic->ic_flags |= IEEE80211_F_HIDESSID; 2400 else 2401 ic->ic_flags &= ~IEEE80211_F_HIDESSID; 2402 error = ENETRESET; 2403 break; 2404 case IEEE80211_IOC_APBRIDGE: 2405 if (ireq->i_val == 0) 2406 ic->ic_flags |= IEEE80211_F_NOBRIDGE; 2407 else 2408 ic->ic_flags &= ~IEEE80211_F_NOBRIDGE; 2409 break; 2410 case IEEE80211_IOC_MCASTCIPHER: 2411 if ((ic->ic_caps & cipher2cap(ireq->i_val)) == 0 && 2412 !ieee80211_crypto_available(ireq->i_val)) 2413 return EINVAL; 2414 rsn->rsn_mcastcipher = ireq->i_val; 2415 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2416 break; 2417 case IEEE80211_IOC_MCASTKEYLEN: 2418 if (!(0 < ireq->i_val && ireq->i_val < IEEE80211_KEYBUF_SIZE)) 2419 return EINVAL; 2420 /* XXX no way to verify driver capability */ 2421 rsn->rsn_mcastkeylen = ireq->i_val; 2422 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2423 break; 2424 case IEEE80211_IOC_UCASTCIPHERS: 2425 /* 2426 * Convert user-specified cipher set to the set 2427 * we can support (via hardware or software). 2428 * NB: this logic intentionally ignores unknown and 2429 * unsupported ciphers so folks can specify 0xff or 2430 * similar and get all available ciphers. 2431 */ 2432 caps = 0; 2433 for (j = 1; j < 32; j++) /* NB: skip WEP */ 2434 if ((ireq->i_val & (1<<j)) && 2435 ((ic->ic_caps & cipher2cap(j)) || 2436 ieee80211_crypto_available(j))) 2437 caps |= 1<<j; 2438 if (caps == 0) /* nothing available */ 2439 return EINVAL; 2440 /* XXX verify ciphers ok for unicast use? */ 2441 /* XXX disallow if running as it'll have no effect */ 2442 rsn->rsn_ucastcipherset = caps; 2443 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2444 break; 2445 case IEEE80211_IOC_UCASTCIPHER: 2446 if ((rsn->rsn_ucastcipherset & cipher2cap(ireq->i_val)) == 0) 2447 return EINVAL; 2448 rsn->rsn_ucastcipher = ireq->i_val; 2449 break; 2450 case IEEE80211_IOC_UCASTKEYLEN: 2451 if (!(0 < ireq->i_val && ireq->i_val < IEEE80211_KEYBUF_SIZE)) 2452 return EINVAL; 2453 /* XXX no way to verify driver capability */ 2454 rsn->rsn_ucastkeylen = ireq->i_val; 2455 break; 2456 case IEEE80211_IOC_DRIVER_CAPS: 2457 /* NB: for testing */ 2458 ic->ic_caps = (((u_int16_t) ireq->i_val) << 16) | 2459 ((u_int16_t) ireq->i_len); 2460 break; 2461 case IEEE80211_IOC_KEYMGTALGS: 2462 /* XXX check */ 2463 rsn->rsn_keymgmtset = ireq->i_val; 2464 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2465 break; 2466 case IEEE80211_IOC_RSNCAPS: 2467 /* XXX check */ 2468 rsn->rsn_caps = ireq->i_val; 2469 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2470 break; 2471 case IEEE80211_IOC_BSSID: 2472 if (ireq->i_len != sizeof(tmpbssid)) 2473 return EINVAL; 2474 error = copyin(ireq->i_data, tmpbssid, ireq->i_len); 2475 if (error) 2476 break; 2477 IEEE80211_ADDR_COPY(ic->ic_des_bssid, tmpbssid); 2478 if (IEEE80211_ADDR_EQ(ic->ic_des_bssid, zerobssid)) 2479 ic->ic_flags &= ~IEEE80211_F_DESBSSID; 2480 else 2481 ic->ic_flags |= IEEE80211_F_DESBSSID; 2482 error = ENETRESET; 2483 break; 2484 case IEEE80211_IOC_CHANLIST: 2485 error = ieee80211_ioctl_setchanlist(ic, ireq); 2486 break; 2487 case IEEE80211_IOC_SCAN_REQ: 2488 if (ic->ic_opmode == IEEE80211_M_HOSTAP) /* XXX ignore */ 2489 break; 2490 error = ieee80211_setupscan(ic, ic->ic_chan_avail); 2491 if (error == 0) /* XXX background scan */ 2492 error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2493 break; 2494 case IEEE80211_IOC_ADDMAC: 2495 case IEEE80211_IOC_DELMAC: 2496 error = ieee80211_ioctl_macmac(ic, ireq); 2497 break; 2498 case IEEE80211_IOC_MACCMD: 2499 error = ieee80211_ioctl_setmaccmd(ic, ireq); 2500 break; 2501 case IEEE80211_IOC_STA_TXPOW: 2502 error = ieee80211_ioctl_setstatxpow(ic, ireq); 2503 break; 2504 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2505 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2506 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2507 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2508 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2509 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 2510 error = ieee80211_ioctl_setwmeparam(ic, ireq); 2511 break; 2512 case IEEE80211_IOC_DTIM_PERIOD: 2513 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 2514 ic->ic_opmode != IEEE80211_M_IBSS) 2515 return EINVAL; 2516 if (IEEE80211_DTIM_MIN <= ireq->i_val && 2517 ireq->i_val <= IEEE80211_DTIM_MAX) { 2518 ic->ic_dtim_period = ireq->i_val; 2519 error = ENETRESET; /* requires restart */ 2520 } else 2521 error = EINVAL; 2522 break; 2523 case IEEE80211_IOC_BEACON_INTERVAL: 2524 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 2525 ic->ic_opmode != IEEE80211_M_IBSS) 2526 return EINVAL; 2527 if (IEEE80211_BINTVAL_MIN <= ireq->i_val && 2528 ireq->i_val <= IEEE80211_BINTVAL_MAX) { 2529 ic->ic_bintval = ireq->i_val; 2530 error = ENETRESET; /* requires restart */ 2531 } else 2532 error = EINVAL; 2533 break; 2534 case IEEE80211_IOC_PUREG: 2535 if (ireq->i_val) 2536 ic->ic_flags |= IEEE80211_F_PUREG; 2537 else 2538 ic->ic_flags &= ~IEEE80211_F_PUREG; 2539 /* NB: reset only if we're operating on an 11g channel */ 2540 if (ic->ic_curmode == IEEE80211_MODE_11G) 2541 error = ENETRESET; 2542 break; 2543 case IEEE80211_IOC_MCAST_RATE: 2544 ic->ic_mcast_rate = ireq->i_val & IEEE80211_RATE_VAL; 2545 break; 2546 case IEEE80211_IOC_FRAGTHRESHOLD: 2547 if ((ic->ic_caps & IEEE80211_C_TXFRAG) == 0 && 2548 ireq->i_val != IEEE80211_FRAG_MAX) 2549 return EINVAL; 2550 if (!(IEEE80211_FRAG_MIN <= ireq->i_val && 2551 ireq->i_val <= IEEE80211_FRAG_MAX)) 2552 return EINVAL; 2553 ic->ic_fragthreshold = ireq->i_val; 2554 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2555 break; 2556 case IEEE80211_IOC_BURST: 2557 if (ireq->i_val) { 2558 if ((ic->ic_caps & IEEE80211_C_BURST) == 0) 2559 return EINVAL; 2560 ic->ic_flags |= IEEE80211_F_BURST; 2561 } else 2562 ic->ic_flags &= ~IEEE80211_F_BURST; 2563 error = ENETRESET; /* XXX maybe not for station? */ 2564 break; 2565 default: 2566 error = EINVAL; 2567 break; 2568 } 2569 if (error == ENETRESET && !IS_UP_AUTO(ic)) 2570 error = 0; 2571 return error; 2572 } 2573 2574 int 2575 ieee80211_ioctl(struct ieee80211com *ic, u_long cmd, caddr_t data) 2576 { 2577 struct ifnet *ifp = ic->ic_ifp; 2578 int error = 0; 2579 struct ifreq *ifr; 2580 struct ifaddr *ifa; /* XXX */ 2581 2582 switch (cmd) { 2583 case SIOCSIFMEDIA: 2584 case SIOCGIFMEDIA: 2585 error = ifmedia_ioctl(ifp, (struct ifreq *) data, 2586 &ic->ic_media, cmd); 2587 break; 2588 case SIOCG80211: 2589 error = ieee80211_ioctl_get80211(ic, cmd, 2590 (struct ieee80211req *) data); 2591 break; 2592 case SIOCS80211: 2593 error = suser(curthread); 2594 if (error == 0) 2595 error = ieee80211_ioctl_set80211(ic, cmd, 2596 (struct ieee80211req *) data); 2597 break; 2598 case SIOCGIFGENERIC: 2599 error = ieee80211_cfgget(ic, cmd, data); 2600 break; 2601 case SIOCSIFGENERIC: 2602 error = suser(curthread); 2603 if (error) 2604 break; 2605 error = ieee80211_cfgset(ic, cmd, data); 2606 break; 2607 case SIOCG80211STATS: 2608 ifr = (struct ifreq *)data; 2609 copyout(&ic->ic_stats, ifr->ifr_data, sizeof (ic->ic_stats)); 2610 break; 2611 case SIOCSIFMTU: 2612 ifr = (struct ifreq *)data; 2613 if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu && 2614 ifr->ifr_mtu <= IEEE80211_MTU_MAX)) 2615 error = EINVAL; 2616 else 2617 ifp->if_mtu = ifr->ifr_mtu; 2618 break; 2619 case SIOCSIFADDR: 2620 /* 2621 * XXX Handle this directly so we can supress if_init calls. 2622 * XXX This should be done in ether_ioctl but for the moment 2623 * XXX there are too many other parts of the system that 2624 * XXX set IFF_UP and so supress if_init being called when 2625 * XXX it should be. 2626 */ 2627 ifa = (struct ifaddr *) data; 2628 switch (ifa->ifa_addr->sa_family) { 2629 #ifdef INET 2630 case AF_INET: 2631 if ((ifp->if_flags & IFF_UP) == 0) { 2632 ifp->if_flags |= IFF_UP; 2633 ifp->if_init(ifp->if_softc); 2634 } 2635 arp_ifinit(ifp, ifa); 2636 break; 2637 #endif 2638 #ifdef IPX 2639 /* 2640 * XXX - This code is probably wrong, 2641 * but has been copied many times. 2642 */ 2643 case AF_IPX: { 2644 struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 2645 2646 if (ipx_nullhost(*ina)) 2647 ina->x_host = *(union ipx_host *) 2648 IF_LLADDR(ifp); 2649 else 2650 bcopy((caddr_t) ina->x_host.c_host, 2651 (caddr_t) IF_LLADDR(ifp), 2652 ETHER_ADDR_LEN); 2653 /* fall thru... */ 2654 } 2655 #endif 2656 default: 2657 if ((ifp->if_flags & IFF_UP) == 0) { 2658 ifp->if_flags |= IFF_UP; 2659 ifp->if_init(ifp->if_softc); 2660 } 2661 break; 2662 } 2663 break; 2664 default: 2665 error = ether_ioctl(ifp, cmd, data); 2666 break; 2667 } 2668 return error; 2669 } 2670