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