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