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