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_setstastats(struct ieee80211com *ic, struct ieee80211req *ireq) 2009 { 2010 struct ieee80211_node *ni; 2011 u_int8_t macaddr[IEEE80211_ADDR_LEN]; 2012 int error; 2013 2014 /* 2015 * NB: we could copyin ieee80211req_sta_stats so apps 2016 * could make selective changes but that's overkill; 2017 * just clear all stats for now. 2018 */ 2019 if (ireq->i_len < IEEE80211_ADDR_LEN) 2020 return EINVAL; 2021 error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); 2022 if (error != 0) 2023 return error; 2024 ni = ieee80211_find_node(&ic->ic_sta, macaddr); 2025 if (ni == NULL) 2026 return EINVAL; /* XXX */ 2027 memset(&ni->ni_stats, 0, sizeof(ni->ni_stats)); 2028 ieee80211_free_node(ni); 2029 return 0; 2030 } 2031 2032 static int 2033 ieee80211_ioctl_setstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq) 2034 { 2035 struct ieee80211_node *ni; 2036 struct ieee80211req_sta_txpow txpow; 2037 int error; 2038 2039 if (ireq->i_len != sizeof(txpow)) 2040 return EINVAL; 2041 error = copyin(ireq->i_data, &txpow, sizeof(txpow)); 2042 if (error != 0) 2043 return error; 2044 ni = ieee80211_find_node(&ic->ic_sta, txpow.it_macaddr); 2045 if (ni == NULL) 2046 return EINVAL; /* XXX */ 2047 ni->ni_txpower = txpow.it_txpow; 2048 ieee80211_free_node(ni); 2049 return error; 2050 } 2051 2052 static int 2053 ieee80211_ioctl_setwmeparam(struct ieee80211com *ic, struct ieee80211req *ireq) 2054 { 2055 struct ieee80211_wme_state *wme = &ic->ic_wme; 2056 struct wmeParams *wmep, *chanp; 2057 int isbss, ac; 2058 2059 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 2060 return EINVAL; 2061 2062 isbss = (ireq->i_len & IEEE80211_WMEPARAM_BSS); 2063 ac = (ireq->i_len & IEEE80211_WMEPARAM_VAL); 2064 if (ac >= WME_NUM_AC) 2065 ac = WME_AC_BE; 2066 if (isbss) { 2067 chanp = &wme->wme_bssChanParams.cap_wmeParams[ac]; 2068 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[ac]; 2069 } else { 2070 chanp = &wme->wme_chanParams.cap_wmeParams[ac]; 2071 wmep = &wme->wme_wmeChanParams.cap_wmeParams[ac]; 2072 } 2073 switch (ireq->i_type) { 2074 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2075 if (isbss) { 2076 wmep->wmep_logcwmin = ireq->i_val; 2077 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2078 chanp->wmep_logcwmin = ireq->i_val; 2079 } else { 2080 wmep->wmep_logcwmin = chanp->wmep_logcwmin = 2081 ireq->i_val; 2082 } 2083 break; 2084 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2085 if (isbss) { 2086 wmep->wmep_logcwmax = ireq->i_val; 2087 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2088 chanp->wmep_logcwmax = ireq->i_val; 2089 } else { 2090 wmep->wmep_logcwmax = chanp->wmep_logcwmax = 2091 ireq->i_val; 2092 } 2093 break; 2094 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2095 if (isbss) { 2096 wmep->wmep_aifsn = ireq->i_val; 2097 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2098 chanp->wmep_aifsn = ireq->i_val; 2099 } else { 2100 wmep->wmep_aifsn = chanp->wmep_aifsn = ireq->i_val; 2101 } 2102 break; 2103 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2104 if (isbss) { 2105 wmep->wmep_txopLimit = ireq->i_val; 2106 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2107 chanp->wmep_txopLimit = ireq->i_val; 2108 } else { 2109 wmep->wmep_txopLimit = chanp->wmep_txopLimit = 2110 ireq->i_val; 2111 } 2112 break; 2113 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2114 wmep->wmep_acm = ireq->i_val; 2115 if ((wme->wme_flags & WME_F_AGGRMODE) == 0) 2116 chanp->wmep_acm = ireq->i_val; 2117 break; 2118 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (!bss only)*/ 2119 wmep->wmep_noackPolicy = chanp->wmep_noackPolicy = 2120 (ireq->i_val) == 0; 2121 break; 2122 } 2123 ieee80211_wme_updateparams(ic); 2124 return 0; 2125 } 2126 2127 static int 2128 cipher2cap(int cipher) 2129 { 2130 switch (cipher) { 2131 case IEEE80211_CIPHER_WEP: return IEEE80211_C_WEP; 2132 case IEEE80211_CIPHER_AES_OCB: return IEEE80211_C_AES; 2133 case IEEE80211_CIPHER_AES_CCM: return IEEE80211_C_AES_CCM; 2134 case IEEE80211_CIPHER_CKIP: return IEEE80211_C_CKIP; 2135 case IEEE80211_CIPHER_TKIP: return IEEE80211_C_TKIP; 2136 } 2137 return 0; 2138 } 2139 2140 static int 2141 ieee80211_ioctl_set80211(struct ieee80211com *ic, u_long cmd, struct ieee80211req *ireq) 2142 { 2143 static const u_int8_t zerobssid[IEEE80211_ADDR_LEN]; 2144 struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn; 2145 int error; 2146 const struct ieee80211_authenticator *auth; 2147 u_int8_t tmpkey[IEEE80211_KEYBUF_SIZE]; 2148 char tmpssid[IEEE80211_NWID_LEN]; 2149 u_int8_t tmpbssid[IEEE80211_ADDR_LEN]; 2150 struct ieee80211_key *k; 2151 int j, caps; 2152 u_int kid; 2153 2154 error = 0; 2155 switch (ireq->i_type) { 2156 case IEEE80211_IOC_SSID: 2157 if (ireq->i_val != 0 || 2158 ireq->i_len > IEEE80211_NWID_LEN) 2159 return EINVAL; 2160 error = copyin(ireq->i_data, tmpssid, ireq->i_len); 2161 if (error) 2162 break; 2163 memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN); 2164 ic->ic_des_esslen = ireq->i_len; 2165 memcpy(ic->ic_des_essid, tmpssid, ireq->i_len); 2166 error = ENETRESET; 2167 break; 2168 case IEEE80211_IOC_WEP: 2169 switch (ireq->i_val) { 2170 case IEEE80211_WEP_OFF: 2171 ic->ic_flags &= ~IEEE80211_F_PRIVACY; 2172 ic->ic_flags &= ~IEEE80211_F_DROPUNENC; 2173 break; 2174 case IEEE80211_WEP_ON: 2175 ic->ic_flags |= IEEE80211_F_PRIVACY; 2176 ic->ic_flags |= IEEE80211_F_DROPUNENC; 2177 break; 2178 case IEEE80211_WEP_MIXED: 2179 ic->ic_flags |= IEEE80211_F_PRIVACY; 2180 ic->ic_flags &= ~IEEE80211_F_DROPUNENC; 2181 break; 2182 } 2183 error = ENETRESET; 2184 break; 2185 case IEEE80211_IOC_WEPKEY: 2186 kid = (u_int) ireq->i_val; 2187 if (kid >= IEEE80211_WEP_NKID) 2188 return EINVAL; 2189 k = &ic->ic_nw_keys[kid]; 2190 if (ireq->i_len == 0) { 2191 /* zero-len =>'s delete any existing key */ 2192 (void) ieee80211_crypto_delkey(ic, k); 2193 break; 2194 } 2195 if (ireq->i_len > sizeof(tmpkey)) 2196 return EINVAL; 2197 memset(tmpkey, 0, sizeof(tmpkey)); 2198 error = copyin(ireq->i_data, tmpkey, ireq->i_len); 2199 if (error) 2200 break; 2201 ieee80211_key_update_begin(ic); 2202 k->wk_keyix = kid; /* NB: force fixed key id */ 2203 if (ieee80211_crypto_newkey(ic, IEEE80211_CIPHER_WEP, 2204 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) { 2205 k->wk_keylen = ireq->i_len; 2206 memcpy(k->wk_key, tmpkey, sizeof(tmpkey)); 2207 if (!ieee80211_crypto_setkey(ic, k, ic->ic_myaddr)) 2208 error = EINVAL; 2209 } else 2210 error = EINVAL; 2211 ieee80211_key_update_end(ic); 2212 if (!error) /* NB: for compatibility */ 2213 error = ENETRESET; 2214 break; 2215 case IEEE80211_IOC_WEPTXKEY: 2216 kid = (u_int) ireq->i_val; 2217 if (kid >= IEEE80211_WEP_NKID && 2218 (u_int16_t) kid != IEEE80211_KEYIX_NONE) 2219 return EINVAL; 2220 ic->ic_def_txkey = kid; 2221 error = ENETRESET; /* push to hardware */ 2222 break; 2223 case IEEE80211_IOC_AUTHMODE: 2224 switch (ireq->i_val) { 2225 case IEEE80211_AUTH_WPA: 2226 case IEEE80211_AUTH_8021X: /* 802.1x */ 2227 case IEEE80211_AUTH_OPEN: /* open */ 2228 case IEEE80211_AUTH_SHARED: /* shared-key */ 2229 case IEEE80211_AUTH_AUTO: /* auto */ 2230 auth = ieee80211_authenticator_get(ireq->i_val); 2231 if (auth == NULL) 2232 return EINVAL; 2233 break; 2234 default: 2235 return EINVAL; 2236 } 2237 switch (ireq->i_val) { 2238 case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */ 2239 ic->ic_flags |= IEEE80211_F_PRIVACY; 2240 ireq->i_val = IEEE80211_AUTH_8021X; 2241 break; 2242 case IEEE80211_AUTH_OPEN: /* open */ 2243 ic->ic_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY); 2244 break; 2245 case IEEE80211_AUTH_SHARED: /* shared-key */ 2246 case IEEE80211_AUTH_8021X: /* 802.1x */ 2247 ic->ic_flags &= ~IEEE80211_F_WPA; 2248 /* both require a key so mark the PRIVACY capability */ 2249 ic->ic_flags |= IEEE80211_F_PRIVACY; 2250 break; 2251 case IEEE80211_AUTH_AUTO: /* auto */ 2252 ic->ic_flags &= ~IEEE80211_F_WPA; 2253 /* XXX PRIVACY handling? */ 2254 /* XXX what's the right way to do this? */ 2255 break; 2256 } 2257 /* NB: authenticator attach/detach happens on state change */ 2258 ic->ic_bss->ni_authmode = ireq->i_val; 2259 /* XXX mixed/mode/usage? */ 2260 ic->ic_auth = auth; 2261 error = ENETRESET; 2262 break; 2263 case IEEE80211_IOC_CHANNEL: 2264 /* XXX 0xffff overflows 16-bit signed */ 2265 if (ireq->i_val == 0 || 2266 ireq->i_val == (int16_t) IEEE80211_CHAN_ANY) 2267 ic->ic_des_chan = IEEE80211_CHAN_ANYC; 2268 else if ((u_int) ireq->i_val > IEEE80211_CHAN_MAX || 2269 isclr(ic->ic_chan_active, ireq->i_val)) { 2270 return EINVAL; 2271 } else 2272 ic->ic_ibss_chan = ic->ic_des_chan = 2273 &ic->ic_channels[ireq->i_val]; 2274 switch (ic->ic_state) { 2275 case IEEE80211_S_INIT: 2276 case IEEE80211_S_SCAN: 2277 error = ENETRESET; 2278 break; 2279 default: 2280 /* 2281 * If the desired channel has changed (to something 2282 * other than any) and we're not already scanning, 2283 * then kick the state machine. 2284 */ 2285 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC && 2286 ic->ic_bss->ni_chan != ic->ic_des_chan && 2287 (ic->ic_flags & IEEE80211_F_SCAN) == 0) 2288 error = ENETRESET; 2289 break; 2290 } 2291 if (error == ENETRESET && 2292 ic->ic_opmode == IEEE80211_M_MONITOR) { 2293 if (IS_UP(ic)) { 2294 /* 2295 * Monitor mode can switch directly. 2296 */ 2297 if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) 2298 ic->ic_curchan = ic->ic_des_chan; 2299 error = ic->ic_reset(ic->ic_ifp); 2300 } else 2301 error = 0; 2302 } 2303 break; 2304 case IEEE80211_IOC_POWERSAVE: 2305 switch (ireq->i_val) { 2306 case IEEE80211_POWERSAVE_OFF: 2307 if (ic->ic_flags & IEEE80211_F_PMGTON) { 2308 ic->ic_flags &= ~IEEE80211_F_PMGTON; 2309 error = ENETRESET; 2310 } 2311 break; 2312 case IEEE80211_POWERSAVE_ON: 2313 if ((ic->ic_caps & IEEE80211_C_PMGT) == 0) 2314 error = EINVAL; 2315 else if ((ic->ic_flags & IEEE80211_F_PMGTON) == 0) { 2316 ic->ic_flags |= IEEE80211_F_PMGTON; 2317 error = ENETRESET; 2318 } 2319 break; 2320 default: 2321 error = EINVAL; 2322 break; 2323 } 2324 break; 2325 case IEEE80211_IOC_POWERSAVESLEEP: 2326 if (ireq->i_val < 0) 2327 return EINVAL; 2328 ic->ic_lintval = ireq->i_val; 2329 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2330 break; 2331 case IEEE80211_IOC_RTSTHRESHOLD: 2332 if (!(IEEE80211_RTS_MIN <= ireq->i_val && 2333 ireq->i_val <= IEEE80211_RTS_MAX)) 2334 return EINVAL; 2335 ic->ic_rtsthreshold = ireq->i_val; 2336 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2337 break; 2338 case IEEE80211_IOC_PROTMODE: 2339 if (ireq->i_val > IEEE80211_PROT_RTSCTS) 2340 return EINVAL; 2341 ic->ic_protmode = ireq->i_val; 2342 /* NB: if not operating in 11g this can wait */ 2343 if (ic->ic_curmode == IEEE80211_MODE_11G) 2344 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2345 break; 2346 case IEEE80211_IOC_TXPOWER: 2347 if ((ic->ic_caps & IEEE80211_C_TXPMGT) == 0) 2348 return EINVAL; 2349 if (!(IEEE80211_TXPOWER_MIN < ireq->i_val && 2350 ireq->i_val < IEEE80211_TXPOWER_MAX)) 2351 return EINVAL; 2352 ic->ic_txpowlimit = ireq->i_val; 2353 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2354 break; 2355 case IEEE80211_IOC_ROAMING: 2356 if (!(IEEE80211_ROAMING_DEVICE <= ireq->i_val && 2357 ireq->i_val <= IEEE80211_ROAMING_MANUAL)) 2358 return EINVAL; 2359 ic->ic_roaming = ireq->i_val; 2360 /* XXXX reset? */ 2361 break; 2362 case IEEE80211_IOC_PRIVACY: 2363 if (ireq->i_val) { 2364 /* XXX check for key state? */ 2365 ic->ic_flags |= IEEE80211_F_PRIVACY; 2366 } else 2367 ic->ic_flags &= ~IEEE80211_F_PRIVACY; 2368 break; 2369 case IEEE80211_IOC_DROPUNENCRYPTED: 2370 if (ireq->i_val) 2371 ic->ic_flags |= IEEE80211_F_DROPUNENC; 2372 else 2373 ic->ic_flags &= ~IEEE80211_F_DROPUNENC; 2374 break; 2375 case IEEE80211_IOC_WPAKEY: 2376 error = ieee80211_ioctl_setkey(ic, ireq); 2377 break; 2378 case IEEE80211_IOC_DELKEY: 2379 error = ieee80211_ioctl_delkey(ic, ireq); 2380 break; 2381 case IEEE80211_IOC_MLME: 2382 error = ieee80211_ioctl_setmlme(ic, ireq); 2383 break; 2384 case IEEE80211_IOC_OPTIE: 2385 error = ieee80211_ioctl_setoptie(ic, ireq); 2386 break; 2387 case IEEE80211_IOC_COUNTERMEASURES: 2388 if (ireq->i_val) { 2389 if ((ic->ic_flags & IEEE80211_F_WPA) == 0) 2390 return EINVAL; 2391 ic->ic_flags |= IEEE80211_F_COUNTERM; 2392 } else 2393 ic->ic_flags &= ~IEEE80211_F_COUNTERM; 2394 break; 2395 case IEEE80211_IOC_WPA: 2396 if (ireq->i_val > 3) 2397 return EINVAL; 2398 /* XXX verify ciphers available */ 2399 ic->ic_flags &= ~IEEE80211_F_WPA; 2400 switch (ireq->i_val) { 2401 case 1: 2402 ic->ic_flags |= IEEE80211_F_WPA1; 2403 break; 2404 case 2: 2405 ic->ic_flags |= IEEE80211_F_WPA2; 2406 break; 2407 case 3: 2408 ic->ic_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2; 2409 break; 2410 } 2411 error = ENETRESET; /* XXX? */ 2412 break; 2413 case IEEE80211_IOC_WME: 2414 if (ireq->i_val) { 2415 if ((ic->ic_caps & IEEE80211_C_WME) == 0) 2416 return EINVAL; 2417 ic->ic_flags |= IEEE80211_F_WME; 2418 } else 2419 ic->ic_flags &= ~IEEE80211_F_WME; 2420 error = ENETRESET; /* XXX maybe not for station? */ 2421 break; 2422 case IEEE80211_IOC_HIDESSID: 2423 if (ireq->i_val) 2424 ic->ic_flags |= IEEE80211_F_HIDESSID; 2425 else 2426 ic->ic_flags &= ~IEEE80211_F_HIDESSID; 2427 error = ENETRESET; 2428 break; 2429 case IEEE80211_IOC_APBRIDGE: 2430 if (ireq->i_val == 0) 2431 ic->ic_flags |= IEEE80211_F_NOBRIDGE; 2432 else 2433 ic->ic_flags &= ~IEEE80211_F_NOBRIDGE; 2434 break; 2435 case IEEE80211_IOC_MCASTCIPHER: 2436 if ((ic->ic_caps & cipher2cap(ireq->i_val)) == 0 && 2437 !ieee80211_crypto_available(ireq->i_val)) 2438 return EINVAL; 2439 rsn->rsn_mcastcipher = ireq->i_val; 2440 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2441 break; 2442 case IEEE80211_IOC_MCASTKEYLEN: 2443 if (!(0 < ireq->i_val && ireq->i_val < IEEE80211_KEYBUF_SIZE)) 2444 return EINVAL; 2445 /* XXX no way to verify driver capability */ 2446 rsn->rsn_mcastkeylen = ireq->i_val; 2447 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2448 break; 2449 case IEEE80211_IOC_UCASTCIPHERS: 2450 /* 2451 * Convert user-specified cipher set to the set 2452 * we can support (via hardware or software). 2453 * NB: this logic intentionally ignores unknown and 2454 * unsupported ciphers so folks can specify 0xff or 2455 * similar and get all available ciphers. 2456 */ 2457 caps = 0; 2458 for (j = 1; j < 32; j++) /* NB: skip WEP */ 2459 if ((ireq->i_val & (1<<j)) && 2460 ((ic->ic_caps & cipher2cap(j)) || 2461 ieee80211_crypto_available(j))) 2462 caps |= 1<<j; 2463 if (caps == 0) /* nothing available */ 2464 return EINVAL; 2465 /* XXX verify ciphers ok for unicast use? */ 2466 /* XXX disallow if running as it'll have no effect */ 2467 rsn->rsn_ucastcipherset = caps; 2468 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2469 break; 2470 case IEEE80211_IOC_UCASTCIPHER: 2471 if ((rsn->rsn_ucastcipherset & cipher2cap(ireq->i_val)) == 0) 2472 return EINVAL; 2473 rsn->rsn_ucastcipher = ireq->i_val; 2474 break; 2475 case IEEE80211_IOC_UCASTKEYLEN: 2476 if (!(0 < ireq->i_val && ireq->i_val < IEEE80211_KEYBUF_SIZE)) 2477 return EINVAL; 2478 /* XXX no way to verify driver capability */ 2479 rsn->rsn_ucastkeylen = ireq->i_val; 2480 break; 2481 case IEEE80211_IOC_DRIVER_CAPS: 2482 /* NB: for testing */ 2483 ic->ic_caps = (((u_int16_t) ireq->i_val) << 16) | 2484 ((u_int16_t) ireq->i_len); 2485 break; 2486 case IEEE80211_IOC_KEYMGTALGS: 2487 /* XXX check */ 2488 rsn->rsn_keymgmtset = ireq->i_val; 2489 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2490 break; 2491 case IEEE80211_IOC_RSNCAPS: 2492 /* XXX check */ 2493 rsn->rsn_caps = ireq->i_val; 2494 error = (ic->ic_flags & IEEE80211_F_WPA) ? ENETRESET : 0; 2495 break; 2496 case IEEE80211_IOC_BSSID: 2497 if (ireq->i_len != sizeof(tmpbssid)) 2498 return EINVAL; 2499 error = copyin(ireq->i_data, tmpbssid, ireq->i_len); 2500 if (error) 2501 break; 2502 IEEE80211_ADDR_COPY(ic->ic_des_bssid, tmpbssid); 2503 if (IEEE80211_ADDR_EQ(ic->ic_des_bssid, zerobssid)) 2504 ic->ic_flags &= ~IEEE80211_F_DESBSSID; 2505 else 2506 ic->ic_flags |= IEEE80211_F_DESBSSID; 2507 error = ENETRESET; 2508 break; 2509 case IEEE80211_IOC_CHANLIST: 2510 error = ieee80211_ioctl_setchanlist(ic, ireq); 2511 break; 2512 case IEEE80211_IOC_SCAN_REQ: 2513 if (ic->ic_opmode == IEEE80211_M_HOSTAP) /* XXX ignore */ 2514 break; 2515 error = ieee80211_setupscan(ic, ic->ic_chan_avail); 2516 if (error == 0) /* XXX background scan */ 2517 error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2518 break; 2519 case IEEE80211_IOC_ADDMAC: 2520 case IEEE80211_IOC_DELMAC: 2521 error = ieee80211_ioctl_macmac(ic, ireq); 2522 break; 2523 case IEEE80211_IOC_MACCMD: 2524 error = ieee80211_ioctl_setmaccmd(ic, ireq); 2525 break; 2526 case IEEE80211_IOC_STA_STATS: 2527 error = ieee80211_ioctl_setstastats(ic, ireq); 2528 break; 2529 case IEEE80211_IOC_STA_TXPOW: 2530 error = ieee80211_ioctl_setstatxpow(ic, ireq); 2531 break; 2532 case IEEE80211_IOC_WME_CWMIN: /* WME: CWmin */ 2533 case IEEE80211_IOC_WME_CWMAX: /* WME: CWmax */ 2534 case IEEE80211_IOC_WME_AIFS: /* WME: AIFS */ 2535 case IEEE80211_IOC_WME_TXOPLIMIT: /* WME: txops limit */ 2536 case IEEE80211_IOC_WME_ACM: /* WME: ACM (bss only) */ 2537 case IEEE80211_IOC_WME_ACKPOLICY: /* WME: ACK policy (bss only) */ 2538 error = ieee80211_ioctl_setwmeparam(ic, ireq); 2539 break; 2540 case IEEE80211_IOC_DTIM_PERIOD: 2541 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 2542 ic->ic_opmode != IEEE80211_M_IBSS) 2543 return EINVAL; 2544 if (IEEE80211_DTIM_MIN <= ireq->i_val && 2545 ireq->i_val <= IEEE80211_DTIM_MAX) { 2546 ic->ic_dtim_period = ireq->i_val; 2547 error = ENETRESET; /* requires restart */ 2548 } else 2549 error = EINVAL; 2550 break; 2551 case IEEE80211_IOC_BEACON_INTERVAL: 2552 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 2553 ic->ic_opmode != IEEE80211_M_IBSS) 2554 return EINVAL; 2555 if (IEEE80211_BINTVAL_MIN <= ireq->i_val && 2556 ireq->i_val <= IEEE80211_BINTVAL_MAX) { 2557 ic->ic_bintval = ireq->i_val; 2558 error = ENETRESET; /* requires restart */ 2559 } else 2560 error = EINVAL; 2561 break; 2562 case IEEE80211_IOC_PUREG: 2563 if (ireq->i_val) 2564 ic->ic_flags |= IEEE80211_F_PUREG; 2565 else 2566 ic->ic_flags &= ~IEEE80211_F_PUREG; 2567 /* NB: reset only if we're operating on an 11g channel */ 2568 if (ic->ic_curmode == IEEE80211_MODE_11G) 2569 error = ENETRESET; 2570 break; 2571 case IEEE80211_IOC_MCAST_RATE: 2572 ic->ic_mcast_rate = ireq->i_val & IEEE80211_RATE_VAL; 2573 break; 2574 case IEEE80211_IOC_FRAGTHRESHOLD: 2575 if ((ic->ic_caps & IEEE80211_C_TXFRAG) == 0 && 2576 ireq->i_val != IEEE80211_FRAG_MAX) 2577 return EINVAL; 2578 if (!(IEEE80211_FRAG_MIN <= ireq->i_val && 2579 ireq->i_val <= IEEE80211_FRAG_MAX)) 2580 return EINVAL; 2581 ic->ic_fragthreshold = ireq->i_val; 2582 error = IS_UP(ic) ? ic->ic_reset(ic->ic_ifp) : 0; 2583 break; 2584 case IEEE80211_IOC_BURST: 2585 if (ireq->i_val) { 2586 if ((ic->ic_caps & IEEE80211_C_BURST) == 0) 2587 return EINVAL; 2588 ic->ic_flags |= IEEE80211_F_BURST; 2589 } else 2590 ic->ic_flags &= ~IEEE80211_F_BURST; 2591 error = ENETRESET; /* XXX maybe not for station? */ 2592 break; 2593 default: 2594 error = EINVAL; 2595 break; 2596 } 2597 if (error == ENETRESET && !IS_UP_AUTO(ic)) 2598 error = 0; 2599 return error; 2600 } 2601 2602 int 2603 ieee80211_ioctl(struct ieee80211com *ic, u_long cmd, caddr_t data) 2604 { 2605 struct ifnet *ifp = ic->ic_ifp; 2606 int error = 0; 2607 struct ifreq *ifr; 2608 struct ifaddr *ifa; /* XXX */ 2609 2610 switch (cmd) { 2611 case SIOCSIFMEDIA: 2612 case SIOCGIFMEDIA: 2613 error = ifmedia_ioctl(ifp, (struct ifreq *) data, 2614 &ic->ic_media, cmd); 2615 break; 2616 case SIOCG80211: 2617 error = ieee80211_ioctl_get80211(ic, cmd, 2618 (struct ieee80211req *) data); 2619 break; 2620 case SIOCS80211: 2621 error = suser(curthread); 2622 if (error == 0) 2623 error = ieee80211_ioctl_set80211(ic, cmd, 2624 (struct ieee80211req *) data); 2625 break; 2626 case SIOCGIFGENERIC: 2627 error = ieee80211_cfgget(ic, cmd, data); 2628 break; 2629 case SIOCSIFGENERIC: 2630 error = suser(curthread); 2631 if (error) 2632 break; 2633 error = ieee80211_cfgset(ic, cmd, data); 2634 break; 2635 case SIOCG80211STATS: 2636 ifr = (struct ifreq *)data; 2637 copyout(&ic->ic_stats, ifr->ifr_data, sizeof (ic->ic_stats)); 2638 break; 2639 case SIOCSIFMTU: 2640 ifr = (struct ifreq *)data; 2641 if (!(IEEE80211_MTU_MIN <= ifr->ifr_mtu && 2642 ifr->ifr_mtu <= IEEE80211_MTU_MAX)) 2643 error = EINVAL; 2644 else 2645 ifp->if_mtu = ifr->ifr_mtu; 2646 break; 2647 case SIOCSIFADDR: 2648 /* 2649 * XXX Handle this directly so we can supress if_init calls. 2650 * XXX This should be done in ether_ioctl but for the moment 2651 * XXX there are too many other parts of the system that 2652 * XXX set IFF_UP and so supress if_init being called when 2653 * XXX it should be. 2654 */ 2655 ifa = (struct ifaddr *) data; 2656 switch (ifa->ifa_addr->sa_family) { 2657 #ifdef INET 2658 case AF_INET: 2659 if ((ifp->if_flags & IFF_UP) == 0) { 2660 ifp->if_flags |= IFF_UP; 2661 ifp->if_init(ifp->if_softc); 2662 } 2663 arp_ifinit(ifp, ifa); 2664 break; 2665 #endif 2666 #ifdef IPX 2667 /* 2668 * XXX - This code is probably wrong, 2669 * but has been copied many times. 2670 */ 2671 case AF_IPX: { 2672 struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 2673 2674 if (ipx_nullhost(*ina)) 2675 ina->x_host = *(union ipx_host *) 2676 IF_LLADDR(ifp); 2677 else 2678 bcopy((caddr_t) ina->x_host.c_host, 2679 (caddr_t) IF_LLADDR(ifp), 2680 ETHER_ADDR_LEN); 2681 /* fall thru... */ 2682 } 2683 #endif 2684 default: 2685 if ((ifp->if_flags & IFF_UP) == 0) { 2686 ifp->if_flags |= IFF_UP; 2687 ifp->if_init(ifp->if_softc); 2688 } 2689 break; 2690 } 2691 break; 2692 default: 2693 error = ether_ioctl(ifp, cmd, data); 2694 break; 2695 } 2696 return error; 2697 } 2698