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