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