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