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