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