2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
31 * IEEE 802.11 ioctl support (FreeBSD-specific)
37 #include <sys/endian.h>
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
42 #include <sys/socket.h>
43 #include <sys/sockio.h>
44 #include <sys/systm.h>
47 #include <net/if_var.h>
48 #include <net/if_dl.h>
49 #include <net/if_media.h>
50 #include <net/ethernet.h>
53 #include <netinet/in.h>
54 #include <netinet/if_ether.h>
57 #include <netproto/802_11/ieee80211_var.h>
58 #include <netproto/802_11/ieee80211_ioctl.h>
59 #include <netproto/802_11/ieee80211_regdomain.h>
60 #include <netproto/802_11/ieee80211_input.h>
62 #define IS_UP_AUTO(_vap) \
63 (IFNET_IS_UP_RUNNING((_vap)->iv_ifp) && \
64 (_vap)->iv_roaming == IEEE80211_ROAMING_AUTO)
66 static const uint8_t zerobssid
[IEEE80211_ADDR_LEN
];
67 static struct ieee80211_channel
*findchannel(struct ieee80211com
*,
69 static int ieee80211_scanreq(struct ieee80211vap
*,
70 struct ieee80211_scan_req
*);
73 ieee80211_ioctl_getkey(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
75 struct ieee80211com
*ic
= vap
->iv_ic
;
76 struct ieee80211_node
*ni
;
77 struct ieee80211req_key ik
;
78 struct ieee80211_key
*wk
;
79 const struct ieee80211_cipher
*cip
;
83 if (ireq
->i_len
!= sizeof(ik
))
85 error
= copyin(ireq
->i_data
, &ik
, sizeof(ik
));
89 if (kid
== IEEE80211_KEYIX_NONE
) {
90 ni
= ieee80211_find_vap_node(&ic
->ic_sta
, vap
, ik
.ik_macaddr
);
93 wk
= &ni
->ni_ucastkey
;
95 if (kid
>= IEEE80211_WEP_NKID
)
97 wk
= &vap
->iv_nw_keys
[kid
];
98 IEEE80211_ADDR_COPY(&ik
.ik_macaddr
, vap
->iv_bss
->ni_macaddr
);
102 ik
.ik_type
= cip
->ic_cipher
;
103 ik
.ik_keylen
= wk
->wk_keylen
;
104 ik
.ik_flags
= wk
->wk_flags
& (IEEE80211_KEY_XMIT
| IEEE80211_KEY_RECV
);
105 if (wk
->wk_keyix
== vap
->iv_def_txkey
)
106 ik
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
107 if (caps_priv_check_self(SYSCAP_NONET_WIFI
) == 0) {
108 /* NB: only root can read key data */
109 ik
.ik_keyrsc
= wk
->wk_keyrsc
[IEEE80211_NONQOS_TID
];
110 ik
.ik_keytsc
= wk
->wk_keytsc
;
111 memcpy(ik
.ik_keydata
, wk
->wk_key
, wk
->wk_keylen
);
112 if (cip
->ic_cipher
== IEEE80211_CIPHER_TKIP
) {
113 memcpy(ik
.ik_keydata
+wk
->wk_keylen
,
114 wk
->wk_key
+ IEEE80211_KEYBUF_SIZE
,
115 IEEE80211_MICBUF_SIZE
);
116 ik
.ik_keylen
+= IEEE80211_MICBUF_SIZE
;
121 memset(ik
.ik_keydata
, 0, sizeof(ik
.ik_keydata
));
124 ieee80211_free_node(ni
);
125 return copyout(&ik
, ireq
->i_data
, sizeof(ik
));
129 ieee80211_ioctl_getchanlist(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
131 struct ieee80211com
*ic
= vap
->iv_ic
;
133 if (sizeof(ic
->ic_chan_active
) < ireq
->i_len
)
134 ireq
->i_len
= sizeof(ic
->ic_chan_active
);
135 return copyout(&ic
->ic_chan_active
, ireq
->i_data
, ireq
->i_len
);
139 ieee80211_ioctl_getchaninfo(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
141 struct ieee80211com
*ic
= vap
->iv_ic
;
144 space
= __offsetof(struct ieee80211req_chaninfo
,
145 ic_chans
[ic
->ic_nchans
]);
146 if (space
> ireq
->i_len
)
148 /* XXX assumes compatible layout */
149 return copyout(&ic
->ic_nchans
, ireq
->i_data
, space
);
153 ieee80211_ioctl_getwpaie(struct ieee80211vap
*vap
,
154 struct ieee80211req
*ireq
, int req
)
156 struct ieee80211_node
*ni
;
157 struct ieee80211req_wpaie2
*wpaie
;
160 if (ireq
->i_len
< IEEE80211_ADDR_LEN
)
162 #if defined(__DragonFly__)
163 wpaie
= kmalloc(sizeof(*wpaie
), M_TEMP
, M_INTWAIT
| M_ZERO
);
165 wpaie
= IEEE80211_MALLOC(sizeof(*wpaie
), M_TEMP
,
166 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
170 error
= copyin(ireq
->i_data
, wpaie
->wpa_macaddr
, IEEE80211_ADDR_LEN
);
173 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
, wpaie
->wpa_macaddr
);
178 if (ni
->ni_ies
.wpa_ie
!= NULL
) {
179 int ielen
= ni
->ni_ies
.wpa_ie
[1] + 2;
180 if (ielen
> sizeof(wpaie
->wpa_ie
))
181 ielen
= sizeof(wpaie
->wpa_ie
);
182 memcpy(wpaie
->wpa_ie
, ni
->ni_ies
.wpa_ie
, ielen
);
184 if (req
== IEEE80211_IOC_WPAIE2
) {
185 if (ni
->ni_ies
.rsn_ie
!= NULL
) {
186 int ielen
= ni
->ni_ies
.rsn_ie
[1] + 2;
187 if (ielen
> sizeof(wpaie
->rsn_ie
))
188 ielen
= sizeof(wpaie
->rsn_ie
);
189 memcpy(wpaie
->rsn_ie
, ni
->ni_ies
.rsn_ie
, ielen
);
191 if (ireq
->i_len
> sizeof(struct ieee80211req_wpaie2
))
192 ireq
->i_len
= sizeof(struct ieee80211req_wpaie2
);
194 /* compatibility op, may overwrite wpa ie */
195 /* XXX check ic_flags? */
196 if (ni
->ni_ies
.rsn_ie
!= NULL
) {
197 int ielen
= ni
->ni_ies
.rsn_ie
[1] + 2;
198 if (ielen
> sizeof(wpaie
->wpa_ie
))
199 ielen
= sizeof(wpaie
->wpa_ie
);
200 memcpy(wpaie
->wpa_ie
, ni
->ni_ies
.rsn_ie
, ielen
);
202 if (ireq
->i_len
> sizeof(struct ieee80211req_wpaie
))
203 ireq
->i_len
= sizeof(struct ieee80211req_wpaie
);
205 ieee80211_free_node(ni
);
206 error
= copyout(wpaie
, ireq
->i_data
, ireq
->i_len
);
208 IEEE80211_FREE(wpaie
, M_TEMP
);
213 ieee80211_ioctl_getstastats(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
215 struct ieee80211_node
*ni
;
216 uint8_t macaddr
[IEEE80211_ADDR_LEN
];
217 const size_t off
= __offsetof(struct ieee80211req_sta_stats
, is_stats
);
220 if (ireq
->i_len
< off
)
222 error
= copyin(ireq
->i_data
, macaddr
, IEEE80211_ADDR_LEN
);
225 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
, macaddr
);
228 if (ireq
->i_len
> sizeof(struct ieee80211req_sta_stats
))
229 ireq
->i_len
= sizeof(struct ieee80211req_sta_stats
);
230 /* NB: copy out only the statistics */
231 error
= copyout(&ni
->ni_stats
, (uint8_t *) ireq
->i_data
+ off
,
233 ieee80211_free_node(ni
);
238 struct ieee80211req_scan_result
*sr
;
243 scan_space(const struct ieee80211_scan_entry
*se
, int *ielen
)
247 *ielen
= se
->se_ies
.len
;
249 * NB: ie's can be no more than 255 bytes and the max 802.11
250 * packet is <3Kbytes so we are sure this doesn't overflow
251 * 16-bits; if this is a concern we can drop the ie's.
253 len
= sizeof(struct ieee80211req_scan_result
) + se
->se_ssid
[1] +
254 se
->se_meshid
[1] + *ielen
;
255 return roundup(len
, sizeof(uint32_t));
259 get_scan_space(void *arg
, const struct ieee80211_scan_entry
*se
)
261 struct scanreq
*req
= arg
;
264 req
->space
+= scan_space(se
, &ielen
);
268 get_scan_result(void *arg
, const struct ieee80211_scan_entry
*se
)
270 struct scanreq
*req
= arg
;
271 struct ieee80211req_scan_result
*sr
;
272 int ielen
, len
, nr
, nxr
;
275 len
= scan_space(se
, &ielen
);
276 if (len
> req
->space
)
280 KASSERT(len
<= 65535 && ielen
<= 65535,
281 ("len %u ssid %u ie %u", len
, se
->se_ssid
[1], ielen
));
283 sr
->isr_ie_off
= sizeof(struct ieee80211req_scan_result
);
284 sr
->isr_ie_len
= ielen
;
285 sr
->isr_freq
= se
->se_chan
->ic_freq
;
286 sr
->isr_flags
= se
->se_chan
->ic_flags
;
287 sr
->isr_rssi
= se
->se_rssi
;
288 sr
->isr_noise
= se
->se_noise
;
289 sr
->isr_intval
= se
->se_intval
;
290 sr
->isr_capinfo
= se
->se_capinfo
;
291 sr
->isr_erp
= se
->se_erp
;
292 IEEE80211_ADDR_COPY(sr
->isr_bssid
, se
->se_bssid
);
293 nr
= min(se
->se_rates
[1], IEEE80211_RATE_MAXSIZE
);
294 memcpy(sr
->isr_rates
, se
->se_rates
+2, nr
);
295 nxr
= min(se
->se_xrates
[1], IEEE80211_RATE_MAXSIZE
- nr
);
296 memcpy(sr
->isr_rates
+nr
, se
->se_xrates
+2, nxr
);
297 sr
->isr_nrates
= nr
+ nxr
;
300 sr
->isr_ssid_len
= se
->se_ssid
[1];
301 cp
= ((uint8_t *)sr
) + sr
->isr_ie_off
;
302 memcpy(cp
, se
->se_ssid
+2, sr
->isr_ssid_len
);
305 cp
+= sr
->isr_ssid_len
;
306 sr
->isr_meshid_len
= se
->se_meshid
[1];
307 memcpy(cp
, se
->se_meshid
+2, sr
->isr_meshid_len
);
308 cp
+= sr
->isr_meshid_len
;
311 memcpy(cp
, se
->se_ies
.data
, ielen
);
314 req
->sr
= (struct ieee80211req_scan_result
*)(((uint8_t *)sr
) + len
);
318 ieee80211_ioctl_getscanresults(struct ieee80211vap
*vap
,
319 struct ieee80211req
*ireq
)
324 if (ireq
->i_len
< sizeof(struct scanreq
))
329 ieee80211_scan_iterate(vap
, get_scan_space
, &req
);
330 if (req
.space
> ireq
->i_len
)
331 req
.space
= ireq
->i_len
;
337 /* XXX M_WAITOK after driver lock released */
338 #if defined(__DragonFly__)
339 p
= kmalloc(space
, M_TEMP
, M_INTWAIT
| M_ZERO
);
341 p
= IEEE80211_MALLOC(space
, M_TEMP
,
342 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
347 ieee80211_scan_iterate(vap
, get_scan_result
, &req
);
348 ireq
->i_len
= space
- req
.space
;
349 error
= copyout(p
, ireq
->i_data
, ireq
->i_len
);
350 IEEE80211_FREE(p
, M_TEMP
);
358 struct ieee80211vap
*vap
;
359 struct ieee80211req_sta_info
*si
;
364 sta_space(const struct ieee80211_node
*ni
, size_t *ielen
)
366 *ielen
= ni
->ni_ies
.len
;
367 return roundup(sizeof(struct ieee80211req_sta_info
) + *ielen
,
372 get_sta_space(void *arg
, struct ieee80211_node
*ni
)
374 struct stainforeq
*req
= arg
;
377 if (req
->vap
!= ni
->ni_vap
)
379 if (ni
->ni_vap
->iv_opmode
== IEEE80211_M_HOSTAP
&&
380 ni
->ni_associd
== 0) /* only associated stations */
382 req
->space
+= sta_space(ni
, &ielen
);
386 get_sta_info(void *arg
, struct ieee80211_node
*ni
)
388 struct stainforeq
*req
= arg
;
389 struct ieee80211vap
*vap
= ni
->ni_vap
;
390 struct ieee80211req_sta_info
*si
;
394 if (req
->vap
!= ni
->ni_vap
)
396 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
&&
397 ni
->ni_associd
== 0) /* only associated stations */
399 if (ni
->ni_chan
== IEEE80211_CHAN_ANYC
) /* XXX bogus entry */
401 len
= sta_space(ni
, &ielen
);
402 if (len
> req
->space
)
406 si
->isi_ie_off
= sizeof(struct ieee80211req_sta_info
);
407 si
->isi_ie_len
= ielen
;
408 si
->isi_freq
= ni
->ni_chan
->ic_freq
;
409 si
->isi_flags
= ni
->ni_chan
->ic_flags
;
410 si
->isi_state
= ni
->ni_flags
;
411 si
->isi_authmode
= ni
->ni_authmode
;
412 vap
->iv_ic
->ic_node_getsignal(ni
, &si
->isi_rssi
, &si
->isi_noise
);
413 vap
->iv_ic
->ic_node_getmimoinfo(ni
, &si
->isi_mimo
);
414 si
->isi_capinfo
= ni
->ni_capinfo
;
415 si
->isi_erp
= ni
->ni_erp
;
416 IEEE80211_ADDR_COPY(si
->isi_macaddr
, ni
->ni_macaddr
);
417 si
->isi_nrates
= ni
->ni_rates
.rs_nrates
;
418 if (si
->isi_nrates
> 15)
420 memcpy(si
->isi_rates
, ni
->ni_rates
.rs_rates
, si
->isi_nrates
);
421 si
->isi_txrate
= ni
->ni_txrate
;
422 if (si
->isi_txrate
& IEEE80211_RATE_MCS
) {
423 const struct ieee80211_mcs_rates
*mcs
=
424 &ieee80211_htrates
[ni
->ni_txrate
&~ IEEE80211_RATE_MCS
];
425 if (IEEE80211_IS_CHAN_HT40(ni
->ni_chan
)) {
426 if (ni
->ni_flags
& IEEE80211_NODE_SGI40
)
427 si
->isi_txmbps
= mcs
->ht40_rate_800ns
;
429 si
->isi_txmbps
= mcs
->ht40_rate_400ns
;
431 if (ni
->ni_flags
& IEEE80211_NODE_SGI20
)
432 si
->isi_txmbps
= mcs
->ht20_rate_800ns
;
434 si
->isi_txmbps
= mcs
->ht20_rate_400ns
;
437 si
->isi_txmbps
= si
->isi_txrate
;
438 si
->isi_associd
= ni
->ni_associd
;
439 si
->isi_txpower
= ni
->ni_txpower
;
440 si
->isi_vlan
= ni
->ni_vlan
;
441 if (ni
->ni_flags
& IEEE80211_NODE_QOS
) {
442 memcpy(si
->isi_txseqs
, ni
->ni_txseqs
, sizeof(ni
->ni_txseqs
));
443 memcpy(si
->isi_rxseqs
, ni
->ni_rxseqs
, sizeof(ni
->ni_rxseqs
));
445 si
->isi_txseqs
[0] = ni
->ni_txseqs
[IEEE80211_NONQOS_TID
];
446 si
->isi_rxseqs
[0] = ni
->ni_rxseqs
[IEEE80211_NONQOS_TID
];
448 /* NB: leave all cases in case we relax ni_associd == 0 check */
449 if (ieee80211_node_is_authorized(ni
))
450 si
->isi_inact
= vap
->iv_inact_run
;
451 else if (ni
->ni_associd
!= 0 ||
452 (vap
->iv_opmode
== IEEE80211_M_WDS
&&
453 (vap
->iv_flags_ext
& IEEE80211_FEXT_WDSLEGACY
)))
454 si
->isi_inact
= vap
->iv_inact_auth
;
456 si
->isi_inact
= vap
->iv_inact_init
;
457 si
->isi_inact
= (si
->isi_inact
- ni
->ni_inact
) * IEEE80211_INACT_WAIT
;
458 si
->isi_localid
= ni
->ni_mllid
;
459 si
->isi_peerid
= ni
->ni_mlpid
;
460 si
->isi_peerstate
= ni
->ni_mlstate
;
463 cp
= ((uint8_t *)si
) + si
->isi_ie_off
;
464 memcpy(cp
, ni
->ni_ies
.data
, ielen
);
467 req
->si
= (struct ieee80211req_sta_info
*)(((uint8_t *)si
) + len
);
472 getstainfo_common(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
,
473 struct ieee80211_node
*ni
, size_t off
)
475 struct ieee80211com
*ic
= vap
->iv_ic
;
476 struct stainforeq req
;
485 ieee80211_iterate_nodes(&ic
->ic_sta
, get_sta_space
, &req
);
487 get_sta_space(&req
, ni
);
488 if (req
.space
> ireq
->i_len
)
489 req
.space
= ireq
->i_len
;
492 /* XXX M_WAITOK after driver lock released */
493 #if defined(__DragonFly__)
494 p
= kmalloc(space
, M_TEMP
, M_INTWAIT
| M_ZERO
);
496 p
= IEEE80211_MALLOC(space
, M_TEMP
,
497 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
505 ieee80211_iterate_nodes(&ic
->ic_sta
, get_sta_info
, &req
);
507 get_sta_info(&req
, ni
);
508 ireq
->i_len
= space
- req
.space
;
509 error
= copyout(p
, (uint8_t *) ireq
->i_data
+off
, ireq
->i_len
);
510 IEEE80211_FREE(p
, M_TEMP
);
515 ieee80211_free_node(ni
);
520 ieee80211_ioctl_getstainfo(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
522 uint8_t macaddr
[IEEE80211_ADDR_LEN
];
523 const size_t off
= __offsetof(struct ieee80211req_sta_req
, info
);
524 struct ieee80211_node
*ni
;
527 if (ireq
->i_len
< sizeof(struct ieee80211req_sta_req
))
529 error
= copyin(ireq
->i_data
, macaddr
, IEEE80211_ADDR_LEN
);
532 if (IEEE80211_ADDR_EQ(macaddr
, vap
->iv_ifp
->if_broadcastaddr
)) {
535 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
, macaddr
);
539 return getstainfo_common(vap
, ireq
, ni
, off
);
543 ieee80211_ioctl_getstatxpow(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
545 struct ieee80211_node
*ni
;
546 struct ieee80211req_sta_txpow txpow
;
549 if (ireq
->i_len
!= sizeof(txpow
))
551 error
= copyin(ireq
->i_data
, &txpow
, sizeof(txpow
));
554 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
, txpow
.it_macaddr
);
557 txpow
.it_txpow
= ni
->ni_txpower
;
558 error
= copyout(&txpow
, ireq
->i_data
, sizeof(txpow
));
559 ieee80211_free_node(ni
);
564 ieee80211_ioctl_getwmeparam(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
566 struct ieee80211com
*ic
= vap
->iv_ic
;
567 struct ieee80211_wme_state
*wme
= &ic
->ic_wme
;
568 struct wmeParams
*wmep
;
571 if ((ic
->ic_caps
& IEEE80211_C_WME
) == 0)
574 ac
= (ireq
->i_len
& IEEE80211_WMEPARAM_VAL
);
575 if (ac
>= WME_NUM_AC
)
577 if (ireq
->i_len
& IEEE80211_WMEPARAM_BSS
)
578 wmep
= &wme
->wme_wmeBssChanParams
.cap_wmeParams
[ac
];
580 wmep
= &wme
->wme_wmeChanParams
.cap_wmeParams
[ac
];
581 switch (ireq
->i_type
) {
582 case IEEE80211_IOC_WME_CWMIN
: /* WME: CWmin */
583 ireq
->i_val
= wmep
->wmep_logcwmin
;
585 case IEEE80211_IOC_WME_CWMAX
: /* WME: CWmax */
586 ireq
->i_val
= wmep
->wmep_logcwmax
;
588 case IEEE80211_IOC_WME_AIFS
: /* WME: AIFS */
589 ireq
->i_val
= wmep
->wmep_aifsn
;
591 case IEEE80211_IOC_WME_TXOPLIMIT
: /* WME: txops limit */
592 ireq
->i_val
= wmep
->wmep_txopLimit
;
594 case IEEE80211_IOC_WME_ACM
: /* WME: ACM (bss only) */
595 wmep
= &wme
->wme_wmeBssChanParams
.cap_wmeParams
[ac
];
596 ireq
->i_val
= wmep
->wmep_acm
;
598 case IEEE80211_IOC_WME_ACKPOLICY
: /* WME: ACK policy (!bss only)*/
599 wmep
= &wme
->wme_wmeChanParams
.cap_wmeParams
[ac
];
600 ireq
->i_val
= !wmep
->wmep_noackPolicy
;
607 ieee80211_ioctl_getmaccmd(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
609 const struct ieee80211_aclator
*acl
= vap
->iv_acl
;
611 return (acl
== NULL
? EINVAL
: acl
->iac_getioctl(vap
, ireq
));
615 ieee80211_ioctl_getcurchan(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
617 struct ieee80211com
*ic
= vap
->iv_ic
;
618 struct ieee80211_channel
*c
;
620 if (ireq
->i_len
!= sizeof(struct ieee80211_channel
))
623 * vap's may have different operating channels when HT is
624 * in use. When in RUN state report the vap-specific channel.
625 * Otherwise return curchan.
627 if (vap
->iv_state
== IEEE80211_S_RUN
|| vap
->iv_state
== IEEE80211_S_SLEEP
)
628 c
= vap
->iv_bss
->ni_chan
;
631 return copyout(c
, ireq
->i_data
, sizeof(*c
));
635 getappie(const struct ieee80211_appie
*aie
, struct ieee80211req
*ireq
)
639 /* NB: truncate, caller can check length */
640 if (ireq
->i_len
> aie
->ie_len
)
641 ireq
->i_len
= aie
->ie_len
;
642 return copyout(aie
->ie_data
, ireq
->i_data
, ireq
->i_len
);
646 ieee80211_ioctl_getappie(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
650 fc0
= ireq
->i_val
& 0xff;
651 if ((fc0
& IEEE80211_FC0_TYPE_MASK
) != IEEE80211_FC0_TYPE_MGT
)
653 /* NB: could check iv_opmode and reject but hardly worth the effort */
654 switch (fc0
& IEEE80211_FC0_SUBTYPE_MASK
) {
655 case IEEE80211_FC0_SUBTYPE_BEACON
:
656 return getappie(vap
->iv_appie_beacon
, ireq
);
657 case IEEE80211_FC0_SUBTYPE_PROBE_RESP
:
658 return getappie(vap
->iv_appie_proberesp
, ireq
);
659 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP
:
660 return getappie(vap
->iv_appie_assocresp
, ireq
);
661 case IEEE80211_FC0_SUBTYPE_PROBE_REQ
:
662 return getappie(vap
->iv_appie_probereq
, ireq
);
663 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ
:
664 return getappie(vap
->iv_appie_assocreq
, ireq
);
665 case IEEE80211_FC0_SUBTYPE_BEACON
|IEEE80211_FC0_SUBTYPE_PROBE_RESP
:
666 return getappie(vap
->iv_appie_wpa
, ireq
);
672 ieee80211_ioctl_getregdomain(struct ieee80211vap
*vap
,
673 const struct ieee80211req
*ireq
)
675 struct ieee80211com
*ic
= vap
->iv_ic
;
677 if (ireq
->i_len
!= sizeof(ic
->ic_regdomain
))
679 return copyout(&ic
->ic_regdomain
, ireq
->i_data
,
680 sizeof(ic
->ic_regdomain
));
684 ieee80211_ioctl_getroam(struct ieee80211vap
*vap
,
685 const struct ieee80211req
*ireq
)
687 size_t len
= ireq
->i_len
;
688 /* NB: accept short requests for backwards compat */
689 if (len
> sizeof(vap
->iv_roamparms
))
690 len
= sizeof(vap
->iv_roamparms
);
691 return copyout(vap
->iv_roamparms
, ireq
->i_data
, len
);
695 ieee80211_ioctl_gettxparams(struct ieee80211vap
*vap
,
696 const struct ieee80211req
*ireq
)
698 size_t len
= ireq
->i_len
;
699 /* NB: accept short requests for backwards compat */
700 if (len
> sizeof(vap
->iv_txparms
))
701 len
= sizeof(vap
->iv_txparms
);
702 return copyout(vap
->iv_txparms
, ireq
->i_data
, len
);
706 ieee80211_ioctl_getdevcaps(struct ieee80211com
*ic
,
707 const struct ieee80211req
*ireq
)
709 struct ieee80211_devcaps_req
*dc
;
710 struct ieee80211req_chaninfo
*ci
;
713 maxchans
= 1 + ((ireq
->i_len
- sizeof(struct ieee80211_devcaps_req
)) /
714 sizeof(struct ieee80211_channel
));
715 /* NB: require 1 so we know ic_nchans is accessible */
718 /* constrain max request size, 2K channels is ~24Kbytes */
721 #if defined(__DragonFly__)
722 dc
= (struct ieee80211_devcaps_req
*)
723 kmalloc(IEEE80211_DEVCAPS_SIZE(maxchans
), M_TEMP
, M_INTWAIT
| M_ZERO
);
725 dc
= (struct ieee80211_devcaps_req
*)
726 IEEE80211_MALLOC(IEEE80211_DEVCAPS_SIZE(maxchans
), M_TEMP
,
727 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
731 dc
->dc_drivercaps
= ic
->ic_caps
;
732 dc
->dc_cryptocaps
= ic
->ic_cryptocaps
;
733 dc
->dc_htcaps
= ic
->ic_htcaps
;
734 ci
= &dc
->dc_chaninfo
;
735 ic
->ic_getradiocaps(ic
, maxchans
, &ci
->ic_nchans
, ci
->ic_chans
);
736 KASSERT(ci
->ic_nchans
<= maxchans
,
737 ("nchans %d maxchans %d", ci
->ic_nchans
, maxchans
));
738 ieee80211_sort_channels(ci
->ic_chans
, ci
->ic_nchans
);
739 error
= copyout(dc
, ireq
->i_data
, IEEE80211_DEVCAPS_SPACE(dc
));
740 IEEE80211_FREE(dc
, M_TEMP
);
745 ieee80211_ioctl_getstavlan(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
747 struct ieee80211_node
*ni
;
748 struct ieee80211req_sta_vlan vlan
;
751 if (ireq
->i_len
!= sizeof(vlan
))
753 error
= copyin(ireq
->i_data
, &vlan
, sizeof(vlan
));
756 if (!IEEE80211_ADDR_EQ(vlan
.sv_macaddr
, zerobssid
)) {
757 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
,
762 ni
= ieee80211_ref_node(vap
->iv_bss
);
763 vlan
.sv_vlan
= ni
->ni_vlan
;
764 error
= copyout(&vlan
, ireq
->i_data
, sizeof(vlan
));
765 ieee80211_free_node(ni
);
770 * Dummy ioctl get handler so the linker set is defined.
773 dummy_ioctl_get(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
777 IEEE80211_IOCTL_GET(dummy
, dummy_ioctl_get
);
780 ieee80211_ioctl_getdefault(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
782 ieee80211_ioctl_getfunc
* const *get
;
785 SET_FOREACH(get
, ieee80211_ioctl_getset
) {
786 error
= (*get
)(vap
, ireq
);
794 ieee80211_ioctl_get80211(struct ieee80211vap
*vap
, u_long cmd
,
795 struct ieee80211req
*ireq
)
797 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
798 struct ieee80211com
*ic
= vap
->iv_ic
;
800 uint8_t tmpkey
[IEEE80211_KEYBUF_SIZE
];
801 char tmpssid
[IEEE80211_NWID_LEN
];
804 switch (ireq
->i_type
) {
805 case IEEE80211_IOC_SSID
:
806 switch (vap
->iv_state
) {
807 case IEEE80211_S_INIT
:
808 case IEEE80211_S_SCAN
:
809 ireq
->i_len
= vap
->iv_des_ssid
[0].len
;
810 memcpy(tmpssid
, vap
->iv_des_ssid
[0].ssid
, ireq
->i_len
);
813 ireq
->i_len
= vap
->iv_bss
->ni_esslen
;
814 memcpy(tmpssid
, vap
->iv_bss
->ni_essid
, ireq
->i_len
);
817 error
= copyout(tmpssid
, ireq
->i_data
, ireq
->i_len
);
819 case IEEE80211_IOC_NUMSSIDS
:
822 case IEEE80211_IOC_WEP
:
823 if ((vap
->iv_flags
& IEEE80211_F_PRIVACY
) == 0)
824 ireq
->i_val
= IEEE80211_WEP_OFF
;
825 else if (vap
->iv_flags
& IEEE80211_F_DROPUNENC
)
826 ireq
->i_val
= IEEE80211_WEP_ON
;
828 ireq
->i_val
= IEEE80211_WEP_MIXED
;
830 case IEEE80211_IOC_WEPKEY
:
831 kid
= (u_int
) ireq
->i_val
;
832 if (kid
>= IEEE80211_WEP_NKID
)
834 len
= (u_int
) vap
->iv_nw_keys
[kid
].wk_keylen
;
835 /* NB: only root can read WEP keys */
836 if (caps_priv_check_self(SYSCAP_NONET_WIFI
) == 0) {
837 bcopy(vap
->iv_nw_keys
[kid
].wk_key
, tmpkey
, len
);
842 error
= copyout(tmpkey
, ireq
->i_data
, len
);
844 case IEEE80211_IOC_NUMWEPKEYS
:
845 ireq
->i_val
= IEEE80211_WEP_NKID
;
847 case IEEE80211_IOC_WEPTXKEY
:
848 ireq
->i_val
= vap
->iv_def_txkey
;
850 case IEEE80211_IOC_AUTHMODE
:
851 if (vap
->iv_flags
& IEEE80211_F_WPA
)
852 ireq
->i_val
= IEEE80211_AUTH_WPA
;
854 ireq
->i_val
= vap
->iv_bss
->ni_authmode
;
856 case IEEE80211_IOC_CHANNEL
:
857 ireq
->i_val
= ieee80211_chan2ieee(ic
, ic
->ic_curchan
);
859 case IEEE80211_IOC_POWERSAVE
:
860 if (vap
->iv_flags
& IEEE80211_F_PMGTON
)
861 ireq
->i_val
= IEEE80211_POWERSAVE_ON
;
863 ireq
->i_val
= IEEE80211_POWERSAVE_OFF
;
865 case IEEE80211_IOC_POWERSAVESLEEP
:
866 ireq
->i_val
= ic
->ic_lintval
;
868 case IEEE80211_IOC_RTSTHRESHOLD
:
869 ireq
->i_val
= vap
->iv_rtsthreshold
;
871 case IEEE80211_IOC_PROTMODE
:
872 ireq
->i_val
= ic
->ic_protmode
;
874 case IEEE80211_IOC_TXPOWER
:
876 * Tx power limit is the min of max regulatory
877 * power, any user-set limit, and the max the
880 ireq
->i_val
= 2*ic
->ic_curchan
->ic_maxregpower
;
881 if (ireq
->i_val
> ic
->ic_txpowlimit
)
882 ireq
->i_val
= ic
->ic_txpowlimit
;
883 if (ireq
->i_val
> ic
->ic_curchan
->ic_maxpower
)
884 ireq
->i_val
= ic
->ic_curchan
->ic_maxpower
;
886 case IEEE80211_IOC_WPA
:
887 switch (vap
->iv_flags
& IEEE80211_F_WPA
) {
888 case IEEE80211_F_WPA1
:
891 case IEEE80211_F_WPA2
:
894 case IEEE80211_F_WPA1
| IEEE80211_F_WPA2
:
902 case IEEE80211_IOC_CHANLIST
:
903 error
= ieee80211_ioctl_getchanlist(vap
, ireq
);
905 case IEEE80211_IOC_ROAMING
:
906 ireq
->i_val
= vap
->iv_roaming
;
908 case IEEE80211_IOC_PRIVACY
:
909 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_PRIVACY
) != 0;
911 case IEEE80211_IOC_DROPUNENCRYPTED
:
912 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_DROPUNENC
) != 0;
914 case IEEE80211_IOC_COUNTERMEASURES
:
915 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_COUNTERM
) != 0;
917 case IEEE80211_IOC_WME
:
918 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_WME
) != 0;
920 case IEEE80211_IOC_HIDESSID
:
921 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_HIDESSID
) != 0;
923 case IEEE80211_IOC_APBRIDGE
:
924 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_NOBRIDGE
) == 0;
926 case IEEE80211_IOC_WPAKEY
:
927 error
= ieee80211_ioctl_getkey(vap
, ireq
);
929 case IEEE80211_IOC_CHANINFO
:
930 error
= ieee80211_ioctl_getchaninfo(vap
, ireq
);
932 case IEEE80211_IOC_BSSID
:
933 if (ireq
->i_len
!= IEEE80211_ADDR_LEN
)
935 if (vap
->iv_state
== IEEE80211_S_RUN
|| vap
->iv_state
== IEEE80211_S_SLEEP
) {
936 error
= copyout(vap
->iv_opmode
== IEEE80211_M_WDS
?
937 vap
->iv_bss
->ni_macaddr
: vap
->iv_bss
->ni_bssid
,
938 ireq
->i_data
, ireq
->i_len
);
940 error
= copyout(vap
->iv_des_bssid
, ireq
->i_data
,
943 case IEEE80211_IOC_WPAIE
:
944 case IEEE80211_IOC_WPAIE2
:
945 error
= ieee80211_ioctl_getwpaie(vap
, ireq
, ireq
->i_type
);
947 case IEEE80211_IOC_SCAN_RESULTS
:
948 error
= ieee80211_ioctl_getscanresults(vap
, ireq
);
950 case IEEE80211_IOC_STA_STATS
:
951 error
= ieee80211_ioctl_getstastats(vap
, ireq
);
953 case IEEE80211_IOC_TXPOWMAX
:
954 ireq
->i_val
= vap
->iv_bss
->ni_txpower
;
956 case IEEE80211_IOC_STA_TXPOW
:
957 error
= ieee80211_ioctl_getstatxpow(vap
, ireq
);
959 case IEEE80211_IOC_STA_INFO
:
960 error
= ieee80211_ioctl_getstainfo(vap
, ireq
);
962 case IEEE80211_IOC_WME_CWMIN
: /* WME: CWmin */
963 case IEEE80211_IOC_WME_CWMAX
: /* WME: CWmax */
964 case IEEE80211_IOC_WME_AIFS
: /* WME: AIFS */
965 case IEEE80211_IOC_WME_TXOPLIMIT
: /* WME: txops limit */
966 case IEEE80211_IOC_WME_ACM
: /* WME: ACM (bss only) */
967 case IEEE80211_IOC_WME_ACKPOLICY
: /* WME: ACK policy (!bss only) */
968 error
= ieee80211_ioctl_getwmeparam(vap
, ireq
);
970 case IEEE80211_IOC_DTIM_PERIOD
:
971 ireq
->i_val
= vap
->iv_dtim_period
;
973 case IEEE80211_IOC_BEACON_INTERVAL
:
974 /* NB: get from ic_bss for station mode */
975 ireq
->i_val
= vap
->iv_bss
->ni_intval
;
977 case IEEE80211_IOC_PUREG
:
978 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_PUREG
) != 0;
980 case IEEE80211_IOC_QUIET
:
981 ireq
->i_val
= vap
->iv_quiet
;
983 case IEEE80211_IOC_QUIET_COUNT
:
984 ireq
->i_val
= vap
->iv_quiet_count
;
986 case IEEE80211_IOC_QUIET_PERIOD
:
987 ireq
->i_val
= vap
->iv_quiet_period
;
989 case IEEE80211_IOC_QUIET_DUR
:
990 ireq
->i_val
= vap
->iv_quiet_duration
;
992 case IEEE80211_IOC_QUIET_OFFSET
:
993 ireq
->i_val
= vap
->iv_quiet_offset
;
995 case IEEE80211_IOC_BGSCAN
:
996 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_BGSCAN
) != 0;
998 case IEEE80211_IOC_BGSCAN_IDLE
:
999 ireq
->i_val
= vap
->iv_bgscanidle
*hz
/1000; /* ms */
1001 case IEEE80211_IOC_BGSCAN_INTERVAL
:
1002 ireq
->i_val
= vap
->iv_bgscanintvl
/hz
; /* seconds */
1004 case IEEE80211_IOC_SCANVALID
:
1005 ireq
->i_val
= vap
->iv_scanvalid
/hz
; /* seconds */
1007 case IEEE80211_IOC_FRAGTHRESHOLD
:
1008 ireq
->i_val
= vap
->iv_fragthreshold
;
1010 case IEEE80211_IOC_MACCMD
:
1011 error
= ieee80211_ioctl_getmaccmd(vap
, ireq
);
1013 case IEEE80211_IOC_BURST
:
1014 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_BURST
) != 0;
1016 case IEEE80211_IOC_BMISSTHRESHOLD
:
1017 ireq
->i_val
= vap
->iv_bmissthreshold
;
1019 case IEEE80211_IOC_CURCHAN
:
1020 error
= ieee80211_ioctl_getcurchan(vap
, ireq
);
1022 case IEEE80211_IOC_SHORTGI
:
1024 if (vap
->iv_flags_ht
& IEEE80211_FHT_SHORTGI20
)
1025 ireq
->i_val
|= IEEE80211_HTCAP_SHORTGI20
;
1026 if (vap
->iv_flags_ht
& IEEE80211_FHT_SHORTGI40
)
1027 ireq
->i_val
|= IEEE80211_HTCAP_SHORTGI40
;
1029 case IEEE80211_IOC_AMPDU
:
1031 if (vap
->iv_flags_ht
& IEEE80211_FHT_AMPDU_TX
)
1033 if (vap
->iv_flags_ht
& IEEE80211_FHT_AMPDU_RX
)
1036 case IEEE80211_IOC_AMPDU_LIMIT
:
1037 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
)
1038 ireq
->i_val
= vap
->iv_ampdu_rxmax
;
1039 else if (vap
->iv_state
== IEEE80211_S_RUN
|| vap
->iv_state
== IEEE80211_S_SLEEP
)
1041 * XXX TODO: this isn't completely correct, as we've
1042 * negotiated the higher of the two.
1044 ireq
->i_val
= MS(vap
->iv_bss
->ni_htparam
,
1045 IEEE80211_HTCAP_MAXRXAMPDU
);
1047 ireq
->i_val
= vap
->iv_ampdu_limit
;
1049 case IEEE80211_IOC_AMPDU_DENSITY
:
1050 if (vap
->iv_opmode
== IEEE80211_M_STA
&&
1051 (vap
->iv_state
== IEEE80211_S_RUN
|| vap
->iv_state
== IEEE80211_S_SLEEP
))
1053 * XXX TODO: this isn't completely correct, as we've
1054 * negotiated the higher of the two.
1056 ireq
->i_val
= MS(vap
->iv_bss
->ni_htparam
,
1057 IEEE80211_HTCAP_MPDUDENSITY
);
1059 ireq
->i_val
= vap
->iv_ampdu_density
;
1061 case IEEE80211_IOC_AMSDU
:
1063 if (vap
->iv_flags_ht
& IEEE80211_FHT_AMSDU_TX
)
1065 if (vap
->iv_flags_ht
& IEEE80211_FHT_AMSDU_RX
)
1068 case IEEE80211_IOC_AMSDU_LIMIT
:
1069 ireq
->i_val
= vap
->iv_amsdu_limit
; /* XXX truncation? */
1071 case IEEE80211_IOC_PUREN
:
1072 ireq
->i_val
= (vap
->iv_flags_ht
& IEEE80211_FHT_PUREN
) != 0;
1074 case IEEE80211_IOC_DOTH
:
1075 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_DOTH
) != 0;
1077 case IEEE80211_IOC_REGDOMAIN
:
1078 error
= ieee80211_ioctl_getregdomain(vap
, ireq
);
1080 case IEEE80211_IOC_ROAM
:
1081 error
= ieee80211_ioctl_getroam(vap
, ireq
);
1083 case IEEE80211_IOC_TXPARAMS
:
1084 error
= ieee80211_ioctl_gettxparams(vap
, ireq
);
1086 case IEEE80211_IOC_HTCOMPAT
:
1087 ireq
->i_val
= (vap
->iv_flags_ht
& IEEE80211_FHT_HTCOMPAT
) != 0;
1089 case IEEE80211_IOC_DWDS
:
1090 ireq
->i_val
= (vap
->iv_flags
& IEEE80211_F_DWDS
) != 0;
1092 case IEEE80211_IOC_INACTIVITY
:
1093 ireq
->i_val
= (vap
->iv_flags_ext
& IEEE80211_FEXT_INACT
) != 0;
1095 case IEEE80211_IOC_APPIE
:
1096 error
= ieee80211_ioctl_getappie(vap
, ireq
);
1098 case IEEE80211_IOC_WPS
:
1099 ireq
->i_val
= (vap
->iv_flags_ext
& IEEE80211_FEXT_WPS
) != 0;
1101 case IEEE80211_IOC_TSN
:
1102 ireq
->i_val
= (vap
->iv_flags_ext
& IEEE80211_FEXT_TSN
) != 0;
1104 case IEEE80211_IOC_DFS
:
1105 ireq
->i_val
= (vap
->iv_flags_ext
& IEEE80211_FEXT_DFS
) != 0;
1107 case IEEE80211_IOC_DOTD
:
1108 ireq
->i_val
= (vap
->iv_flags_ext
& IEEE80211_FEXT_DOTD
) != 0;
1110 case IEEE80211_IOC_DEVCAPS
:
1111 error
= ieee80211_ioctl_getdevcaps(ic
, ireq
);
1113 case IEEE80211_IOC_HTPROTMODE
:
1114 ireq
->i_val
= ic
->ic_htprotmode
;
1116 case IEEE80211_IOC_HTCONF
:
1117 if (vap
->iv_flags_ht
& IEEE80211_FHT_HT
) {
1119 if (vap
->iv_flags_ht
& IEEE80211_FHT_USEHT40
)
1124 case IEEE80211_IOC_STA_VLAN
:
1125 error
= ieee80211_ioctl_getstavlan(vap
, ireq
);
1127 case IEEE80211_IOC_SMPS
:
1128 if (vap
->iv_opmode
== IEEE80211_M_STA
&&
1129 (vap
->iv_state
== IEEE80211_S_RUN
|| vap
->iv_state
== IEEE80211_S_SLEEP
)) {
1130 if (vap
->iv_bss
->ni_flags
& IEEE80211_NODE_MIMO_RTS
)
1131 ireq
->i_val
= IEEE80211_HTCAP_SMPS_DYNAMIC
;
1132 else if (vap
->iv_bss
->ni_flags
& IEEE80211_NODE_MIMO_PS
)
1133 ireq
->i_val
= IEEE80211_HTCAP_SMPS_ENA
;
1135 ireq
->i_val
= IEEE80211_HTCAP_SMPS_OFF
;
1137 ireq
->i_val
= vap
->iv_htcaps
& IEEE80211_HTCAP_SMPS
;
1139 case IEEE80211_IOC_RIFS
:
1140 if (vap
->iv_opmode
== IEEE80211_M_STA
&&
1141 (vap
->iv_state
== IEEE80211_S_RUN
|| vap
->iv_state
== IEEE80211_S_SLEEP
))
1143 (vap
->iv_bss
->ni_flags
& IEEE80211_NODE_RIFS
) != 0;
1146 (vap
->iv_flags_ht
& IEEE80211_FHT_RIFS
) != 0;
1148 case IEEE80211_IOC_STBC
:
1150 if (vap
->iv_flags_ht
& IEEE80211_FHT_STBC_TX
)
1152 if (vap
->iv_flags_ht
& IEEE80211_FHT_STBC_RX
)
1156 error
= ieee80211_ioctl_getdefault(vap
, ireq
);
1164 ieee80211_ioctl_setkey(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1166 struct ieee80211req_key ik
;
1167 struct ieee80211_node
*ni
;
1168 struct ieee80211_key
*wk
;
1172 if (ireq
->i_len
!= sizeof(ik
))
1174 error
= copyin(ireq
->i_data
, &ik
, sizeof(ik
));
1177 /* NB: cipher support is verified by ieee80211_crypt_newkey */
1178 /* NB: this also checks ik->ik_keylen > sizeof(wk->wk_key) */
1179 if (ik
.ik_keylen
> sizeof(ik
.ik_keydata
))
1182 if (kid
== IEEE80211_KEYIX_NONE
) {
1183 /* XXX unicast keys currently must be tx/rx */
1184 if (ik
.ik_flags
!= (IEEE80211_KEY_XMIT
| IEEE80211_KEY_RECV
))
1186 if (vap
->iv_opmode
== IEEE80211_M_STA
) {
1187 ni
= ieee80211_ref_node(vap
->iv_bss
);
1188 if (!IEEE80211_ADDR_EQ(ik
.ik_macaddr
, ni
->ni_bssid
)) {
1189 ieee80211_free_node(ni
);
1190 return EADDRNOTAVAIL
;
1193 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
,
1198 wk
= &ni
->ni_ucastkey
;
1200 if (kid
>= IEEE80211_WEP_NKID
)
1202 wk
= &vap
->iv_nw_keys
[kid
];
1204 * Global slots start off w/o any assigned key index.
1205 * Force one here for consistency with IEEE80211_IOC_WEPKEY.
1207 if (wk
->wk_keyix
== IEEE80211_KEYIX_NONE
)
1212 ieee80211_key_update_begin(vap
);
1213 if (ieee80211_crypto_newkey(vap
, ik
.ik_type
, ik
.ik_flags
, wk
)) {
1214 wk
->wk_keylen
= ik
.ik_keylen
;
1215 /* NB: MIC presence is implied by cipher type */
1216 if (wk
->wk_keylen
> IEEE80211_KEYBUF_SIZE
)
1217 wk
->wk_keylen
= IEEE80211_KEYBUF_SIZE
;
1218 for (i
= 0; i
< IEEE80211_TID_SIZE
; i
++)
1219 wk
->wk_keyrsc
[i
] = ik
.ik_keyrsc
;
1220 wk
->wk_keytsc
= 0; /* new key, reset */
1221 memset(wk
->wk_key
, 0, sizeof(wk
->wk_key
));
1222 memcpy(wk
->wk_key
, ik
.ik_keydata
, ik
.ik_keylen
);
1223 IEEE80211_ADDR_COPY(wk
->wk_macaddr
,
1224 ni
!= NULL
? ni
->ni_macaddr
: ik
.ik_macaddr
);
1225 if (!ieee80211_crypto_setkey(vap
, wk
))
1227 else if ((ik
.ik_flags
& IEEE80211_KEY_DEFAULT
))
1228 vap
->iv_def_txkey
= kid
;
1231 ieee80211_key_update_end(vap
);
1233 ieee80211_free_node(ni
);
1238 ieee80211_ioctl_delkey(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1240 struct ieee80211req_del_key dk
;
1243 if (ireq
->i_len
!= sizeof(dk
))
1245 error
= copyin(ireq
->i_data
, &dk
, sizeof(dk
));
1249 /* XXX uint8_t -> uint16_t */
1250 if (dk
.idk_keyix
== (uint8_t) IEEE80211_KEYIX_NONE
) {
1251 struct ieee80211_node
*ni
;
1253 if (vap
->iv_opmode
== IEEE80211_M_STA
) {
1254 ni
= ieee80211_ref_node(vap
->iv_bss
);
1255 if (!IEEE80211_ADDR_EQ(dk
.idk_macaddr
, ni
->ni_bssid
)) {
1256 ieee80211_free_node(ni
);
1257 return EADDRNOTAVAIL
;
1260 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
,
1265 /* XXX error return */
1266 ieee80211_node_delucastkey(ni
);
1267 ieee80211_free_node(ni
);
1269 if (kid
>= IEEE80211_WEP_NKID
)
1271 /* XXX error return */
1272 ieee80211_crypto_delkey(vap
, &vap
->iv_nw_keys
[kid
]);
1278 struct ieee80211vap
*vap
;
1284 mlmedebug(struct ieee80211vap
*vap
, const uint8_t mac
[IEEE80211_ADDR_LEN
],
1287 #ifdef IEEE80211_DEBUG
1288 static const struct {
1293 { IEEE80211_MSG_IOCTL
| IEEE80211_MSG_STATE
|
1294 IEEE80211_MSG_ASSOC
, "assoc" },
1295 { IEEE80211_MSG_IOCTL
| IEEE80211_MSG_STATE
|
1296 IEEE80211_MSG_ASSOC
, "disassoc" },
1297 { IEEE80211_MSG_IOCTL
| IEEE80211_MSG_STATE
|
1298 IEEE80211_MSG_AUTH
, "deauth" },
1299 { IEEE80211_MSG_IOCTL
| IEEE80211_MSG_STATE
|
1300 IEEE80211_MSG_AUTH
, "authorize" },
1301 { IEEE80211_MSG_IOCTL
| IEEE80211_MSG_STATE
|
1302 IEEE80211_MSG_AUTH
, "unauthorize" },
1305 if (op
== IEEE80211_MLME_AUTH
) {
1306 IEEE80211_NOTE_MAC(vap
, IEEE80211_MSG_IOCTL
|
1307 IEEE80211_MSG_STATE
| IEEE80211_MSG_AUTH
, mac
,
1308 "station authenticate %s via MLME (reason: %d (%s))",
1309 reason
== IEEE80211_STATUS_SUCCESS
? "ACCEPT" : "REJECT",
1310 reason
, ieee80211_reason_to_string(reason
));
1311 } else if (!(IEEE80211_MLME_ASSOC
<= op
&& op
<= IEEE80211_MLME_AUTH
)) {
1312 IEEE80211_NOTE_MAC(vap
, IEEE80211_MSG_ANY
, mac
,
1313 "unknown MLME request %d (reason: %d (%s))", op
, reason
,
1314 ieee80211_reason_to_string(reason
));
1315 } else if (reason
== IEEE80211_STATUS_SUCCESS
) {
1316 IEEE80211_NOTE_MAC(vap
, ops
[op
].mask
, mac
,
1317 "station %s via MLME", ops
[op
].opstr
);
1319 IEEE80211_NOTE_MAC(vap
, ops
[op
].mask
, mac
,
1320 "station %s via MLME (reason: %d (%s))", ops
[op
].opstr
,
1321 reason
, ieee80211_reason_to_string(reason
));
1323 #endif /* IEEE80211_DEBUG */
1327 domlme(void *arg
, struct ieee80211_node
*ni
)
1329 struct mlmeop
*mop
= arg
;
1330 struct ieee80211vap
*vap
= ni
->ni_vap
;
1332 if (vap
!= mop
->vap
)
1335 * NB: if ni_associd is zero then the node is already cleaned
1336 * up and we don't need to do this (we're safely holding a
1337 * reference but should otherwise not modify it's state).
1339 if (ni
->ni_associd
== 0)
1341 mlmedebug(vap
, ni
->ni_macaddr
, mop
->op
, mop
->reason
);
1342 if (mop
->op
== IEEE80211_MLME_DEAUTH
) {
1343 IEEE80211_SEND_MGMT(ni
, IEEE80211_FC0_SUBTYPE_DEAUTH
,
1346 IEEE80211_SEND_MGMT(ni
, IEEE80211_FC0_SUBTYPE_DISASSOC
,
1349 ieee80211_node_leave(ni
);
1353 setmlme_dropsta(struct ieee80211vap
*vap
,
1354 const uint8_t mac
[IEEE80211_ADDR_LEN
], struct mlmeop
*mlmeop
)
1356 struct ieee80211_node_table
*nt
= &vap
->iv_ic
->ic_sta
;
1357 struct ieee80211_node
*ni
;
1360 /* NB: the broadcast address means do 'em all */
1361 if (!IEEE80211_ADDR_EQ(mac
, vap
->iv_ifp
->if_broadcastaddr
)) {
1362 IEEE80211_NODE_LOCK(nt
);
1363 ni
= ieee80211_find_node_locked(nt
, mac
);
1364 IEEE80211_NODE_UNLOCK(nt
);
1366 * Don't do the node update inside the node
1367 * table lock. This unfortunately causes LORs
1368 * with drivers and their TX paths.
1372 ieee80211_free_node(ni
);
1376 ieee80211_iterate_nodes(nt
, domlme
, mlmeop
);
1382 setmlme_common(struct ieee80211vap
*vap
, int op
,
1383 const uint8_t mac
[IEEE80211_ADDR_LEN
], int reason
)
1385 struct ieee80211com
*ic
= vap
->iv_ic
;
1386 struct ieee80211_node_table
*nt
= &ic
->ic_sta
;
1387 struct ieee80211_node
*ni
;
1388 struct mlmeop mlmeop
;
1393 case IEEE80211_MLME_DISASSOC
:
1394 case IEEE80211_MLME_DEAUTH
:
1395 switch (vap
->iv_opmode
) {
1396 case IEEE80211_M_STA
:
1397 mlmedebug(vap
, vap
->iv_bss
->ni_macaddr
, op
, reason
);
1398 /* XXX not quite right */
1399 ieee80211_new_state(vap
, IEEE80211_S_INIT
, reason
);
1401 case IEEE80211_M_HOSTAP
:
1404 mlmeop
.reason
= reason
;
1405 error
= setmlme_dropsta(vap
, mac
, &mlmeop
);
1407 case IEEE80211_M_WDS
:
1408 /* XXX user app should send raw frame? */
1409 if (op
!= IEEE80211_MLME_DEAUTH
) {
1414 /* XXX accept any address, simplifies user code */
1415 if (!IEEE80211_ADDR_EQ(mac
, vap
->iv_bss
->ni_macaddr
)) {
1420 mlmedebug(vap
, vap
->iv_bss
->ni_macaddr
, op
, reason
);
1421 ni
= ieee80211_ref_node(vap
->iv_bss
);
1422 IEEE80211_SEND_MGMT(ni
,
1423 IEEE80211_FC0_SUBTYPE_DEAUTH
, reason
);
1424 ieee80211_free_node(ni
);
1426 case IEEE80211_M_MBSS
:
1427 IEEE80211_NODE_LOCK(nt
);
1428 ni
= ieee80211_find_node_locked(nt
, mac
);
1430 * Don't do the node update inside the node
1431 * table lock. This unfortunately causes LORs
1432 * with drivers and their TX paths.
1434 IEEE80211_NODE_UNLOCK(nt
);
1436 ieee80211_node_leave(ni
);
1437 ieee80211_free_node(ni
);
1447 case IEEE80211_MLME_AUTHORIZE
:
1448 case IEEE80211_MLME_UNAUTHORIZE
:
1449 if (vap
->iv_opmode
!= IEEE80211_M_HOSTAP
&&
1450 vap
->iv_opmode
!= IEEE80211_M_WDS
) {
1454 IEEE80211_NODE_LOCK(nt
);
1455 ni
= ieee80211_find_vap_node_locked(nt
, vap
, mac
);
1457 * Don't do the node update inside the node
1458 * table lock. This unfortunately causes LORs
1459 * with drivers and their TX paths.
1461 IEEE80211_NODE_UNLOCK(nt
);
1463 mlmedebug(vap
, mac
, op
, reason
);
1464 if (op
== IEEE80211_MLME_AUTHORIZE
)
1465 ieee80211_node_authorize(ni
);
1467 ieee80211_node_unauthorize(ni
);
1468 ieee80211_free_node(ni
);
1472 case IEEE80211_MLME_AUTH
:
1473 if (vap
->iv_opmode
!= IEEE80211_M_HOSTAP
) {
1477 IEEE80211_NODE_LOCK(nt
);
1478 ni
= ieee80211_find_vap_node_locked(nt
, vap
, mac
);
1480 * Don't do the node update inside the node
1481 * table lock. This unfortunately causes LORs
1482 * with drivers and their TX paths.
1484 IEEE80211_NODE_UNLOCK(nt
);
1486 mlmedebug(vap
, mac
, op
, reason
);
1487 if (reason
== IEEE80211_STATUS_SUCCESS
) {
1488 IEEE80211_SEND_MGMT(ni
,
1489 IEEE80211_FC0_SUBTYPE_AUTH
, 2);
1491 * For shared key auth, just continue the
1492 * exchange. Otherwise when 802.1x is not in
1493 * use mark the port authorized at this point
1494 * so traffic can flow.
1496 if (ni
->ni_authmode
!= IEEE80211_AUTH_8021X
&&
1497 ni
->ni_challenge
== NULL
)
1498 ieee80211_node_authorize(ni
);
1500 vap
->iv_stats
.is_rx_acl
++;
1501 ieee80211_send_error(ni
, ni
->ni_macaddr
,
1502 IEEE80211_FC0_SUBTYPE_AUTH
, 2|(reason
<<16));
1503 ieee80211_node_leave(ni
);
1505 ieee80211_free_node(ni
);
1519 const uint8_t *essid
;
1520 const struct ieee80211_scan_entry
*se
;
1524 * Match mac address and any ssid.
1527 mlmelookup(void *arg
, const struct ieee80211_scan_entry
*se
)
1529 struct scanlookup
*look
= arg
;
1531 if (!IEEE80211_ADDR_EQ(look
->mac
, se
->se_macaddr
))
1533 if (look
->esslen
!= 0) {
1534 if (se
->se_ssid
[1] != look
->esslen
)
1536 if (memcmp(look
->essid
, se
->se_ssid
+2, look
->esslen
))
1543 setmlme_assoc_sta(struct ieee80211vap
*vap
,
1544 const uint8_t mac
[IEEE80211_ADDR_LEN
], int ssid_len
,
1545 const uint8_t ssid
[IEEE80211_NWID_LEN
])
1547 struct scanlookup lookup
;
1549 KASSERT(vap
->iv_opmode
== IEEE80211_M_STA
,
1550 ("expected opmode STA not %s",
1551 ieee80211_opmode_name
[vap
->iv_opmode
]));
1553 /* NB: this is racey if roaming is !manual */
1556 lookup
.esslen
= ssid_len
;
1557 lookup
.essid
= ssid
;
1558 ieee80211_scan_iterate(vap
, mlmelookup
, &lookup
);
1559 if (lookup
.se
== NULL
)
1561 mlmedebug(vap
, mac
, IEEE80211_MLME_ASSOC
, 0);
1562 if (!ieee80211_sta_join(vap
, lookup
.se
->se_chan
, lookup
.se
))
1563 return EIO
; /* XXX unique but could be better */
1568 setmlme_assoc_adhoc(struct ieee80211vap
*vap
,
1569 const uint8_t mac
[IEEE80211_ADDR_LEN
], int ssid_len
,
1570 const uint8_t ssid
[IEEE80211_NWID_LEN
])
1572 struct ieee80211_scan_req
*sr
;
1575 KASSERT(vap
->iv_opmode
== IEEE80211_M_IBSS
||
1576 vap
->iv_opmode
== IEEE80211_M_AHDEMO
,
1577 ("expected opmode IBSS or AHDEMO not %s",
1578 ieee80211_opmode_name
[vap
->iv_opmode
]));
1583 #if defined(__DragonFly__)
1584 sr
= kmalloc(sizeof(*sr
), M_TEMP
, M_INTWAIT
| M_ZERO
);
1586 sr
= IEEE80211_MALLOC(sizeof(*sr
), M_TEMP
,
1587 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
1592 /* NB: IEEE80211_IOC_SSID call missing for ap_scan=2. */
1593 memset(vap
->iv_des_ssid
[0].ssid
, 0, IEEE80211_NWID_LEN
);
1594 vap
->iv_des_ssid
[0].len
= ssid_len
;
1595 memcpy(vap
->iv_des_ssid
[0].ssid
, ssid
, ssid_len
);
1596 vap
->iv_des_nssid
= 1;
1598 sr
->sr_flags
= IEEE80211_IOC_SCAN_ACTIVE
| IEEE80211_IOC_SCAN_ONCE
;
1599 sr
->sr_duration
= IEEE80211_IOC_SCAN_FOREVER
;
1600 memcpy(sr
->sr_ssid
[0].ssid
, ssid
, ssid_len
);
1601 sr
->sr_ssid
[0].len
= ssid_len
;
1604 error
= ieee80211_scanreq(vap
, sr
);
1606 IEEE80211_FREE(sr
, M_TEMP
);
1611 ieee80211_ioctl_setmlme(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1613 struct ieee80211req_mlme mlme
;
1616 if (ireq
->i_len
!= sizeof(mlme
))
1618 error
= copyin(ireq
->i_data
, &mlme
, sizeof(mlme
));
1621 if (vap
->iv_opmode
== IEEE80211_M_STA
&&
1622 mlme
.im_op
== IEEE80211_MLME_ASSOC
)
1623 return setmlme_assoc_sta(vap
, mlme
.im_macaddr
,
1624 vap
->iv_des_ssid
[0].len
, vap
->iv_des_ssid
[0].ssid
);
1625 else if ((vap
->iv_opmode
== IEEE80211_M_IBSS
||
1626 vap
->iv_opmode
== IEEE80211_M_AHDEMO
) &&
1627 mlme
.im_op
== IEEE80211_MLME_ASSOC
)
1628 return setmlme_assoc_adhoc(vap
, mlme
.im_macaddr
,
1629 mlme
.im_ssid_len
, mlme
.im_ssid
);
1631 return setmlme_common(vap
, mlme
.im_op
,
1632 mlme
.im_macaddr
, mlme
.im_reason
);
1636 ieee80211_ioctl_macmac(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1638 uint8_t mac
[IEEE80211_ADDR_LEN
];
1639 const struct ieee80211_aclator
*acl
= vap
->iv_acl
;
1642 if (ireq
->i_len
!= sizeof(mac
))
1644 error
= copyin(ireq
->i_data
, mac
, ireq
->i_len
);
1648 acl
= ieee80211_aclator_get("mac");
1649 if (acl
== NULL
|| !acl
->iac_attach(vap
))
1653 if (ireq
->i_type
== IEEE80211_IOC_ADDMAC
)
1654 acl
->iac_add(vap
, mac
);
1656 acl
->iac_remove(vap
, mac
);
1661 ieee80211_ioctl_setmaccmd(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1663 const struct ieee80211_aclator
*acl
= vap
->iv_acl
;
1665 switch (ireq
->i_val
) {
1666 case IEEE80211_MACCMD_POLICY_OPEN
:
1667 case IEEE80211_MACCMD_POLICY_ALLOW
:
1668 case IEEE80211_MACCMD_POLICY_DENY
:
1669 case IEEE80211_MACCMD_POLICY_RADIUS
:
1671 acl
= ieee80211_aclator_get("mac");
1672 if (acl
== NULL
|| !acl
->iac_attach(vap
))
1676 acl
->iac_setpolicy(vap
, ireq
->i_val
);
1678 case IEEE80211_MACCMD_FLUSH
:
1680 acl
->iac_flush(vap
);
1681 /* NB: silently ignore when not in use */
1683 case IEEE80211_MACCMD_DETACH
:
1686 acl
->iac_detach(vap
);
1693 return acl
->iac_setioctl(vap
, ireq
);
1699 ieee80211_ioctl_setchanlist(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1701 struct ieee80211com
*ic
= vap
->iv_ic
;
1702 uint8_t *chanlist
, *list
;
1703 int i
, nchan
, maxchan
, error
;
1705 if (ireq
->i_len
> sizeof(ic
->ic_chan_active
))
1706 ireq
->i_len
= sizeof(ic
->ic_chan_active
);
1707 #if defined(__DragonFly__)
1708 list
= kmalloc(ireq
->i_len
+ IEEE80211_CHAN_BYTES
, M_TEMP
,
1709 M_INTWAIT
| M_ZERO
);
1711 list
= IEEE80211_MALLOC(ireq
->i_len
+ IEEE80211_CHAN_BYTES
, M_TEMP
,
1712 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
1716 error
= copyin(ireq
->i_data
, list
, ireq
->i_len
);
1718 IEEE80211_FREE(list
, M_TEMP
);
1722 chanlist
= list
+ ireq
->i_len
; /* NB: zero'd already */
1723 maxchan
= ireq
->i_len
* NBBY
;
1724 for (i
= 0; i
< ic
->ic_nchans
; i
++) {
1725 const struct ieee80211_channel
*c
= &ic
->ic_channels
[i
];
1727 * Calculate the intersection of the user list and the
1728 * available channels so users can do things like specify
1729 * 1-255 to get all available channels.
1731 if (c
->ic_ieee
< maxchan
&& isset(list
, c
->ic_ieee
)) {
1732 setbit(chanlist
, c
->ic_ieee
);
1737 IEEE80211_FREE(list
, M_TEMP
);
1740 if (ic
->ic_bsschan
!= IEEE80211_CHAN_ANYC
&& /* XXX */
1741 isclr(chanlist
, ic
->ic_bsschan
->ic_ieee
))
1742 ic
->ic_bsschan
= IEEE80211_CHAN_ANYC
;
1743 memcpy(ic
->ic_chan_active
, chanlist
, IEEE80211_CHAN_BYTES
);
1744 ieee80211_scan_flush(vap
);
1745 IEEE80211_FREE(list
, M_TEMP
);
1750 ieee80211_ioctl_setstastats(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1752 struct ieee80211_node
*ni
;
1753 uint8_t macaddr
[IEEE80211_ADDR_LEN
];
1757 * NB: we could copyin ieee80211req_sta_stats so apps
1758 * could make selective changes but that's overkill;
1759 * just clear all stats for now.
1761 if (ireq
->i_len
< IEEE80211_ADDR_LEN
)
1763 error
= copyin(ireq
->i_data
, macaddr
, IEEE80211_ADDR_LEN
);
1766 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
, macaddr
);
1769 /* XXX require ni_vap == vap? */
1770 memset(&ni
->ni_stats
, 0, sizeof(ni
->ni_stats
));
1771 ieee80211_free_node(ni
);
1776 ieee80211_ioctl_setstatxpow(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1778 struct ieee80211_node
*ni
;
1779 struct ieee80211req_sta_txpow txpow
;
1782 if (ireq
->i_len
!= sizeof(txpow
))
1784 error
= copyin(ireq
->i_data
, &txpow
, sizeof(txpow
));
1787 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
, txpow
.it_macaddr
);
1790 ni
->ni_txpower
= txpow
.it_txpow
;
1791 ieee80211_free_node(ni
);
1796 ieee80211_ioctl_setwmeparam(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
1798 struct ieee80211com
*ic
= vap
->iv_ic
;
1799 struct ieee80211_wme_state
*wme
= &ic
->ic_wme
;
1800 struct wmeParams
*wmep
, *chanp
;
1801 int isbss
, ac
, aggrmode
;
1803 if ((ic
->ic_caps
& IEEE80211_C_WME
) == 0)
1806 isbss
= (ireq
->i_len
& IEEE80211_WMEPARAM_BSS
);
1807 ac
= (ireq
->i_len
& IEEE80211_WMEPARAM_VAL
);
1808 aggrmode
= (wme
->wme_flags
& WME_F_AGGRMODE
);
1809 if (ac
>= WME_NUM_AC
)
1812 chanp
= &wme
->wme_bssChanParams
.cap_wmeParams
[ac
];
1813 wmep
= &wme
->wme_wmeBssChanParams
.cap_wmeParams
[ac
];
1815 chanp
= &wme
->wme_chanParams
.cap_wmeParams
[ac
];
1816 wmep
= &wme
->wme_wmeChanParams
.cap_wmeParams
[ac
];
1818 switch (ireq
->i_type
) {
1819 case IEEE80211_IOC_WME_CWMIN
: /* WME: CWmin */
1820 wmep
->wmep_logcwmin
= ireq
->i_val
;
1821 if (!isbss
|| !aggrmode
)
1822 chanp
->wmep_logcwmin
= ireq
->i_val
;
1824 case IEEE80211_IOC_WME_CWMAX
: /* WME: CWmax */
1825 wmep
->wmep_logcwmax
= ireq
->i_val
;
1826 if (!isbss
|| !aggrmode
)
1827 chanp
->wmep_logcwmax
= ireq
->i_val
;
1829 case IEEE80211_IOC_WME_AIFS
: /* WME: AIFS */
1830 wmep
->wmep_aifsn
= ireq
->i_val
;
1831 if (!isbss
|| !aggrmode
)
1832 chanp
->wmep_aifsn
= ireq
->i_val
;
1834 case IEEE80211_IOC_WME_TXOPLIMIT
: /* WME: txops limit */
1835 wmep
->wmep_txopLimit
= ireq
->i_val
;
1836 if (!isbss
|| !aggrmode
)
1837 chanp
->wmep_txopLimit
= ireq
->i_val
;
1839 case IEEE80211_IOC_WME_ACM
: /* WME: ACM (bss only) */
1840 wmep
->wmep_acm
= ireq
->i_val
;
1842 chanp
->wmep_acm
= ireq
->i_val
;
1844 case IEEE80211_IOC_WME_ACKPOLICY
: /* WME: ACK policy (!bss only)*/
1845 wmep
->wmep_noackPolicy
= chanp
->wmep_noackPolicy
=
1849 ieee80211_wme_updateparams(vap
);
1854 find11gchannel(struct ieee80211com
*ic
, int start
, int freq
)
1856 const struct ieee80211_channel
*c
;
1859 for (i
= start
+1; i
< ic
->ic_nchans
; i
++) {
1860 c
= &ic
->ic_channels
[i
];
1861 if (c
->ic_freq
== freq
&& IEEE80211_IS_CHAN_ANYG(c
))
1864 /* NB: should not be needed but in case things are mis-sorted */
1865 for (i
= 0; i
< start
; i
++) {
1866 c
= &ic
->ic_channels
[i
];
1867 if (c
->ic_freq
== freq
&& IEEE80211_IS_CHAN_ANYG(c
))
1873 static struct ieee80211_channel
*
1874 findchannel(struct ieee80211com
*ic
, int ieee
, int mode
)
1876 static const u_int chanflags
[IEEE80211_MODE_MAX
] = {
1877 [IEEE80211_MODE_AUTO
] = 0,
1878 [IEEE80211_MODE_11A
] = IEEE80211_CHAN_A
,
1879 [IEEE80211_MODE_11B
] = IEEE80211_CHAN_B
,
1880 [IEEE80211_MODE_11G
] = IEEE80211_CHAN_G
,
1881 [IEEE80211_MODE_FH
] = IEEE80211_CHAN_FHSS
,
1882 [IEEE80211_MODE_TURBO_A
] = IEEE80211_CHAN_108A
,
1883 [IEEE80211_MODE_TURBO_G
] = IEEE80211_CHAN_108G
,
1884 [IEEE80211_MODE_STURBO_A
] = IEEE80211_CHAN_STURBO
,
1885 [IEEE80211_MODE_HALF
] = IEEE80211_CHAN_HALF
,
1886 [IEEE80211_MODE_QUARTER
] = IEEE80211_CHAN_QUARTER
,
1887 /* NB: handled specially below */
1888 [IEEE80211_MODE_11NA
] = IEEE80211_CHAN_A
,
1889 [IEEE80211_MODE_11NG
] = IEEE80211_CHAN_G
,
1894 modeflags
= chanflags
[mode
];
1895 for (i
= 0; i
< ic
->ic_nchans
; i
++) {
1896 struct ieee80211_channel
*c
= &ic
->ic_channels
[i
];
1898 if (c
->ic_ieee
!= ieee
)
1900 if (mode
== IEEE80211_MODE_AUTO
) {
1901 /* ignore turbo channels for autoselect */
1902 if (IEEE80211_IS_CHAN_TURBO(c
))
1905 * XXX special-case 11b/g channels so we
1906 * always select the g channel if both
1908 * XXX prefer HT to non-HT?
1910 if (!IEEE80211_IS_CHAN_B(c
) ||
1911 !find11gchannel(ic
, i
, c
->ic_freq
))
1914 /* must check HT specially */
1915 if ((mode
== IEEE80211_MODE_11NA
||
1916 mode
== IEEE80211_MODE_11NG
) &&
1917 !IEEE80211_IS_CHAN_HT(c
))
1919 if ((c
->ic_flags
& modeflags
) == modeflags
)
1927 * Check the specified against any desired mode (aka netband).
1928 * This is only used (presently) when operating in hostap mode
1929 * to enforce consistency.
1932 check_mode_consistency(const struct ieee80211_channel
*c
, int mode
)
1934 KASSERT(c
!= IEEE80211_CHAN_ANYC
, ("oops, no channel"));
1937 case IEEE80211_MODE_11B
:
1938 return (IEEE80211_IS_CHAN_B(c
));
1939 case IEEE80211_MODE_11G
:
1940 return (IEEE80211_IS_CHAN_ANYG(c
) && !IEEE80211_IS_CHAN_HT(c
));
1941 case IEEE80211_MODE_11A
:
1942 return (IEEE80211_IS_CHAN_A(c
) && !IEEE80211_IS_CHAN_HT(c
));
1943 case IEEE80211_MODE_STURBO_A
:
1944 return (IEEE80211_IS_CHAN_STURBO(c
));
1945 case IEEE80211_MODE_11NA
:
1946 return (IEEE80211_IS_CHAN_HTA(c
));
1947 case IEEE80211_MODE_11NG
:
1948 return (IEEE80211_IS_CHAN_HTG(c
));
1955 * Common code to set the current channel. If the device
1956 * is up and running this may result in an immediate channel
1957 * change or a kick of the state machine.
1960 setcurchan(struct ieee80211vap
*vap
, struct ieee80211_channel
*c
)
1962 struct ieee80211com
*ic
= vap
->iv_ic
;
1965 if (c
!= IEEE80211_CHAN_ANYC
) {
1966 if (IEEE80211_IS_CHAN_RADAR(c
))
1967 return EBUSY
; /* XXX better code? */
1968 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
) {
1969 if (IEEE80211_IS_CHAN_NOHOSTAP(c
))
1971 if (!check_mode_consistency(c
, vap
->iv_des_mode
))
1973 } else if (vap
->iv_opmode
== IEEE80211_M_IBSS
) {
1974 if (IEEE80211_IS_CHAN_NOADHOC(c
))
1977 if ((vap
->iv_state
== IEEE80211_S_RUN
|| vap
->iv_state
== IEEE80211_S_SLEEP
) &&
1978 vap
->iv_bss
->ni_chan
== c
)
1979 return 0; /* NB: nothing to do */
1981 vap
->iv_des_chan
= c
;
1984 if (vap
->iv_opmode
== IEEE80211_M_MONITOR
&&
1985 vap
->iv_des_chan
!= IEEE80211_CHAN_ANYC
) {
1987 * Monitor mode can switch directly.
1989 if (IFNET_IS_UP_RUNNING(vap
->iv_ifp
)) {
1990 /* XXX need state machine for other vap's to follow */
1991 ieee80211_setcurchan(ic
, vap
->iv_des_chan
);
1992 vap
->iv_bss
->ni_chan
= ic
->ic_curchan
;
1994 ic
->ic_curchan
= vap
->iv_des_chan
;
1995 ic
->ic_rt
= ieee80211_get_ratetable(ic
->ic_curchan
);
1999 * Need to go through the state machine in case we
2000 * need to reassociate or the like. The state machine
2001 * will pickup the desired channel and avoid scanning.
2003 if (IS_UP_AUTO(vap
))
2004 ieee80211_new_state(vap
, IEEE80211_S_SCAN
, 0);
2005 else if (vap
->iv_des_chan
!= IEEE80211_CHAN_ANYC
) {
2007 * When not up+running and a real channel has
2008 * been specified fix the current channel so
2009 * there is immediate feedback; e.g. via ifconfig.
2011 ic
->ic_curchan
= vap
->iv_des_chan
;
2012 ic
->ic_rt
= ieee80211_get_ratetable(ic
->ic_curchan
);
2019 * Old api for setting the current channel; this is
2020 * deprecated because channel numbers are ambiguous.
2023 ieee80211_ioctl_setchannel(struct ieee80211vap
*vap
,
2024 const struct ieee80211req
*ireq
)
2026 struct ieee80211com
*ic
= vap
->iv_ic
;
2027 struct ieee80211_channel
*c
;
2029 /* XXX 0xffff overflows 16-bit signed */
2030 if (ireq
->i_val
== 0 ||
2031 ireq
->i_val
== (int16_t) IEEE80211_CHAN_ANY
) {
2032 c
= IEEE80211_CHAN_ANYC
;
2034 struct ieee80211_channel
*c2
;
2036 c
= findchannel(ic
, ireq
->i_val
, vap
->iv_des_mode
);
2038 c
= findchannel(ic
, ireq
->i_val
,
2039 IEEE80211_MODE_AUTO
);
2044 * Fine tune channel selection based on desired mode:
2045 * if 11b is requested, find the 11b version of any
2046 * 11g channel returned,
2047 * if static turbo, find the turbo version of any
2048 * 11a channel return,
2049 * if 11na is requested, find the ht version of any
2050 * 11a channel returned,
2051 * if 11ng is requested, find the ht version of any
2052 * 11g channel returned,
2053 * otherwise we should be ok with what we've got.
2055 switch (vap
->iv_des_mode
) {
2056 case IEEE80211_MODE_11B
:
2057 if (IEEE80211_IS_CHAN_ANYG(c
)) {
2058 c2
= findchannel(ic
, ireq
->i_val
,
2059 IEEE80211_MODE_11B
);
2060 /* NB: should not happen, =>'s 11g w/o 11b */
2065 case IEEE80211_MODE_TURBO_A
:
2066 if (IEEE80211_IS_CHAN_A(c
)) {
2067 c2
= findchannel(ic
, ireq
->i_val
,
2068 IEEE80211_MODE_TURBO_A
);
2073 case IEEE80211_MODE_11NA
:
2074 if (IEEE80211_IS_CHAN_A(c
)) {
2075 c2
= findchannel(ic
, ireq
->i_val
,
2076 IEEE80211_MODE_11NA
);
2081 case IEEE80211_MODE_11NG
:
2082 if (IEEE80211_IS_CHAN_ANYG(c
)) {
2083 c2
= findchannel(ic
, ireq
->i_val
,
2084 IEEE80211_MODE_11NG
);
2089 default: /* NB: no static turboG */
2093 return setcurchan(vap
, c
);
2097 * New/current api for setting the current channel; a complete
2098 * channel description is provide so there is no ambiguity in
2099 * identifying the channel.
2102 ieee80211_ioctl_setcurchan(struct ieee80211vap
*vap
,
2103 const struct ieee80211req
*ireq
)
2105 struct ieee80211com
*ic
= vap
->iv_ic
;
2106 struct ieee80211_channel chan
, *c
;
2109 if (ireq
->i_len
!= sizeof(chan
))
2111 error
= copyin(ireq
->i_data
, &chan
, sizeof(chan
));
2114 /* XXX 0xffff overflows 16-bit signed */
2115 if (chan
.ic_freq
== 0 || chan
.ic_freq
== IEEE80211_CHAN_ANY
) {
2116 c
= IEEE80211_CHAN_ANYC
;
2118 c
= ieee80211_find_channel(ic
, chan
.ic_freq
, chan
.ic_flags
);
2122 return setcurchan(vap
, c
);
2126 ieee80211_ioctl_setregdomain(struct ieee80211vap
*vap
,
2127 const struct ieee80211req
*ireq
)
2129 struct ieee80211_regdomain_req
*reg
;
2132 nchans
= 1 + ((ireq
->i_len
- sizeof(struct ieee80211_regdomain_req
)) /
2133 sizeof(struct ieee80211_channel
));
2134 if (!(1 <= nchans
&& nchans
<= IEEE80211_CHAN_MAX
)) {
2135 IEEE80211_DPRINTF(vap
, IEEE80211_MSG_IOCTL
,
2136 "%s: bad # chans, i_len %d nchans %d\n", __func__
,
2137 ireq
->i_len
, nchans
);
2140 #if defined(__DragonFly__)
2141 reg
= (struct ieee80211_regdomain_req
*)
2142 kmalloc(IEEE80211_REGDOMAIN_SIZE(nchans
), M_TEMP
, M_INTWAIT
);
2144 reg
= (struct ieee80211_regdomain_req
*)
2145 IEEE80211_MALLOC(IEEE80211_REGDOMAIN_SIZE(nchans
), M_TEMP
,
2146 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
2149 IEEE80211_DPRINTF(vap
, IEEE80211_MSG_IOCTL
,
2150 "%s: no memory, nchans %d\n", __func__
, nchans
);
2153 error
= copyin(ireq
->i_data
, reg
, IEEE80211_REGDOMAIN_SIZE(nchans
));
2155 /* NB: validate inline channel count against storage size */
2156 if (reg
->chaninfo
.ic_nchans
!= nchans
) {
2157 IEEE80211_DPRINTF(vap
, IEEE80211_MSG_IOCTL
,
2158 "%s: chan cnt mismatch, %d != %d\n", __func__
,
2159 reg
->chaninfo
.ic_nchans
, nchans
);
2162 error
= ieee80211_setregdomain(vap
, reg
);
2164 IEEE80211_FREE(reg
, M_TEMP
);
2166 return (error
== 0 ? ENETRESET
: error
);
2170 ieee80211_ioctl_setroam(struct ieee80211vap
*vap
,
2171 const struct ieee80211req
*ireq
)
2173 if (ireq
->i_len
!= sizeof(vap
->iv_roamparms
))
2175 /* XXX validate params */
2176 /* XXX? ENETRESET to push to device? */
2177 return copyin(ireq
->i_data
, vap
->iv_roamparms
,
2178 sizeof(vap
->iv_roamparms
));
2182 checkrate(const struct ieee80211_rateset
*rs
, int rate
)
2186 if (rate
== IEEE80211_FIXED_RATE_NONE
)
2188 for (i
= 0; i
< rs
->rs_nrates
; i
++)
2189 if ((rs
->rs_rates
[i
] & IEEE80211_RATE_VAL
) == rate
)
2197 if (mcs
== IEEE80211_FIXED_RATE_NONE
)
2199 if ((mcs
& IEEE80211_RATE_MCS
) == 0) /* MCS always have 0x80 set */
2201 return (mcs
& 0x7f) <= 15; /* XXX could search ht rate set */
2205 ieee80211_ioctl_settxparams(struct ieee80211vap
*vap
,
2206 const struct ieee80211req
*ireq
)
2208 struct ieee80211com
*ic
= vap
->iv_ic
;
2209 struct ieee80211_txparams_req parms
; /* XXX stack use? */
2210 struct ieee80211_txparam
*src
, *dst
;
2211 const struct ieee80211_rateset
*rs
;
2212 int error
, mode
, changed
, is11n
, nmodes
;
2214 /* NB: accept short requests for backwards compat */
2215 if (ireq
->i_len
> sizeof(parms
))
2217 error
= copyin(ireq
->i_data
, &parms
, ireq
->i_len
);
2220 nmodes
= ireq
->i_len
/ sizeof(struct ieee80211_txparam
);
2222 /* validate parameters and check if anything changed */
2223 for (mode
= IEEE80211_MODE_11A
; mode
< nmodes
; mode
++) {
2224 if (isclr(ic
->ic_modecaps
, mode
))
2226 src
= &parms
.params
[mode
];
2227 dst
= &vap
->iv_txparms
[mode
];
2228 rs
= &ic
->ic_sup_rates
[mode
]; /* NB: 11n maps to legacy */
2229 is11n
= (mode
== IEEE80211_MODE_11NA
||
2230 mode
== IEEE80211_MODE_11NG
);
2231 if (src
->ucastrate
!= dst
->ucastrate
) {
2232 if (!checkrate(rs
, src
->ucastrate
) &&
2233 (!is11n
|| !checkmcs(src
->ucastrate
)))
2237 if (src
->mcastrate
!= dst
->mcastrate
) {
2238 if (!checkrate(rs
, src
->mcastrate
) &&
2239 (!is11n
|| !checkmcs(src
->mcastrate
)))
2243 if (src
->mgmtrate
!= dst
->mgmtrate
) {
2244 if (!checkrate(rs
, src
->mgmtrate
) &&
2245 (!is11n
|| !checkmcs(src
->mgmtrate
)))
2249 if (src
->maxretry
!= dst
->maxretry
) /* NB: no bounds */
2254 * Copy new parameters in place and notify the
2255 * driver so it can push state to the device.
2257 for (mode
= IEEE80211_MODE_11A
; mode
< nmodes
; mode
++) {
2258 if (isset(ic
->ic_modecaps
, mode
))
2259 vap
->iv_txparms
[mode
] = parms
.params
[mode
];
2261 /* XXX could be more intelligent,
2262 e.g. don't reset if setting not being used */
2269 * Application Information Element support.
2272 setappie(struct ieee80211_appie
**aie
, const struct ieee80211req
*ireq
)
2274 struct ieee80211_appie
*app
= *aie
;
2275 struct ieee80211_appie
*napp
;
2278 if (ireq
->i_len
== 0) { /* delete any existing ie */
2280 *aie
= NULL
; /* XXX racey */
2281 IEEE80211_FREE(app
, M_80211_NODE_IE
);
2285 if (!(2 <= ireq
->i_len
&& ireq
->i_len
<= IEEE80211_MAX_APPIE
))
2288 * Allocate a new appie structure and copy in the user data.
2289 * When done swap in the new structure. Note that we do not
2290 * guard against users holding a ref to the old structure;
2291 * this must be handled outside this code.
2295 #if defined(__DragonFly__)
2296 napp
= (struct ieee80211_appie
*) kmalloc(
2297 sizeof(struct ieee80211_appie
) + ireq
->i_len
, M_80211_NODE_IE
, M_INTWAIT
);
2299 napp
= (struct ieee80211_appie
*) IEEE80211_MALLOC(
2300 sizeof(struct ieee80211_appie
) + ireq
->i_len
, M_80211_NODE_IE
,
2301 IEEE80211_M_NOWAIT
);
2305 /* XXX holding ic lock */
2306 error
= copyin(ireq
->i_data
, napp
->ie_data
, ireq
->i_len
);
2308 IEEE80211_FREE(napp
, M_80211_NODE_IE
);
2311 napp
->ie_len
= ireq
->i_len
;
2314 IEEE80211_FREE(app
, M_80211_NODE_IE
);
2319 setwparsnie(struct ieee80211vap
*vap
, uint8_t *ie
, int space
)
2321 /* validate data is present as best we can */
2322 if (space
== 0 || 2+ie
[1] > space
)
2324 if (ie
[0] == IEEE80211_ELEMID_VENDOR
)
2325 vap
->iv_wpa_ie
= ie
;
2326 else if (ie
[0] == IEEE80211_ELEMID_RSN
)
2327 vap
->iv_rsn_ie
= ie
;
2331 ieee80211_ioctl_setappie_locked(struct ieee80211vap
*vap
,
2332 const struct ieee80211req
*ireq
, int fc0
)
2336 IEEE80211_LOCK_ASSERT(vap
->iv_ic
);
2338 switch (fc0
& IEEE80211_FC0_SUBTYPE_MASK
) {
2339 case IEEE80211_FC0_SUBTYPE_BEACON
:
2340 if (vap
->iv_opmode
!= IEEE80211_M_HOSTAP
&&
2341 vap
->iv_opmode
!= IEEE80211_M_IBSS
) {
2345 error
= setappie(&vap
->iv_appie_beacon
, ireq
);
2347 ieee80211_beacon_notify(vap
, IEEE80211_BEACON_APPIE
);
2349 case IEEE80211_FC0_SUBTYPE_PROBE_RESP
:
2350 error
= setappie(&vap
->iv_appie_proberesp
, ireq
);
2352 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP
:
2353 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
)
2354 error
= setappie(&vap
->iv_appie_assocresp
, ireq
);
2358 case IEEE80211_FC0_SUBTYPE_PROBE_REQ
:
2359 error
= setappie(&vap
->iv_appie_probereq
, ireq
);
2361 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ
:
2362 if (vap
->iv_opmode
== IEEE80211_M_STA
)
2363 error
= setappie(&vap
->iv_appie_assocreq
, ireq
);
2367 case (IEEE80211_APPIE_WPA
& IEEE80211_FC0_SUBTYPE_MASK
):
2368 error
= setappie(&vap
->iv_appie_wpa
, ireq
);
2371 * Must split single blob of data into separate
2372 * WPA and RSN ie's because they go in different
2373 * locations in the mgt frames.
2374 * XXX use IEEE80211_IOC_WPA2 so user code does split
2376 vap
->iv_wpa_ie
= NULL
;
2377 vap
->iv_rsn_ie
= NULL
;
2378 if (vap
->iv_appie_wpa
!= NULL
) {
2379 struct ieee80211_appie
*appie
=
2381 uint8_t *data
= appie
->ie_data
;
2383 /* XXX ie length validate is painful, cheat */
2384 setwparsnie(vap
, data
, appie
->ie_len
);
2385 setwparsnie(vap
, data
+ 2 + data
[1],
2386 appie
->ie_len
- (2 + data
[1]));
2388 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
||
2389 vap
->iv_opmode
== IEEE80211_M_IBSS
) {
2391 * Must rebuild beacon frame as the update
2392 * mechanism doesn't handle WPA/RSN ie's.
2393 * Could extend it but it doesn't normally
2394 * change; this is just to deal with hostapd
2395 * plumbing the ie after the interface is up.
2409 ieee80211_ioctl_setappie(struct ieee80211vap
*vap
,
2410 const struct ieee80211req
*ireq
)
2412 struct ieee80211com
*ic
= vap
->iv_ic
;
2416 fc0
= ireq
->i_val
& 0xff;
2417 if ((fc0
& IEEE80211_FC0_TYPE_MASK
) != IEEE80211_FC0_TYPE_MGT
)
2419 /* NB: could check iv_opmode and reject but hardly worth the effort */
2421 error
= ieee80211_ioctl_setappie_locked(vap
, ireq
, fc0
);
2422 IEEE80211_UNLOCK(ic
);
2427 ieee80211_ioctl_chanswitch(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
2429 struct ieee80211com
*ic
= vap
->iv_ic
;
2430 struct ieee80211_chanswitch_req csr
;
2431 struct ieee80211_channel
*c
;
2434 if (ireq
->i_len
!= sizeof(csr
))
2436 error
= copyin(ireq
->i_data
, &csr
, sizeof(csr
));
2439 /* XXX adhoc mode not supported */
2440 if (vap
->iv_opmode
!= IEEE80211_M_HOSTAP
||
2441 (vap
->iv_flags
& IEEE80211_F_DOTH
) == 0)
2443 c
= ieee80211_find_channel(ic
,
2444 csr
.csa_chan
.ic_freq
, csr
.csa_chan
.ic_flags
);
2448 if ((ic
->ic_flags
& IEEE80211_F_CSAPENDING
) == 0)
2449 ieee80211_csa_startswitch(ic
, c
, csr
.csa_mode
, csr
.csa_count
);
2450 else if (csr
.csa_count
== 0)
2451 ieee80211_csa_cancelswitch(ic
);
2454 IEEE80211_UNLOCK(ic
);
2459 ieee80211_scanreq(struct ieee80211vap
*vap
, struct ieee80211_scan_req
*sr
)
2461 #define IEEE80211_IOC_SCAN_FLAGS \
2462 (IEEE80211_IOC_SCAN_NOPICK | IEEE80211_IOC_SCAN_ACTIVE | \
2463 IEEE80211_IOC_SCAN_PICK1ST | IEEE80211_IOC_SCAN_BGSCAN | \
2464 IEEE80211_IOC_SCAN_ONCE | IEEE80211_IOC_SCAN_NOBCAST | \
2465 IEEE80211_IOC_SCAN_NOJOIN | IEEE80211_IOC_SCAN_FLUSH | \
2466 IEEE80211_IOC_SCAN_CHECK)
2467 struct ieee80211com
*ic
= vap
->iv_ic
;
2470 /* convert duration */
2471 if (sr
->sr_duration
== IEEE80211_IOC_SCAN_FOREVER
)
2472 sr
->sr_duration
= IEEE80211_SCAN_FOREVER
;
2474 if (sr
->sr_duration
< IEEE80211_IOC_SCAN_DURATION_MIN
||
2475 sr
->sr_duration
> IEEE80211_IOC_SCAN_DURATION_MAX
)
2477 sr
->sr_duration
= msecs_to_ticks(sr
->sr_duration
);
2478 if (sr
->sr_duration
< 1)
2479 sr
->sr_duration
= 1;
2481 /* convert min/max channel dwell */
2482 if (sr
->sr_mindwell
!= 0) {
2483 sr
->sr_mindwell
= msecs_to_ticks(sr
->sr_mindwell
);
2484 if (sr
->sr_mindwell
< 1)
2485 sr
->sr_mindwell
= 1;
2487 if (sr
->sr_maxdwell
!= 0) {
2488 sr
->sr_maxdwell
= msecs_to_ticks(sr
->sr_maxdwell
);
2489 if (sr
->sr_maxdwell
< 1)
2490 sr
->sr_maxdwell
= 1;
2492 /* NB: silently reduce ssid count to what is supported */
2493 if (sr
->sr_nssid
> IEEE80211_SCAN_MAX_SSID
)
2494 sr
->sr_nssid
= IEEE80211_SCAN_MAX_SSID
;
2495 for (i
= 0; i
< sr
->sr_nssid
; i
++)
2496 if (sr
->sr_ssid
[i
].len
> IEEE80211_NWID_LEN
)
2498 /* cleanse flags just in case, could reject if invalid flags */
2499 sr
->sr_flags
&= IEEE80211_IOC_SCAN_FLAGS
;
2501 * Add an implicit NOPICK if the vap is not marked UP. This
2502 * allows applications to scan without joining a bss (or picking
2503 * a channel and setting up a bss) and without forcing manual
2504 * roaming mode--you just need to mark the parent device UP.
2506 if ((vap
->iv_ifp
->if_flags
& IFF_UP
) == 0)
2507 sr
->sr_flags
|= IEEE80211_IOC_SCAN_NOPICK
;
2509 IEEE80211_DPRINTF(vap
, IEEE80211_MSG_SCAN
,
2510 "%s: flags 0x%x%s duration 0x%x mindwell %u maxdwell %u nssid %d\n",
2511 __func__
, sr
->sr_flags
,
2512 (vap
->iv_ifp
->if_flags
& IFF_UP
) == 0 ? " (!IFF_UP)" : "",
2513 sr
->sr_duration
, sr
->sr_mindwell
, sr
->sr_maxdwell
, sr
->sr_nssid
);
2515 * If we are in INIT state then the driver has never had a chance
2516 * to setup hardware state to do a scan; we must use the state
2517 * machine to get us up to the SCAN state but once we reach SCAN
2518 * state we then want to use the supplied params. Stash the
2519 * parameters in the vap and mark IEEE80211_FEXT_SCANREQ; the
2520 * state machines will recognize this and use the stashed params
2521 * to issue the scan request.
2523 * Otherwise just invoke the scan machinery directly.
2526 if (ic
->ic_nrunning
== 0) {
2527 IEEE80211_UNLOCK(ic
);
2531 if (vap
->iv_state
== IEEE80211_S_INIT
) {
2532 /* NB: clobbers previous settings */
2533 vap
->iv_scanreq_flags
= sr
->sr_flags
;
2534 vap
->iv_scanreq_duration
= sr
->sr_duration
;
2535 vap
->iv_scanreq_nssid
= sr
->sr_nssid
;
2536 for (i
= 0; i
< sr
->sr_nssid
; i
++) {
2537 vap
->iv_scanreq_ssid
[i
].len
= sr
->sr_ssid
[i
].len
;
2538 memcpy(vap
->iv_scanreq_ssid
[i
].ssid
,
2539 sr
->sr_ssid
[i
].ssid
, sr
->sr_ssid
[i
].len
);
2541 vap
->iv_flags_ext
|= IEEE80211_FEXT_SCANREQ
;
2542 IEEE80211_UNLOCK(ic
);
2543 ieee80211_new_state(vap
, IEEE80211_S_SCAN
, 0);
2545 vap
->iv_flags_ext
&= ~IEEE80211_FEXT_SCANREQ
;
2546 IEEE80211_UNLOCK(ic
);
2547 if (sr
->sr_flags
& IEEE80211_IOC_SCAN_CHECK
) {
2548 error
= ieee80211_check_scan(vap
, sr
->sr_flags
,
2549 sr
->sr_duration
, sr
->sr_mindwell
, sr
->sr_maxdwell
,
2551 /* NB: cheat, we assume structures are compatible */
2552 (const struct ieee80211_scan_ssid
*) &sr
->sr_ssid
[0]);
2554 error
= ieee80211_start_scan(vap
, sr
->sr_flags
,
2555 sr
->sr_duration
, sr
->sr_mindwell
, sr
->sr_maxdwell
,
2557 /* NB: cheat, we assume structures are compatible */
2558 (const struct ieee80211_scan_ssid
*) &sr
->sr_ssid
[0]);
2564 #undef IEEE80211_IOC_SCAN_FLAGS
2568 ieee80211_ioctl_scanreq(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
2570 struct ieee80211_scan_req
*sr
;
2573 if (ireq
->i_len
!= sizeof(*sr
))
2575 #if defined(__DragonFly__)
2576 sr
= kmalloc(sizeof(*sr
), M_TEMP
, M_INTWAIT
| M_ZERO
);
2578 sr
= IEEE80211_MALLOC(sizeof(*sr
), M_TEMP
,
2579 IEEE80211_M_NOWAIT
| IEEE80211_M_ZERO
);
2583 error
= copyin(ireq
->i_data
, sr
, sizeof(*sr
));
2586 error
= ieee80211_scanreq(vap
, sr
);
2588 IEEE80211_FREE(sr
, M_TEMP
);
2593 ieee80211_ioctl_setstavlan(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
2595 struct ieee80211_node
*ni
;
2596 struct ieee80211req_sta_vlan vlan
;
2599 if (ireq
->i_len
!= sizeof(vlan
))
2601 error
= copyin(ireq
->i_data
, &vlan
, sizeof(vlan
));
2604 if (!IEEE80211_ADDR_EQ(vlan
.sv_macaddr
, zerobssid
)) {
2605 ni
= ieee80211_find_vap_node(&vap
->iv_ic
->ic_sta
, vap
,
2610 ni
= ieee80211_ref_node(vap
->iv_bss
);
2611 ni
->ni_vlan
= vlan
.sv_vlan
;
2612 ieee80211_free_node(ni
);
2617 isvap11g(const struct ieee80211vap
*vap
)
2619 const struct ieee80211_node
*bss
= vap
->iv_bss
;
2620 return bss
->ni_chan
!= IEEE80211_CHAN_ANYC
&&
2621 IEEE80211_IS_CHAN_ANYG(bss
->ni_chan
);
2625 isvapht(const struct ieee80211vap
*vap
)
2627 const struct ieee80211_node
*bss
= vap
->iv_bss
;
2628 return bss
->ni_chan
!= IEEE80211_CHAN_ANYC
&&
2629 IEEE80211_IS_CHAN_HT(bss
->ni_chan
);
2633 * Dummy ioctl set handler so the linker set is defined.
2636 dummy_ioctl_set(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
2640 IEEE80211_IOCTL_SET(dummy
, dummy_ioctl_set
);
2643 ieee80211_ioctl_setdefault(struct ieee80211vap
*vap
, struct ieee80211req
*ireq
)
2645 ieee80211_ioctl_setfunc
* const *set
;
2648 SET_FOREACH(set
, ieee80211_ioctl_setset
) {
2649 error
= (*set
)(vap
, ireq
);
2650 if (error
!= ENOSYS
)
2657 ieee80211_ioctl_set80211(struct ieee80211vap
*vap
, u_long cmd
, struct ieee80211req
*ireq
)
2659 struct ieee80211com
*ic
= vap
->iv_ic
;
2661 const struct ieee80211_authenticator
*auth
;
2662 uint8_t tmpkey
[IEEE80211_KEYBUF_SIZE
];
2663 char tmpssid
[IEEE80211_NWID_LEN
];
2664 uint8_t tmpbssid
[IEEE80211_ADDR_LEN
];
2665 struct ieee80211_key
*k
;
2670 switch (ireq
->i_type
) {
2671 case IEEE80211_IOC_SSID
:
2672 if (ireq
->i_val
!= 0 ||
2673 ireq
->i_len
> IEEE80211_NWID_LEN
)
2675 error
= copyin(ireq
->i_data
, tmpssid
, ireq
->i_len
);
2678 memset(vap
->iv_des_ssid
[0].ssid
, 0, IEEE80211_NWID_LEN
);
2679 vap
->iv_des_ssid
[0].len
= ireq
->i_len
;
2680 memcpy(vap
->iv_des_ssid
[0].ssid
, tmpssid
, ireq
->i_len
);
2681 vap
->iv_des_nssid
= (ireq
->i_len
> 0);
2684 case IEEE80211_IOC_WEP
:
2685 switch (ireq
->i_val
) {
2686 case IEEE80211_WEP_OFF
:
2687 vap
->iv_flags
&= ~IEEE80211_F_PRIVACY
;
2688 vap
->iv_flags
&= ~IEEE80211_F_DROPUNENC
;
2690 case IEEE80211_WEP_ON
:
2691 vap
->iv_flags
|= IEEE80211_F_PRIVACY
;
2692 vap
->iv_flags
|= IEEE80211_F_DROPUNENC
;
2694 case IEEE80211_WEP_MIXED
:
2695 vap
->iv_flags
|= IEEE80211_F_PRIVACY
;
2696 vap
->iv_flags
&= ~IEEE80211_F_DROPUNENC
;
2701 case IEEE80211_IOC_WEPKEY
:
2702 kid
= (u_int
) ireq
->i_val
;
2703 if (kid
>= IEEE80211_WEP_NKID
)
2705 k
= &vap
->iv_nw_keys
[kid
];
2706 if (ireq
->i_len
== 0) {
2707 /* zero-len =>'s delete any existing key */
2708 (void) ieee80211_crypto_delkey(vap
, k
);
2711 if (ireq
->i_len
> sizeof(tmpkey
))
2713 memset(tmpkey
, 0, sizeof(tmpkey
));
2714 error
= copyin(ireq
->i_data
, tmpkey
, ireq
->i_len
);
2717 ieee80211_key_update_begin(vap
);
2718 k
->wk_keyix
= kid
; /* NB: force fixed key id */
2719 if (ieee80211_crypto_newkey(vap
, IEEE80211_CIPHER_WEP
,
2720 IEEE80211_KEY_XMIT
| IEEE80211_KEY_RECV
, k
)) {
2721 k
->wk_keylen
= ireq
->i_len
;
2722 memcpy(k
->wk_key
, tmpkey
, sizeof(tmpkey
));
2723 IEEE80211_ADDR_COPY(k
->wk_macaddr
, vap
->iv_myaddr
);
2724 if (!ieee80211_crypto_setkey(vap
, k
))
2728 ieee80211_key_update_end(vap
);
2730 case IEEE80211_IOC_WEPTXKEY
:
2731 kid
= (u_int
) ireq
->i_val
;
2732 if (kid
>= IEEE80211_WEP_NKID
&&
2733 (uint16_t) kid
!= IEEE80211_KEYIX_NONE
)
2735 vap
->iv_def_txkey
= kid
;
2737 case IEEE80211_IOC_AUTHMODE
:
2738 switch (ireq
->i_val
) {
2739 case IEEE80211_AUTH_WPA
:
2740 case IEEE80211_AUTH_8021X
: /* 802.1x */
2741 case IEEE80211_AUTH_OPEN
: /* open */
2742 case IEEE80211_AUTH_SHARED
: /* shared-key */
2743 case IEEE80211_AUTH_AUTO
: /* auto */
2744 auth
= ieee80211_authenticator_get(ireq
->i_val
);
2751 switch (ireq
->i_val
) {
2752 case IEEE80211_AUTH_WPA
: /* WPA w/ 802.1x */
2753 vap
->iv_flags
|= IEEE80211_F_PRIVACY
;
2754 ireq
->i_val
= IEEE80211_AUTH_8021X
;
2756 case IEEE80211_AUTH_OPEN
: /* open */
2757 vap
->iv_flags
&= ~(IEEE80211_F_WPA
|IEEE80211_F_PRIVACY
);
2759 case IEEE80211_AUTH_SHARED
: /* shared-key */
2760 case IEEE80211_AUTH_8021X
: /* 802.1x */
2761 vap
->iv_flags
&= ~IEEE80211_F_WPA
;
2762 /* both require a key so mark the PRIVACY capability */
2763 vap
->iv_flags
|= IEEE80211_F_PRIVACY
;
2765 case IEEE80211_AUTH_AUTO
: /* auto */
2766 vap
->iv_flags
&= ~IEEE80211_F_WPA
;
2767 /* XXX PRIVACY handling? */
2768 /* XXX what's the right way to do this? */
2771 /* NB: authenticator attach/detach happens on state change */
2772 vap
->iv_bss
->ni_authmode
= ireq
->i_val
;
2773 /* XXX mixed/mode/usage? */
2774 vap
->iv_auth
= auth
;
2777 case IEEE80211_IOC_CHANNEL
:
2778 error
= ieee80211_ioctl_setchannel(vap
, ireq
);
2780 case IEEE80211_IOC_POWERSAVE
:
2781 switch (ireq
->i_val
) {
2782 case IEEE80211_POWERSAVE_OFF
:
2783 if (vap
->iv_flags
& IEEE80211_F_PMGTON
) {
2784 ieee80211_syncflag(vap
, -IEEE80211_F_PMGTON
);
2788 case IEEE80211_POWERSAVE_ON
:
2789 if ((vap
->iv_caps
& IEEE80211_C_PMGT
) == 0)
2791 else if ((vap
->iv_flags
& IEEE80211_F_PMGTON
) == 0) {
2792 ieee80211_syncflag(vap
, IEEE80211_F_PMGTON
);
2801 case IEEE80211_IOC_POWERSAVESLEEP
:
2802 if (ireq
->i_val
< 0)
2804 ic
->ic_lintval
= ireq
->i_val
;
2807 case IEEE80211_IOC_RTSTHRESHOLD
:
2808 if (!(IEEE80211_RTS_MIN
<= ireq
->i_val
&&
2809 ireq
->i_val
<= IEEE80211_RTS_MAX
))
2811 vap
->iv_rtsthreshold
= ireq
->i_val
;
2814 case IEEE80211_IOC_PROTMODE
:
2815 if (ireq
->i_val
> IEEE80211_PROT_RTSCTS
)
2817 ic
->ic_protmode
= (enum ieee80211_protmode
)ireq
->i_val
;
2818 /* NB: if not operating in 11g this can wait */
2819 if (ic
->ic_bsschan
!= IEEE80211_CHAN_ANYC
&&
2820 IEEE80211_IS_CHAN_ANYG(ic
->ic_bsschan
))
2823 case IEEE80211_IOC_TXPOWER
:
2824 if ((ic
->ic_caps
& IEEE80211_C_TXPMGT
) == 0)
2826 if (!(IEEE80211_TXPOWER_MIN
<= ireq
->i_val
&&
2827 ireq
->i_val
<= IEEE80211_TXPOWER_MAX
))
2829 ic
->ic_txpowlimit
= ireq
->i_val
;
2832 case IEEE80211_IOC_ROAMING
:
2833 if (!(IEEE80211_ROAMING_DEVICE
<= ireq
->i_val
&&
2834 ireq
->i_val
<= IEEE80211_ROAMING_MANUAL
))
2836 vap
->iv_roaming
= (enum ieee80211_roamingmode
)ireq
->i_val
;
2839 case IEEE80211_IOC_PRIVACY
:
2841 /* XXX check for key state? */
2842 vap
->iv_flags
|= IEEE80211_F_PRIVACY
;
2844 vap
->iv_flags
&= ~IEEE80211_F_PRIVACY
;
2847 case IEEE80211_IOC_DROPUNENCRYPTED
:
2849 vap
->iv_flags
|= IEEE80211_F_DROPUNENC
;
2851 vap
->iv_flags
&= ~IEEE80211_F_DROPUNENC
;
2854 case IEEE80211_IOC_WPAKEY
:
2855 error
= ieee80211_ioctl_setkey(vap
, ireq
);
2857 case IEEE80211_IOC_DELKEY
:
2858 error
= ieee80211_ioctl_delkey(vap
, ireq
);
2860 case IEEE80211_IOC_MLME
:
2861 error
= ieee80211_ioctl_setmlme(vap
, ireq
);
2863 case IEEE80211_IOC_COUNTERMEASURES
:
2865 if ((vap
->iv_flags
& IEEE80211_F_WPA
) == 0)
2867 vap
->iv_flags
|= IEEE80211_F_COUNTERM
;
2869 vap
->iv_flags
&= ~IEEE80211_F_COUNTERM
;
2872 case IEEE80211_IOC_WPA
:
2873 if (ireq
->i_val
> 3)
2875 /* XXX verify ciphers available */
2876 flags
= vap
->iv_flags
& ~IEEE80211_F_WPA
;
2877 switch (ireq
->i_val
) {
2879 /* wpa_supplicant calls this to clear the WPA config */
2882 if (!(vap
->iv_caps
& IEEE80211_C_WPA1
))
2884 flags
|= IEEE80211_F_WPA1
;
2887 if (!(vap
->iv_caps
& IEEE80211_C_WPA2
))
2889 flags
|= IEEE80211_F_WPA2
;
2892 if ((vap
->iv_caps
& IEEE80211_C_WPA
) != IEEE80211_C_WPA
)
2894 flags
|= IEEE80211_F_WPA1
| IEEE80211_F_WPA2
;
2896 default: /* Can't set any -> error */
2899 vap
->iv_flags
= flags
;
2900 error
= ERESTART
; /* NB: can change beacon frame */
2902 case IEEE80211_IOC_WME
:
2904 if ((vap
->iv_caps
& IEEE80211_C_WME
) == 0)
2906 ieee80211_syncflag(vap
, IEEE80211_F_WME
);
2908 ieee80211_syncflag(vap
, -IEEE80211_F_WME
);
2909 error
= ERESTART
; /* NB: can change beacon frame */
2911 case IEEE80211_IOC_HIDESSID
:
2913 vap
->iv_flags
|= IEEE80211_F_HIDESSID
;
2915 vap
->iv_flags
&= ~IEEE80211_F_HIDESSID
;
2916 error
= ERESTART
; /* XXX ENETRESET? */
2918 case IEEE80211_IOC_APBRIDGE
:
2919 if (ireq
->i_val
== 0)
2920 vap
->iv_flags
|= IEEE80211_F_NOBRIDGE
;
2922 vap
->iv_flags
&= ~IEEE80211_F_NOBRIDGE
;
2924 case IEEE80211_IOC_BSSID
:
2925 if (ireq
->i_len
!= sizeof(tmpbssid
))
2927 error
= copyin(ireq
->i_data
, tmpbssid
, ireq
->i_len
);
2930 IEEE80211_ADDR_COPY(vap
->iv_des_bssid
, tmpbssid
);
2931 if (IEEE80211_ADDR_EQ(vap
->iv_des_bssid
, zerobssid
))
2932 vap
->iv_flags
&= ~IEEE80211_F_DESBSSID
;
2934 vap
->iv_flags
|= IEEE80211_F_DESBSSID
;
2937 case IEEE80211_IOC_CHANLIST
:
2938 error
= ieee80211_ioctl_setchanlist(vap
, ireq
);
2940 #define OLD_IEEE80211_IOC_SCAN_REQ 23
2941 #ifdef OLD_IEEE80211_IOC_SCAN_REQ
2942 case OLD_IEEE80211_IOC_SCAN_REQ
:
2943 IEEE80211_DPRINTF(vap
, IEEE80211_MSG_SCAN
,
2944 "%s: active scan request\n", __func__
);
2946 * If we are in INIT state then the driver has never
2947 * had a chance to setup hardware state to do a scan;
2948 * use the state machine to get us up the SCAN state.
2949 * Otherwise just invoke the scan machinery to start
2952 if (vap
->iv_state
== IEEE80211_S_INIT
)
2953 ieee80211_new_state(vap
, IEEE80211_S_SCAN
, 0);
2955 (void) ieee80211_start_scan(vap
,
2956 IEEE80211_SCAN_ACTIVE
|
2957 IEEE80211_SCAN_NOPICK
|
2958 IEEE80211_SCAN_ONCE
,
2959 IEEE80211_SCAN_FOREVER
, 0, 0,
2960 /* XXX use ioctl params */
2961 vap
->iv_des_nssid
, vap
->iv_des_ssid
);
2963 #endif /* OLD_IEEE80211_IOC_SCAN_REQ */
2964 case IEEE80211_IOC_SCAN_REQ
:
2965 error
= ieee80211_ioctl_scanreq(vap
, ireq
);
2967 case IEEE80211_IOC_SCAN_CANCEL
:
2968 IEEE80211_DPRINTF(vap
, IEEE80211_MSG_SCAN
,
2969 "%s: cancel scan\n", __func__
);
2970 ieee80211_cancel_scan(vap
);
2972 case IEEE80211_IOC_HTCONF
:
2973 if (ireq
->i_val
& 1)
2974 ieee80211_syncflag_ht(vap
, IEEE80211_FHT_HT
);
2976 ieee80211_syncflag_ht(vap
, -IEEE80211_FHT_HT
);
2977 if (ireq
->i_val
& 2)
2978 ieee80211_syncflag_ht(vap
, IEEE80211_FHT_USEHT40
);
2980 ieee80211_syncflag_ht(vap
, -IEEE80211_FHT_USEHT40
);
2983 case IEEE80211_IOC_ADDMAC
:
2984 case IEEE80211_IOC_DELMAC
:
2985 error
= ieee80211_ioctl_macmac(vap
, ireq
);
2987 case IEEE80211_IOC_MACCMD
:
2988 error
= ieee80211_ioctl_setmaccmd(vap
, ireq
);
2990 case IEEE80211_IOC_STA_STATS
:
2991 error
= ieee80211_ioctl_setstastats(vap
, ireq
);
2993 case IEEE80211_IOC_STA_TXPOW
:
2994 error
= ieee80211_ioctl_setstatxpow(vap
, ireq
);
2996 case IEEE80211_IOC_WME_CWMIN
: /* WME: CWmin */
2997 case IEEE80211_IOC_WME_CWMAX
: /* WME: CWmax */
2998 case IEEE80211_IOC_WME_AIFS
: /* WME: AIFS */
2999 case IEEE80211_IOC_WME_TXOPLIMIT
: /* WME: txops limit */
3000 case IEEE80211_IOC_WME_ACM
: /* WME: ACM (bss only) */
3001 case IEEE80211_IOC_WME_ACKPOLICY
: /* WME: ACK policy (!bss only) */
3002 error
= ieee80211_ioctl_setwmeparam(vap
, ireq
);
3004 case IEEE80211_IOC_DTIM_PERIOD
:
3005 if (vap
->iv_opmode
!= IEEE80211_M_HOSTAP
&&
3006 vap
->iv_opmode
!= IEEE80211_M_MBSS
&&
3007 vap
->iv_opmode
!= IEEE80211_M_IBSS
)
3009 if (IEEE80211_DTIM_MIN
<= ireq
->i_val
&&
3010 ireq
->i_val
<= IEEE80211_DTIM_MAX
) {
3011 vap
->iv_dtim_period
= ireq
->i_val
;
3012 error
= ENETRESET
; /* requires restart */
3016 case IEEE80211_IOC_BEACON_INTERVAL
:
3017 if (vap
->iv_opmode
!= IEEE80211_M_HOSTAP
&&
3018 vap
->iv_opmode
!= IEEE80211_M_MBSS
&&
3019 vap
->iv_opmode
!= IEEE80211_M_IBSS
)
3021 if (IEEE80211_BINTVAL_MIN
<= ireq
->i_val
&&
3022 ireq
->i_val
<= IEEE80211_BINTVAL_MAX
) {
3023 ic
->ic_bintval
= ireq
->i_val
;
3024 error
= ENETRESET
; /* requires restart */
3028 case IEEE80211_IOC_PUREG
:
3030 vap
->iv_flags
|= IEEE80211_F_PUREG
;
3032 vap
->iv_flags
&= ~IEEE80211_F_PUREG
;
3033 /* NB: reset only if we're operating on an 11g channel */
3037 case IEEE80211_IOC_QUIET
:
3038 vap
->iv_quiet
= ireq
->i_val
;
3040 case IEEE80211_IOC_QUIET_COUNT
:
3041 vap
->iv_quiet_count
=ireq
->i_val
;
3043 case IEEE80211_IOC_QUIET_PERIOD
:
3044 vap
->iv_quiet_period
=ireq
->i_val
;
3046 case IEEE80211_IOC_QUIET_OFFSET
:
3047 vap
->iv_quiet_offset
=ireq
->i_val
;
3049 case IEEE80211_IOC_QUIET_DUR
:
3050 if(ireq
->i_val
< vap
->iv_bss
->ni_intval
)
3051 vap
->iv_quiet_duration
= ireq
->i_val
;
3055 case IEEE80211_IOC_BGSCAN
:
3057 if ((vap
->iv_caps
& IEEE80211_C_BGSCAN
) == 0)
3059 vap
->iv_flags
|= IEEE80211_F_BGSCAN
;
3061 vap
->iv_flags
&= ~IEEE80211_F_BGSCAN
;
3063 case IEEE80211_IOC_BGSCAN_IDLE
:
3064 if (ireq
->i_val
>= IEEE80211_BGSCAN_IDLE_MIN
)
3065 vap
->iv_bgscanidle
= ireq
->i_val
*hz
/1000;
3069 case IEEE80211_IOC_BGSCAN_INTERVAL
:
3070 if (ireq
->i_val
>= IEEE80211_BGSCAN_INTVAL_MIN
)
3071 vap
->iv_bgscanintvl
= ireq
->i_val
*hz
;
3075 case IEEE80211_IOC_SCANVALID
:
3076 if (ireq
->i_val
>= IEEE80211_SCAN_VALID_MIN
)
3077 vap
->iv_scanvalid
= ireq
->i_val
*hz
;
3081 case IEEE80211_IOC_FRAGTHRESHOLD
:
3082 if ((vap
->iv_caps
& IEEE80211_C_TXFRAG
) == 0 &&
3083 ireq
->i_val
!= IEEE80211_FRAG_MAX
)
3085 if (!(IEEE80211_FRAG_MIN
<= ireq
->i_val
&&
3086 ireq
->i_val
<= IEEE80211_FRAG_MAX
))
3088 vap
->iv_fragthreshold
= ireq
->i_val
;
3091 case IEEE80211_IOC_BURST
:
3093 if ((vap
->iv_caps
& IEEE80211_C_BURST
) == 0)
3095 ieee80211_syncflag(vap
, IEEE80211_F_BURST
);
3097 ieee80211_syncflag(vap
, -IEEE80211_F_BURST
);
3100 case IEEE80211_IOC_BMISSTHRESHOLD
:
3101 if (!(IEEE80211_HWBMISS_MIN
<= ireq
->i_val
&&
3102 ireq
->i_val
<= IEEE80211_HWBMISS_MAX
))
3104 vap
->iv_bmissthreshold
= ireq
->i_val
;
3107 case IEEE80211_IOC_CURCHAN
:
3108 error
= ieee80211_ioctl_setcurchan(vap
, ireq
);
3110 case IEEE80211_IOC_SHORTGI
:
3112 #define IEEE80211_HTCAP_SHORTGI \
3113 (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40)
3114 if (((ireq
->i_val
^ vap
->iv_htcaps
) & IEEE80211_HTCAP_SHORTGI
) != 0)
3116 if (ireq
->i_val
& IEEE80211_HTCAP_SHORTGI20
)
3117 vap
->iv_flags_ht
|= IEEE80211_FHT_SHORTGI20
;
3118 if (ireq
->i_val
& IEEE80211_HTCAP_SHORTGI40
)
3119 vap
->iv_flags_ht
|= IEEE80211_FHT_SHORTGI40
;
3120 #undef IEEE80211_HTCAP_SHORTGI
3123 ~(IEEE80211_FHT_SHORTGI20
| IEEE80211_FHT_SHORTGI40
);
3126 case IEEE80211_IOC_AMPDU
:
3127 if (ireq
->i_val
&& (vap
->iv_htcaps
& IEEE80211_HTC_AMPDU
) == 0)
3129 if (ireq
->i_val
& 1)
3130 vap
->iv_flags_ht
|= IEEE80211_FHT_AMPDU_TX
;
3132 vap
->iv_flags_ht
&= ~IEEE80211_FHT_AMPDU_TX
;
3133 if (ireq
->i_val
& 2)
3134 vap
->iv_flags_ht
|= IEEE80211_FHT_AMPDU_RX
;
3136 vap
->iv_flags_ht
&= ~IEEE80211_FHT_AMPDU_RX
;
3137 /* NB: reset only if we're operating on an 11n channel */
3141 case IEEE80211_IOC_AMPDU_LIMIT
:
3142 if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K
<= ireq
->i_val
&&
3143 ireq
->i_val
<= IEEE80211_HTCAP_MAXRXAMPDU_64K
))
3145 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
)
3146 vap
->iv_ampdu_rxmax
= ireq
->i_val
;
3148 vap
->iv_ampdu_limit
= ireq
->i_val
;
3151 case IEEE80211_IOC_AMPDU_DENSITY
:
3152 if (!(IEEE80211_HTCAP_MPDUDENSITY_NA
<= ireq
->i_val
&&
3153 ireq
->i_val
<= IEEE80211_HTCAP_MPDUDENSITY_16
))
3155 vap
->iv_ampdu_density
= ireq
->i_val
;
3158 case IEEE80211_IOC_AMSDU
:
3159 if (ireq
->i_val
&& (vap
->iv_htcaps
& IEEE80211_HTC_AMSDU
) == 0)
3161 if (ireq
->i_val
& 1)
3162 vap
->iv_flags_ht
|= IEEE80211_FHT_AMSDU_TX
;
3164 vap
->iv_flags_ht
&= ~IEEE80211_FHT_AMSDU_TX
;
3165 if (ireq
->i_val
& 2)
3166 vap
->iv_flags_ht
|= IEEE80211_FHT_AMSDU_RX
;
3168 vap
->iv_flags_ht
&= ~IEEE80211_FHT_AMSDU_RX
;
3169 /* NB: reset only if we're operating on an 11n channel */
3173 case IEEE80211_IOC_AMSDU_LIMIT
:
3175 vap
->iv_amsdu_limit
= ireq
->i_val
; /* XXX truncation? */
3177 case IEEE80211_IOC_PUREN
:
3179 if ((vap
->iv_flags_ht
& IEEE80211_FHT_HT
) == 0)
3181 vap
->iv_flags_ht
|= IEEE80211_FHT_PUREN
;
3183 vap
->iv_flags_ht
&= ~IEEE80211_FHT_PUREN
;
3184 /* NB: reset only if we're operating on an 11n channel */
3188 case IEEE80211_IOC_DOTH
:
3191 /* XXX no capability */
3192 if ((vap
->iv_caps
& IEEE80211_C_DOTH
) == 0)
3195 vap
->iv_flags
|= IEEE80211_F_DOTH
;
3197 vap
->iv_flags
&= ~IEEE80211_F_DOTH
;
3200 case IEEE80211_IOC_REGDOMAIN
:
3201 error
= ieee80211_ioctl_setregdomain(vap
, ireq
);
3203 case IEEE80211_IOC_ROAM
:
3204 error
= ieee80211_ioctl_setroam(vap
, ireq
);
3206 case IEEE80211_IOC_TXPARAMS
:
3207 error
= ieee80211_ioctl_settxparams(vap
, ireq
);
3209 case IEEE80211_IOC_HTCOMPAT
:
3211 if ((vap
->iv_flags_ht
& IEEE80211_FHT_HT
) == 0)
3213 vap
->iv_flags_ht
|= IEEE80211_FHT_HTCOMPAT
;
3215 vap
->iv_flags_ht
&= ~IEEE80211_FHT_HTCOMPAT
;
3216 /* NB: reset only if we're operating on an 11n channel */
3220 case IEEE80211_IOC_DWDS
:
3222 /* NB: DWDS only makes sense for WDS-capable devices */
3223 if ((ic
->ic_caps
& IEEE80211_C_WDS
) == 0)
3225 /* NB: DWDS is used only with ap+sta vaps */
3226 if (vap
->iv_opmode
!= IEEE80211_M_HOSTAP
&&
3227 vap
->iv_opmode
!= IEEE80211_M_STA
)
3229 vap
->iv_flags
|= IEEE80211_F_DWDS
;
3230 if (vap
->iv_opmode
== IEEE80211_M_STA
)
3231 vap
->iv_flags_ext
|= IEEE80211_FEXT_4ADDR
;
3233 vap
->iv_flags
&= ~IEEE80211_F_DWDS
;
3234 if (vap
->iv_opmode
== IEEE80211_M_STA
)
3235 vap
->iv_flags_ext
&= ~IEEE80211_FEXT_4ADDR
;
3238 case IEEE80211_IOC_INACTIVITY
:
3240 vap
->iv_flags_ext
|= IEEE80211_FEXT_INACT
;
3242 vap
->iv_flags_ext
&= ~IEEE80211_FEXT_INACT
;
3244 case IEEE80211_IOC_APPIE
:
3245 error
= ieee80211_ioctl_setappie(vap
, ireq
);
3247 case IEEE80211_IOC_WPS
:
3249 if ((vap
->iv_caps
& IEEE80211_C_WPA
) == 0)
3251 vap
->iv_flags_ext
|= IEEE80211_FEXT_WPS
;
3253 vap
->iv_flags_ext
&= ~IEEE80211_FEXT_WPS
;
3255 case IEEE80211_IOC_TSN
:
3257 if ((vap
->iv_caps
& IEEE80211_C_WPA
) == 0)
3259 vap
->iv_flags_ext
|= IEEE80211_FEXT_TSN
;
3261 vap
->iv_flags_ext
&= ~IEEE80211_FEXT_TSN
;
3263 case IEEE80211_IOC_CHANSWITCH
:
3264 error
= ieee80211_ioctl_chanswitch(vap
, ireq
);
3266 case IEEE80211_IOC_DFS
:
3268 if ((vap
->iv_caps
& IEEE80211_C_DFS
) == 0)
3270 /* NB: DFS requires 11h support */
3271 if ((vap
->iv_flags
& IEEE80211_F_DOTH
) == 0)
3273 vap
->iv_flags_ext
|= IEEE80211_FEXT_DFS
;
3275 vap
->iv_flags_ext
&= ~IEEE80211_FEXT_DFS
;
3277 case IEEE80211_IOC_DOTD
:
3279 vap
->iv_flags_ext
|= IEEE80211_FEXT_DOTD
;
3281 vap
->iv_flags_ext
&= ~IEEE80211_FEXT_DOTD
;
3282 if (vap
->iv_opmode
== IEEE80211_M_STA
)
3285 case IEEE80211_IOC_HTPROTMODE
:
3286 if (ireq
->i_val
> IEEE80211_PROT_RTSCTS
)
3288 ic
->ic_htprotmode
= ireq
->i_val
?
3289 IEEE80211_PROT_RTSCTS
: IEEE80211_PROT_NONE
;
3290 /* NB: if not operating in 11n this can wait */
3294 case IEEE80211_IOC_STA_VLAN
:
3295 error
= ieee80211_ioctl_setstavlan(vap
, ireq
);
3297 case IEEE80211_IOC_SMPS
:
3298 if ((ireq
->i_val
&~ IEEE80211_HTCAP_SMPS
) != 0 ||
3299 ireq
->i_val
== 0x0008) /* value of 2 is reserved */
3301 if (ireq
->i_val
!= IEEE80211_HTCAP_SMPS_OFF
&&
3302 (vap
->iv_htcaps
& IEEE80211_HTC_SMPS
) == 0)
3304 vap
->iv_htcaps
= (vap
->iv_htcaps
&~ IEEE80211_HTCAP_SMPS
) |
3306 /* NB: if not operating in 11n this can wait */
3310 case IEEE80211_IOC_RIFS
:
3311 if (ireq
->i_val
!= 0) {
3312 if ((vap
->iv_htcaps
& IEEE80211_HTC_RIFS
) == 0)
3314 vap
->iv_flags_ht
|= IEEE80211_FHT_RIFS
;
3316 vap
->iv_flags_ht
&= ~IEEE80211_FHT_RIFS
;
3317 /* NB: if not operating in 11n this can wait */
3321 case IEEE80211_IOC_STBC
:
3322 /* Check if we can do STBC TX/RX before changing the setting */
3323 if ((ireq
->i_val
& 1) &&
3324 ((vap
->iv_htcaps
& IEEE80211_HTCAP_TXSTBC
) == 0))
3326 if ((ireq
->i_val
& 2) &&
3327 ((vap
->iv_htcaps
& IEEE80211_HTCAP_RXSTBC
) == 0))
3331 if (ireq
->i_val
& 1)
3332 vap
->iv_flags_ht
|= IEEE80211_FHT_STBC_TX
;
3334 vap
->iv_flags_ht
&= ~IEEE80211_FHT_STBC_TX
;
3337 if (ireq
->i_val
& 2)
3338 vap
->iv_flags_ht
|= IEEE80211_FHT_STBC_RX
;
3340 vap
->iv_flags_ht
&= ~IEEE80211_FHT_STBC_RX
;
3342 /* NB: reset only if we're operating on an 11n channel */
3347 error
= ieee80211_ioctl_setdefault(vap
, ireq
);
3351 * The convention is that ENETRESET means an operation
3352 * requires a complete re-initialization of the device (e.g.
3353 * changing something that affects the association state).
3354 * ERESTART means the request may be handled with only a
3355 * reload of the hardware state. We hand ERESTART requests
3356 * to the iv_reset callback so the driver can decide. If
3357 * a device does not fillin iv_reset then it defaults to one
3358 * that returns ENETRESET. Otherwise a driver may return
3359 * ENETRESET (in which case a full reset will be done) or
3360 * 0 to mean there's no need to do anything (e.g. when the
3361 * change has no effect on the driver/device).
3363 if (error
== ERESTART
)
3364 error
= IFNET_IS_UP_RUNNING(vap
->iv_ifp
) ?
3365 vap
->iv_reset(vap
, ireq
->i_type
) : 0;
3366 if (error
== ENETRESET
) {
3367 /* XXX need to re-think AUTO handling */
3368 if (IS_UP_AUTO(vap
))
3369 ieee80211_init(vap
);
3375 #if defined(__DragonFly__)
3377 ieee80211_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
, struct ucred
*ucred
)
3380 ieee80211_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
)
3383 struct ieee80211vap
*vap
= ifp
->if_softc
;
3384 struct ieee80211com
*ic
= vap
->iv_ic
;
3385 int error
= 0, wait
= 0;
3387 struct ifaddr
*ifa
; /* XXX */
3392 if ((ifp
->if_flags
^ vap
->iv_ifflags
) & IFF_PROMISC
) {
3394 * Enable promiscuous mode when:
3395 * 1. Interface is not a member of bridge, or
3396 * 2. Requested by user, or
3397 * 3. In monitor (or adhoc-demo) mode.
3399 if (ifp
->if_bridge
== NULL
||
3400 (ifp
->if_flags
& IFF_PPROMISC
) != 0 ||
3401 vap
->iv_opmode
== IEEE80211_M_MONITOR
||
3402 (vap
->iv_opmode
== IEEE80211_M_AHDEMO
&&
3403 (vap
->iv_caps
& IEEE80211_C_TDMA
) == 0)) {
3404 ieee80211_promisc(vap
,
3405 ifp
->if_flags
& IFF_PROMISC
);
3406 vap
->iv_ifflags
^= IFF_PROMISC
;
3409 if ((ifp
->if_flags
^ vap
->iv_ifflags
) & IFF_ALLMULTI
) {
3410 ieee80211_allmulti(vap
, ifp
->if_flags
& IFF_ALLMULTI
);
3411 vap
->iv_ifflags
^= IFF_ALLMULTI
;
3413 if (ifp
->if_flags
& IFF_UP
) {
3415 * Bring ourself up unless we're already operational.
3416 * If we're the first vap and the parent is not up
3417 * then it will automatically be brought up as a
3418 * side-effect of bringing ourself up.
3420 if (vap
->iv_state
== IEEE80211_S_INIT
) {
3421 if (ic
->ic_nrunning
== 0)
3423 ieee80211_start_locked(vap
);
3425 } else if (ifp
->if_drv_flags
& IFF_DRV_RUNNING
) {
3427 * Stop ourself. If we are the last vap to be
3428 * marked down the parent will also be taken down.
3430 if (ic
->ic_nrunning
== 1)
3432 ieee80211_stop_locked(vap
);
3434 IEEE80211_UNLOCK(ic
);
3435 /* Wait for parent ioctl handler if it was queued */
3437 #if defined(__DragonFly__)
3438 /* DragonFly: release serializer to avoid deadlock */
3439 wlan_serialize_exit();
3441 ieee80211_waitfor_parent(ic
);
3444 * Check if the MAC address was changed
3445 * via SIOCSIFLLADDR ioctl.
3447 if ((ifp
->if_flags
& IFF_UP
) == 0 &&
3448 !IEEE80211_ADDR_EQ(vap
->iv_myaddr
, IF_LLADDR(ifp
)))
3449 IEEE80211_ADDR_COPY(vap
->iv_myaddr
,
3451 #if defined(__DragonFly__)
3452 wlan_serialize_enter();
3458 /* DragonFly: serializer must be held */
3459 ieee80211_runtask(ic
, &ic
->ic_mcast_task
);
3463 /* DragonFly: serializer must be held */
3464 ifr
= (struct ifreq
*)data
;
3465 error
= ifmedia_ioctl(ifp
, ifr
, &vap
->iv_media
, cmd
);
3468 error
= ieee80211_ioctl_get80211(vap
, cmd
,
3469 (struct ieee80211req
*) data
);
3472 error
= caps_priv_check_self(SYSCAP_NONET_WIFI
);
3474 error
= ieee80211_ioctl_set80211(vap
, cmd
,
3475 (struct ieee80211req
*) data
);
3477 case SIOCG80211STATS
:
3478 ifr
= (struct ifreq
*)data
;
3479 copyout(&vap
->iv_stats
, ifr
->ifr_data
, sizeof (vap
->iv_stats
));
3482 ifr
= (struct ifreq
*)data
;
3483 if (!(IEEE80211_MTU_MIN
<= ifr
->ifr_mtu
&&
3484 ifr
->ifr_mtu
<= IEEE80211_MTU_MAX
))
3487 ifp
->if_mtu
= ifr
->ifr_mtu
;
3491 * XXX Handle this directly so we can suppress if_init calls.
3492 * XXX This should be done in ether_ioctl but for the moment
3493 * XXX there are too many other parts of the system that
3494 * XXX set IFF_UP and so suppress if_init being called when
3497 ifa
= (struct ifaddr
*) data
;
3498 switch (ifa
->ifa_addr
->sa_family
) {
3501 if ((ifp
->if_flags
& IFF_UP
) == 0) {
3502 ifp
->if_flags
|= IFF_UP
;
3503 ifp
->if_init(ifp
->if_softc
);
3505 arp_ifinit(ifp
, ifa
);
3509 if ((ifp
->if_flags
& IFF_UP
) == 0) {
3510 ifp
->if_flags
|= IFF_UP
;
3511 ifp
->if_init(ifp
->if_softc
);
3518 * Pass unknown ioctls first to the driver, and if it
3519 * returns ENOTTY, then to the generic Ethernet handler.
3521 if (ic
->ic_ioctl
!= NULL
&&
3522 (error
= ic
->ic_ioctl(ic
, cmd
, data
)) != ENOTTY
)
3524 /* DragonFly: serializer must be held */
3525 error
= ether_ioctl(ifp
, cmd
, data
);