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