xref: /freebsd/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c (revision cc61bf9eccd46592704f3e7bc189c94ccae8f524)
109cbe818SShteryana Shopova /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
409cbe818SShteryana Shopova  * Copyright (c) 2010 The FreeBSD Foundation
55fff2859SEd Maste  *
609cbe818SShteryana Shopova  * This software was developed by Shteryana Sotirova Shopova under
709cbe818SShteryana Shopova  * sponsorship from the FreeBSD Foundation.
809cbe818SShteryana Shopova  *
909cbe818SShteryana Shopova  * Redistribution and use in source and binary forms, with or without
1009cbe818SShteryana Shopova  * modification, are permitted provided that the following conditions
1109cbe818SShteryana Shopova  * are met:
1209cbe818SShteryana Shopova  * 1. Redistributions of source code must retain the above copyright
1309cbe818SShteryana Shopova  *    notice, this list of conditions and the following disclaimer.
1409cbe818SShteryana Shopova  * 2. Redistributions in binary form must reproduce the above copyright
1509cbe818SShteryana Shopova  *    notice, this list of conditions and the following disclaimer in the
1609cbe818SShteryana Shopova  *    documentation and/or other materials provided with the distribution.
1709cbe818SShteryana Shopova  *
1809cbe818SShteryana Shopova  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1909cbe818SShteryana Shopova  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2009cbe818SShteryana Shopova  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2109cbe818SShteryana Shopova  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2209cbe818SShteryana Shopova  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2309cbe818SShteryana Shopova  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2409cbe818SShteryana Shopova  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2509cbe818SShteryana Shopova  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2609cbe818SShteryana Shopova  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2709cbe818SShteryana Shopova  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2809cbe818SShteryana Shopova  * SUCH DAMAGE.
2909cbe818SShteryana Shopova  */
3009cbe818SShteryana Shopova 
3109cbe818SShteryana Shopova #include <sys/ioctl.h>
3209cbe818SShteryana Shopova #include <sys/param.h>
3309cbe818SShteryana Shopova #include <sys/module.h>
3409cbe818SShteryana Shopova #include <sys/linker.h>
3509cbe818SShteryana Shopova #include <sys/socket.h>
3609cbe818SShteryana Shopova #include <sys/sysctl.h>
3709cbe818SShteryana Shopova 
3809cbe818SShteryana Shopova #include <net/if.h>
3909cbe818SShteryana Shopova #include <net/if_dl.h>
4009cbe818SShteryana Shopova #include <net/if_media.h>
4109cbe818SShteryana Shopova #include <net/if_mib.h>
4209cbe818SShteryana Shopova #include <net/if_types.h>
4309cbe818SShteryana Shopova #include <net80211/ieee80211.h>
4409cbe818SShteryana Shopova #include <net80211/ieee80211_ioctl.h>
4509cbe818SShteryana Shopova #include <net80211/ieee80211_regdomain.h>
4609cbe818SShteryana Shopova 
4709cbe818SShteryana Shopova #include <errno.h>
4809cbe818SShteryana Shopova #include <ifaddrs.h>
4909cbe818SShteryana Shopova #include <stdarg.h>
5009cbe818SShteryana Shopova #include <stdlib.h>
5109cbe818SShteryana Shopova #include <stdio.h>
5209cbe818SShteryana Shopova #include <string.h>
5309cbe818SShteryana Shopova #include <syslog.h>
5409cbe818SShteryana Shopova 
5509cbe818SShteryana Shopova #include <bsnmp/snmpmod.h>
5609cbe818SShteryana Shopova #include <bsnmp/snmp_mibII.h>
5709cbe818SShteryana Shopova 
588e9b3e70SHartmut Brandt #define	SNMPTREE_TYPES
5909cbe818SShteryana Shopova #include "wlan_tree.h"
6009cbe818SShteryana Shopova #include "wlan_snmp.h"
6109cbe818SShteryana Shopova 
6209cbe818SShteryana Shopova static int sock = -1;
6309cbe818SShteryana Shopova 
6409cbe818SShteryana Shopova static int	wlan_ioctl(char *, uint16_t, int *, void *, size_t *, int);
6509cbe818SShteryana Shopova static int	wlan_kmod_load(const char *);
6609cbe818SShteryana Shopova static uint32_t	wlan_drivercaps_to_snmp(uint32_t);
6709cbe818SShteryana Shopova static uint32_t	wlan_cryptocaps_to_snmp(uint32_t);
6809cbe818SShteryana Shopova static uint32_t	wlan_htcaps_to_snmp(uint32_t);
6909cbe818SShteryana Shopova static uint32_t	wlan_peerstate_to_snmp(uint32_t);
7009cbe818SShteryana Shopova static uint32_t	wlan_peercaps_to_snmp(uint32_t );
71*cc61bf9eSJohn Baldwin static enum WlanIfPhyMode wlan_channel_flags_to_snmp_phy(uint32_t);
72*cc61bf9eSJohn Baldwin static enum WlanRegDomainCode wlan_regdomain_to_snmp(int);
7309cbe818SShteryana Shopova static uint32_t	wlan_snmp_to_scan_flags(int);
7409cbe818SShteryana Shopova static int	wlan_config_snmp2ioctl(int);
7509cbe818SShteryana Shopova static int	wlan_snmp_to_regdomain(enum WlanRegDomainCode);
7609cbe818SShteryana Shopova static int	wlan_config_get_country(struct wlan_iface *);
7709cbe818SShteryana Shopova static int	wlan_config_set_country(struct wlan_iface *, char *, int);
7809cbe818SShteryana Shopova static int	wlan_config_get_dchannel(struct wlan_iface *wif);
7909cbe818SShteryana Shopova static int	wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t);
8009cbe818SShteryana Shopova static int	wlan_config_get_bssid(struct wlan_iface *);
8109cbe818SShteryana Shopova static int	wlan_config_set_bssid(struct wlan_iface *, uint8_t *);
8209cbe818SShteryana Shopova static void	wlan_config_set_snmp_intval(struct wlan_iface *, int, int);
8309cbe818SShteryana Shopova static int	wlan_config_snmp2value(int, int, int *);
8409cbe818SShteryana Shopova static int	wlan_config_check(struct wlan_iface *, int);
8509cbe818SShteryana Shopova static int	wlan_config_get_intval(struct wlan_iface *, int);
8609cbe818SShteryana Shopova static int	wlan_config_set_intval(struct wlan_iface *, int, int);
8709cbe818SShteryana Shopova static int	wlan_add_new_scan_result(struct wlan_iface *,
8809cbe818SShteryana Shopova     const struct ieee80211req_scan_result *, uint8_t *);
8909cbe818SShteryana Shopova static int	wlan_add_mac_macinfo(struct wlan_iface *,
9009cbe818SShteryana Shopova     const struct ieee80211req_maclist *);
9109cbe818SShteryana Shopova static struct wlan_peer *wlan_add_peerinfo(const struct ieee80211req_sta_info *);
9209cbe818SShteryana Shopova 
9309cbe818SShteryana Shopova int
wlan_ioctl_init(void)9409cbe818SShteryana Shopova wlan_ioctl_init(void)
9509cbe818SShteryana Shopova {
9609cbe818SShteryana Shopova 	if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
9709cbe818SShteryana Shopova 		syslog(LOG_ERR, "cannot open socket : %s", strerror(errno));
9809cbe818SShteryana Shopova 		return (-1);
9909cbe818SShteryana Shopova 	}
10009cbe818SShteryana Shopova 
10109cbe818SShteryana Shopova 	return (0);
10209cbe818SShteryana Shopova }
10309cbe818SShteryana Shopova /*
10409cbe818SShteryana Shopova  * Load the needed modules in kernel if not already there.
10509cbe818SShteryana Shopova  */
10609cbe818SShteryana Shopova enum wlan_kmodules {
10709cbe818SShteryana Shopova 	WLAN_KMOD = 0,
10809cbe818SShteryana Shopova 	WLAN_KMOD_ACL,
10909cbe818SShteryana Shopova 	WLAN_KMOD_WEP,
11009cbe818SShteryana Shopova 	WLAN_KMODS_MAX
11109cbe818SShteryana Shopova };
11209cbe818SShteryana Shopova 
11309cbe818SShteryana Shopova static const char *wmod_names[] = {
11409cbe818SShteryana Shopova 	"wlan",
11509cbe818SShteryana Shopova 	"wlan_wlan_acl",
11609cbe818SShteryana Shopova 	"wlan_wep",
11709cbe818SShteryana Shopova 	NULL
11809cbe818SShteryana Shopova };
11909cbe818SShteryana Shopova 
12009cbe818SShteryana Shopova static int
wlan_kmod_load(const char * modname)12109cbe818SShteryana Shopova wlan_kmod_load(const char *modname)
12209cbe818SShteryana Shopova {
12309cbe818SShteryana Shopova 	int fileid, modid;
12409cbe818SShteryana Shopova 	struct module_stat mstat;
12509cbe818SShteryana Shopova 
12609cbe818SShteryana Shopova 	mstat.version = sizeof(struct module_stat);
12709cbe818SShteryana Shopova 	for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
12809cbe818SShteryana Shopova 		for (modid = kldfirstmod(fileid); modid > 0;
12909cbe818SShteryana Shopova 			modid = modfnext(modid)) {
13009cbe818SShteryana Shopova 			if (modstat(modid, &mstat) < 0)
13109cbe818SShteryana Shopova 				continue;
13209cbe818SShteryana Shopova 			if (strcmp(modname, mstat.name) == 0)
13309cbe818SShteryana Shopova 				return (0);
13409cbe818SShteryana Shopova 		}
13509cbe818SShteryana Shopova 	}
13609cbe818SShteryana Shopova 
13709cbe818SShteryana Shopova 	/* Not present - load it. */
13809cbe818SShteryana Shopova 	if (kldload(modname) < 0) {
13909cbe818SShteryana Shopova 		syslog(LOG_ERR, "failed to load %s kernel module - %s", modname,
14009cbe818SShteryana Shopova 		    strerror(errno));
14109cbe818SShteryana Shopova 		return (-1);
14209cbe818SShteryana Shopova 	}
14309cbe818SShteryana Shopova 
14409cbe818SShteryana Shopova 	return (1);
14509cbe818SShteryana Shopova }
14609cbe818SShteryana Shopova 
14709cbe818SShteryana Shopova int
wlan_kmodules_load(void)14809cbe818SShteryana Shopova wlan_kmodules_load(void)
14909cbe818SShteryana Shopova {
15009cbe818SShteryana Shopova 	if (wlan_kmod_load(wmod_names[WLAN_KMOD]) < 0)
15109cbe818SShteryana Shopova 		return (-1);
15209cbe818SShteryana Shopova 
15309cbe818SShteryana Shopova 	if (wlan_kmod_load(wmod_names[WLAN_KMOD_ACL]) > 0)
15409cbe818SShteryana Shopova 		syslog(LOG_NOTICE, "SNMP wlan loaded %s module",
15509cbe818SShteryana Shopova 		    wmod_names[WLAN_KMOD_ACL]);
15609cbe818SShteryana Shopova 
15709cbe818SShteryana Shopova 	if (wlan_kmod_load(wmod_names[WLAN_KMOD_WEP]) > 0)
15809cbe818SShteryana Shopova 		syslog(LOG_NOTICE, "SNMP wlan loaded %s module",
15909cbe818SShteryana Shopova 		    wmod_names[WLAN_KMOD_WEP]);
16009cbe818SShteryana Shopova 
16109cbe818SShteryana Shopova 	return (0);
16209cbe818SShteryana Shopova }
16309cbe818SShteryana Shopova 
16409cbe818SShteryana Shopova /* XXX: FIXME */
16509cbe818SShteryana Shopova static int
wlan_ioctl(char * wif_name,uint16_t req_type,int * val,void * arg,size_t * argsize,int set)16609cbe818SShteryana Shopova wlan_ioctl(char *wif_name, uint16_t req_type, int *val, void *arg,
16709cbe818SShteryana Shopova      size_t *argsize, int set)
16809cbe818SShteryana Shopova {
16909cbe818SShteryana Shopova 	struct ieee80211req ireq;
17009cbe818SShteryana Shopova 
17109cbe818SShteryana Shopova 	memset(&ireq, 0, sizeof(struct ieee80211req));
17209cbe818SShteryana Shopova 	strlcpy(ireq.i_name, wif_name, IFNAMSIZ);
17309cbe818SShteryana Shopova 
17409cbe818SShteryana Shopova 	ireq.i_type = req_type;
17509cbe818SShteryana Shopova 	ireq.i_val = *val;
17609cbe818SShteryana Shopova 	ireq.i_len = *argsize;
17709cbe818SShteryana Shopova 	ireq.i_data = arg;
17809cbe818SShteryana Shopova 
17909cbe818SShteryana Shopova 	if (ioctl(sock, set ? SIOCS80211 : SIOCG80211, &ireq) < 0) {
18009cbe818SShteryana Shopova 		syslog(LOG_ERR, "iface %s - %s param: ioctl(%d) "
18109cbe818SShteryana Shopova 		    "failed: %s", wif_name, set ? "set" : "get",
18209cbe818SShteryana Shopova 		    req_type, strerror(errno));
18309cbe818SShteryana Shopova 		return (-1);
18409cbe818SShteryana Shopova 	}
18509cbe818SShteryana Shopova 
18609cbe818SShteryana Shopova 	*argsize = ireq.i_len;
18709cbe818SShteryana Shopova 	*val = ireq.i_val;
18809cbe818SShteryana Shopova 
18909cbe818SShteryana Shopova 	return (0);
19009cbe818SShteryana Shopova }
19109cbe818SShteryana Shopova 
19209cbe818SShteryana Shopova int
wlan_check_media(char * ifname)19309cbe818SShteryana Shopova wlan_check_media(char *ifname)
19409cbe818SShteryana Shopova {
19509cbe818SShteryana Shopova 	struct ifmediareq ifmr;
19609cbe818SShteryana Shopova 
19709cbe818SShteryana Shopova 	memset(&ifmr, 0, sizeof(struct ifmediareq));
19809cbe818SShteryana Shopova 	strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
19909cbe818SShteryana Shopova 
20009cbe818SShteryana Shopova 	if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0 || ifmr.ifm_count == 0)
20109cbe818SShteryana Shopova 		return (0);     /* Interface doesn't support SIOCGIFMEDIA. */
20209cbe818SShteryana Shopova 
20309cbe818SShteryana Shopova 	if ((ifmr.ifm_status & IFM_AVALID) == 0)
20409cbe818SShteryana Shopova 		return (0);
20509cbe818SShteryana Shopova 
20609cbe818SShteryana Shopova 	return (IFM_TYPE(ifmr.ifm_active));
20709cbe818SShteryana Shopova }
20809cbe818SShteryana Shopova 
20909cbe818SShteryana Shopova int
wlan_get_opmode(struct wlan_iface * wif)21009cbe818SShteryana Shopova wlan_get_opmode(struct wlan_iface *wif)
21109cbe818SShteryana Shopova {
21209cbe818SShteryana Shopova 	struct ifmediareq ifmr;
21309cbe818SShteryana Shopova 
21409cbe818SShteryana Shopova 	memset(&ifmr, 0, sizeof(struct ifmediareq));
21509cbe818SShteryana Shopova 	strlcpy(ifmr.ifm_name, wif->wname, sizeof(ifmr.ifm_name));
21609cbe818SShteryana Shopova 
21709cbe818SShteryana Shopova 	if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0) {
21809cbe818SShteryana Shopova 		if (errno == ENXIO)
21909cbe818SShteryana Shopova 			return (-1);
22009cbe818SShteryana Shopova 		wif->mode = WlanIfaceOperatingModeType_station;
22109cbe818SShteryana Shopova 		return (0);
22209cbe818SShteryana Shopova 	}
22309cbe818SShteryana Shopova 
22409cbe818SShteryana Shopova 	if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
22509cbe818SShteryana Shopova 		if (ifmr.ifm_current & IFM_FLAG0)
22609cbe818SShteryana Shopova 			wif->mode = WlanIfaceOperatingModeType_adhocDemo;
22709cbe818SShteryana Shopova 		else
22809cbe818SShteryana Shopova 			wif->mode = WlanIfaceOperatingModeType_ibss;
22909cbe818SShteryana Shopova 	} else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
23009cbe818SShteryana Shopova 		wif->mode = WlanIfaceOperatingModeType_hostAp;
23109cbe818SShteryana Shopova 	else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
23209cbe818SShteryana Shopova 		wif->mode = WlanIfaceOperatingModeType_monitor;
23309cbe818SShteryana Shopova 	else if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
23409cbe818SShteryana Shopova 		wif->mode = WlanIfaceOperatingModeType_meshPoint;
23509cbe818SShteryana Shopova 	else if (ifmr.ifm_current & IFM_IEEE80211_WDS)
23609cbe818SShteryana Shopova 		wif->mode = WlanIfaceOperatingModeType_wds;
23709cbe818SShteryana Shopova 
23809cbe818SShteryana Shopova 	return (0);
23909cbe818SShteryana Shopova }
24009cbe818SShteryana Shopova 
24109cbe818SShteryana Shopova int
wlan_config_state(struct wlan_iface * wif,uint8_t set)24209cbe818SShteryana Shopova wlan_config_state(struct wlan_iface *wif, uint8_t set)
24309cbe818SShteryana Shopova {
24409cbe818SShteryana Shopova 	int	flags;
24509cbe818SShteryana Shopova 	struct ifreq ifr;
24609cbe818SShteryana Shopova 
24709cbe818SShteryana Shopova 	memset(&ifr, 0, sizeof(ifr));
24809cbe818SShteryana Shopova 	strcpy(ifr.ifr_name, wif->wname);
24909cbe818SShteryana Shopova 
25009cbe818SShteryana Shopova 	if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
25109cbe818SShteryana Shopova 		syslog(LOG_ERR, "set %s status: ioctl(SIOCGIFFLAGS) "
25209cbe818SShteryana Shopova 		    "failed: %s", wif->wname, strerror(errno));
25309cbe818SShteryana Shopova 		return (-1);
25409cbe818SShteryana Shopova 	}
25509cbe818SShteryana Shopova 
25609cbe818SShteryana Shopova 	if (set == 0) {
25709cbe818SShteryana Shopova 		if ((ifr.ifr_flags & IFF_UP) != 0)
25809cbe818SShteryana Shopova 			wif->state = wlanIfaceState_up;
25909cbe818SShteryana Shopova 		else
26009cbe818SShteryana Shopova 			wif->state = wlanIfaceState_down;
26109cbe818SShteryana Shopova 		return (0);
26209cbe818SShteryana Shopova 	}
26309cbe818SShteryana Shopova 
26409cbe818SShteryana Shopova 	flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
26509cbe818SShteryana Shopova 
26609cbe818SShteryana Shopova 	if (wif->state == wlanIfaceState_up)
26709cbe818SShteryana Shopova 		flags |= IFF_UP;
26809cbe818SShteryana Shopova 	else
26909cbe818SShteryana Shopova 		flags &= ~IFF_UP;
27009cbe818SShteryana Shopova 
27109cbe818SShteryana Shopova 	ifr.ifr_flags = flags & 0xffff;
27209cbe818SShteryana Shopova 	ifr.ifr_flagshigh = flags >> 16;
27309cbe818SShteryana Shopova 	if (ioctl(sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
27409cbe818SShteryana Shopova 		syslog(LOG_ERR, "set %s %s: ioctl(SIOCSIFFLAGS) failed: %s",
27509cbe818SShteryana Shopova 		    wif->wname, wif->state == wlanIfaceState_up?"up":"down",
27609cbe818SShteryana Shopova 		    strerror(errno));
27709cbe818SShteryana Shopova 		return (-1);
27809cbe818SShteryana Shopova 	}
27909cbe818SShteryana Shopova 
28009cbe818SShteryana Shopova 	return (0);
28109cbe818SShteryana Shopova }
28209cbe818SShteryana Shopova 
28309cbe818SShteryana Shopova int
wlan_get_local_addr(struct wlan_iface * wif)28409cbe818SShteryana Shopova wlan_get_local_addr(struct wlan_iface *wif)
28509cbe818SShteryana Shopova {
28609cbe818SShteryana Shopova 	int len;
28709cbe818SShteryana Shopova 	char ifname[IFNAMSIZ];
28809cbe818SShteryana Shopova 	struct ifaddrs *ifap, *ifa;
28909cbe818SShteryana Shopova 	struct sockaddr_dl sdl;
29009cbe818SShteryana Shopova 
29109cbe818SShteryana Shopova 	if (getifaddrs(&ifap) != 0) {
29209cbe818SShteryana Shopova 		syslog(LOG_ERR, "wlan get mac: getifaddrs() failed - %s",
29309cbe818SShteryana Shopova 		    strerror(errno));
29409cbe818SShteryana Shopova 		return (-1);
29509cbe818SShteryana Shopova 	}
29609cbe818SShteryana Shopova 
29709cbe818SShteryana Shopova 	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
29809cbe818SShteryana Shopova 		if (ifa->ifa_addr->sa_family != AF_LINK)
29909cbe818SShteryana Shopova 			continue;
30009cbe818SShteryana Shopova 		memcpy(&sdl, ifa->ifa_addr, sizeof(struct sockaddr_dl));
30109cbe818SShteryana Shopova 		if (sdl.sdl_alen > IEEE80211_ADDR_LEN)
30209cbe818SShteryana Shopova 			continue;
30309cbe818SShteryana Shopova 		if ((len = sdl.sdl_nlen) >= IFNAMSIZ)
30409cbe818SShteryana Shopova 			len = IFNAMSIZ - 1;
30509cbe818SShteryana Shopova 		memcpy(ifname, sdl.sdl_data, len);
30609cbe818SShteryana Shopova 		ifname[len] = '\0';
30709cbe818SShteryana Shopova 		if (strcmp(wif->wname, ifname) == 0)
30809cbe818SShteryana Shopova 			break;
30909cbe818SShteryana Shopova 	}
31009cbe818SShteryana Shopova 
31109cbe818SShteryana Shopova 	freeifaddrs(ifap);
31209cbe818SShteryana Shopova 	return (0);
31309cbe818SShteryana Shopova }
31409cbe818SShteryana Shopova 
31509cbe818SShteryana Shopova int
wlan_get_parent(struct wlan_iface * wif __unused)31609cbe818SShteryana Shopova wlan_get_parent(struct wlan_iface *wif __unused)
31709cbe818SShteryana Shopova {
31809cbe818SShteryana Shopova 	/* XXX: There's no way to fetch this from the kernel. */
31909cbe818SShteryana Shopova 	return (0);
32009cbe818SShteryana Shopova }
32109cbe818SShteryana Shopova 
32209cbe818SShteryana Shopova /* XXX */
32309cbe818SShteryana Shopova #define	IEEE80211_C_STA		0x00000001	/* CAPABILITY: STA available */
32409cbe818SShteryana Shopova #define	IEEE80211_C_8023ENCAP	0x00000002	/* CAPABILITY: 802.3 encap */
32509cbe818SShteryana Shopova #define	IEEE80211_C_FF		0x00000040	/* CAPABILITY: ATH FF avail */
32609cbe818SShteryana Shopova #define	IEEE80211_C_TURBOP	0x00000080	/* CAPABILITY: ATH Turbo avail*/
32709cbe818SShteryana Shopova #define	IEEE80211_C_IBSS	0x00000100	/* CAPABILITY: IBSS available */
32809cbe818SShteryana Shopova #define	IEEE80211_C_PMGT	0x00000200	/* CAPABILITY: Power mgmt */
32909cbe818SShteryana Shopova #define	IEEE80211_C_HOSTAP	0x00000400	/* CAPABILITY: HOSTAP avail */
33009cbe818SShteryana Shopova #define	IEEE80211_C_AHDEMO	0x00000800	/* CAPABILITY: Old Adhoc Demo */
33109cbe818SShteryana Shopova #define	IEEE80211_C_SWRETRY	0x00001000	/* CAPABILITY: sw tx retry */
33209cbe818SShteryana Shopova #define	IEEE80211_C_TXPMGT	0x00002000	/* CAPABILITY: tx power mgmt */
33309cbe818SShteryana Shopova #define	IEEE80211_C_SHSLOT	0x00004000	/* CAPABILITY: short slottime */
33409cbe818SShteryana Shopova #define	IEEE80211_C_SHPREAMBLE	0x00008000	/* CAPABILITY: short preamble */
33509cbe818SShteryana Shopova #define	IEEE80211_C_MONITOR	0x00010000	/* CAPABILITY: monitor mode */
33609cbe818SShteryana Shopova #define	IEEE80211_C_DFS		0x00020000	/* CAPABILITY: DFS/radar avail*/
33709cbe818SShteryana Shopova #define	IEEE80211_C_MBSS	0x00040000	/* CAPABILITY: MBSS available */
33809cbe818SShteryana Shopova /* 0x7c0000 available */
33909cbe818SShteryana Shopova #define	IEEE80211_C_WPA1	0x00800000	/* CAPABILITY: WPA1 avail */
34009cbe818SShteryana Shopova #define	IEEE80211_C_WPA2	0x01000000	/* CAPABILITY: WPA2 avail */
34109cbe818SShteryana Shopova #define	IEEE80211_C_WPA		0x01800000	/* CAPABILITY: WPA1+WPA2 avail*/
34209cbe818SShteryana Shopova #define	IEEE80211_C_BURST	0x02000000	/* CAPABILITY: frame bursting */
34309cbe818SShteryana Shopova #define	IEEE80211_C_WME		0x04000000	/* CAPABILITY: WME avail */
34409cbe818SShteryana Shopova #define	IEEE80211_C_WDS		0x08000000	/* CAPABILITY: 4-addr support */
34509cbe818SShteryana Shopova /* 0x10000000 reserved */
34609cbe818SShteryana Shopova #define	IEEE80211_C_BGSCAN	0x20000000	/* CAPABILITY: bg scanning */
34709cbe818SShteryana Shopova #define	IEEE80211_C_TXFRAG	0x40000000	/* CAPABILITY: tx fragments */
34809cbe818SShteryana Shopova #define	IEEE80211_C_TDMA	0x80000000	/* CAPABILITY: TDMA avail */
34909cbe818SShteryana Shopova 
35009cbe818SShteryana Shopova static uint32_t
wlan_drivercaps_to_snmp(uint32_t dcaps)35109cbe818SShteryana Shopova wlan_drivercaps_to_snmp(uint32_t dcaps)
35209cbe818SShteryana Shopova {
35309cbe818SShteryana Shopova 	uint32_t scaps = 0;
35409cbe818SShteryana Shopova 
35509cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_STA) != 0)
35609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_station);
35709cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_8023ENCAP) != 0)
35809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_ieee8023encap);
35909cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_FF) != 0)
36009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_athFastFrames);
36109cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_TURBOP) != 0)
36209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_athTurbo);
36309cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_IBSS) != 0)
36409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_ibss);
36509cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_PMGT) != 0)
36609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_pmgt);
36709cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_HOSTAP) != 0)
36809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_hostAp);
36909cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_AHDEMO) != 0)
37009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_ahDemo);
37109cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_SWRETRY) != 0)
37209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_swRetry);
37309cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_TXPMGT) != 0)
37409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_txPmgt);
37509cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_SHSLOT) != 0)
37609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_shortSlot);
37709cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_SHPREAMBLE) != 0)
37809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_shortPreamble);
37909cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_MONITOR) != 0)
38009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_monitor);
38109cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_DFS) != 0)
38209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_dfs);
38309cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_MBSS) != 0)
38409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_mbss);
38509cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_WPA1) != 0)
38609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_wpa1);
38709cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_WPA2) != 0)
38809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_wpa2);
38909cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_BURST) != 0)
39009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_burst);
39109cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_WME) != 0)
39209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_wme);
39309cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_WDS) != 0)
39409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_wds);
39509cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_BGSCAN) != 0)
39609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_bgScan);
39709cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_TXFRAG) != 0)
39809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_txFrag);
39909cbe818SShteryana Shopova 	if ((dcaps & IEEE80211_C_TDMA) != 0)
40009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanDriverCaps_tdma);
40109cbe818SShteryana Shopova 
40209cbe818SShteryana Shopova 	return (scaps);
40309cbe818SShteryana Shopova }
40409cbe818SShteryana Shopova 
40509cbe818SShteryana Shopova static uint32_t
wlan_cryptocaps_to_snmp(uint32_t ccaps)40609cbe818SShteryana Shopova wlan_cryptocaps_to_snmp(uint32_t ccaps)
40709cbe818SShteryana Shopova {
40809cbe818SShteryana Shopova 	uint32_t scaps = 0;
40909cbe818SShteryana Shopova 
41009cbe818SShteryana Shopova #if NOT_YET
41109cbe818SShteryana Shopova 	if ((ccaps & IEEE80211_CRYPTO_WEP) != 0)
41209cbe818SShteryana Shopova 		scaps |= (0x1 << wlanCryptoCaps_wep);
41309cbe818SShteryana Shopova 	if ((ccaps & IEEE80211_CRYPTO_TKIP) != 0)
41409cbe818SShteryana Shopova 		scaps |= (0x1 << wlanCryptoCaps_tkip);
41509cbe818SShteryana Shopova 	if ((ccaps & IEEE80211_CRYPTO_AES_OCB) != 0)
41609cbe818SShteryana Shopova 		scaps |= (0x1 << wlanCryptoCaps_aes);
41709cbe818SShteryana Shopova 	if ((ccaps & IEEE80211_CRYPTO_AES_CCM) != 0)
41809cbe818SShteryana Shopova 		scaps |= (0x1 << wlanCryptoCaps_aesCcm);
41909cbe818SShteryana Shopova 	if ((ccaps & IEEE80211_CRYPTO_TKIPMIC) != 0)
42009cbe818SShteryana Shopova 		scaps |= (0x1 << wlanCryptoCaps_tkipMic);
42109cbe818SShteryana Shopova 	if ((ccaps & IEEE80211_CRYPTO_CKIP) != 0)
42209cbe818SShteryana Shopova 		scaps |= (0x1 << wlanCryptoCaps_ckip);
42309cbe818SShteryana Shopova #else /* !NOT_YET */
42409cbe818SShteryana Shopova 	scaps = ccaps;
42509cbe818SShteryana Shopova #endif
42609cbe818SShteryana Shopova 	return (scaps);
42709cbe818SShteryana Shopova }
42809cbe818SShteryana Shopova 
42909cbe818SShteryana Shopova #define	IEEE80211_HTC_AMPDU	0x00010000	/* CAPABILITY: A-MPDU tx */
43009cbe818SShteryana Shopova #define	IEEE80211_HTC_AMSDU	0x00020000	/* CAPABILITY: A-MSDU tx */
43109cbe818SShteryana Shopova /* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */
43209cbe818SShteryana Shopova #define	IEEE80211_HTC_HT	0x00040000	/* CAPABILITY: HT operation */
43309cbe818SShteryana Shopova #define	IEEE80211_HTC_SMPS	0x00080000	/* CAPABILITY: MIMO power save*/
43409cbe818SShteryana Shopova #define	IEEE80211_HTC_RIFS	0x00100000	/* CAPABILITY: RIFS support */
43509cbe818SShteryana Shopova 
43609cbe818SShteryana Shopova static uint32_t
wlan_htcaps_to_snmp(uint32_t hcaps)43709cbe818SShteryana Shopova wlan_htcaps_to_snmp(uint32_t hcaps)
43809cbe818SShteryana Shopova {
43909cbe818SShteryana Shopova 	uint32_t scaps = 0;
44009cbe818SShteryana Shopova 
44109cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_LDPC) != 0)
44209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_ldpc);
44309cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_CHWIDTH40) != 0)
44409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_chwidth40);
44509cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_GREENFIELD) != 0)
44609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_greenField);
44709cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_SHORTGI20) != 0)
44809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_shortGi20);
44909cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_SHORTGI40) != 0)
45009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_shortGi40);
45109cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_TXSTBC) != 0)
45209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_txStbc);
45309cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_DELBA) != 0)
45409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_delba);
45509cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_MAXAMSDU_7935) != 0)
45609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_amsdu7935);
45709cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_DSSSCCK40) != 0)
45809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_dssscck40);
45909cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_PSMP) != 0)
46009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_psmp);
46109cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_40INTOLERANT) != 0)
46209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_fortyMHzIntolerant);
46309cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTCAP_LSIGTXOPPROT) != 0)
46409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_lsigTxOpProt);
46509cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTC_AMPDU) != 0)
46609cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_htcAmpdu);
46709cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTC_AMSDU) != 0)
46809cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_htcAmsdu);
46909cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTC_HT) != 0)
47009cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_htcHt);
47109cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTC_SMPS) != 0)
47209cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_htcSmps);
47309cbe818SShteryana Shopova 	if ((hcaps & IEEE80211_HTC_RIFS) != 0)
47409cbe818SShteryana Shopova 		scaps |= (0x1 << WlanHTCaps_htcRifs);
47509cbe818SShteryana Shopova 
47609cbe818SShteryana Shopova 	return (scaps);
47709cbe818SShteryana Shopova }
47809cbe818SShteryana Shopova 
47909cbe818SShteryana Shopova /* XXX: Not here? */
48009cbe818SShteryana Shopova #define	WLAN_SET_TDMA_OPMODE(w) do {						\
48109cbe818SShteryana Shopova 	if ((w)->mode == WlanIfaceOperatingModeType_adhocDemo &&		\
48209cbe818SShteryana Shopova 	    ((w)->drivercaps & WlanDriverCaps_tdma) != 0)			\
48309cbe818SShteryana Shopova 		(w)->mode = WlanIfaceOperatingModeType_tdma;			\
48409cbe818SShteryana Shopova } while (0)
48509cbe818SShteryana Shopova int
wlan_get_driver_caps(struct wlan_iface * wif)48609cbe818SShteryana Shopova wlan_get_driver_caps(struct wlan_iface *wif)
48709cbe818SShteryana Shopova {
48809cbe818SShteryana Shopova 	int val = 0;
48909cbe818SShteryana Shopova 	size_t argsize;
49009cbe818SShteryana Shopova 	struct ieee80211_devcaps_req dc;
49109cbe818SShteryana Shopova 
49209cbe818SShteryana Shopova 	memset(&dc, 0, sizeof(struct ieee80211_devcaps_req));
49309cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211_devcaps_req);
49409cbe818SShteryana Shopova 
49509cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_DEVCAPS, &val, &dc,
49609cbe818SShteryana Shopova 	    &argsize, 0) < 0)
49709cbe818SShteryana Shopova 		return (-1);
49809cbe818SShteryana Shopova 
49909cbe818SShteryana Shopova 	wif->drivercaps = wlan_drivercaps_to_snmp(dc.dc_drivercaps);
50009cbe818SShteryana Shopova 	wif->cryptocaps = wlan_cryptocaps_to_snmp(dc.dc_cryptocaps);
50109cbe818SShteryana Shopova 	wif->htcaps = wlan_htcaps_to_snmp(dc.dc_htcaps);
50209cbe818SShteryana Shopova 
50309cbe818SShteryana Shopova 	WLAN_SET_TDMA_OPMODE(wif);
50409cbe818SShteryana Shopova 
50509cbe818SShteryana Shopova 	argsize = dc.dc_chaninfo.ic_nchans * sizeof(struct ieee80211_channel);
50609cbe818SShteryana Shopova 	wif->chanlist = (struct ieee80211_channel *)malloc(argsize);
50709cbe818SShteryana Shopova 	if (wif->chanlist == NULL)
50809cbe818SShteryana Shopova 		return (0);
50909cbe818SShteryana Shopova 
51009cbe818SShteryana Shopova 	memcpy(wif->chanlist, dc.dc_chaninfo.ic_chans, argsize);
51109cbe818SShteryana Shopova 	wif->nchannels = dc.dc_chaninfo.ic_nchans;
51209cbe818SShteryana Shopova 
51309cbe818SShteryana Shopova 	return (0);
51409cbe818SShteryana Shopova }
51509cbe818SShteryana Shopova 
51609cbe818SShteryana Shopova uint8_t
wlan_channel_state_to_snmp(uint8_t cstate)51709cbe818SShteryana Shopova wlan_channel_state_to_snmp(uint8_t cstate)
51809cbe818SShteryana Shopova {
51909cbe818SShteryana Shopova 	uint8_t cs = 0;
52009cbe818SShteryana Shopova 
52109cbe818SShteryana Shopova 	if ((cstate & IEEE80211_CHANSTATE_RADAR) != 0)
52209cbe818SShteryana Shopova 		cs |= (0x1 << WlanIfaceChannelStateType_radar);
52309cbe818SShteryana Shopova 	if ((cstate & IEEE80211_CHANSTATE_CACDONE) != 0)
52409cbe818SShteryana Shopova 		cs |= (0x1 << WlanIfaceChannelStateType_cacDone);
52509cbe818SShteryana Shopova 	if ((cstate & IEEE80211_CHANSTATE_CWINT) != 0)
52609cbe818SShteryana Shopova 		cs |= (0x1 << WlanIfaceChannelStateType_interferenceDetected);
52709cbe818SShteryana Shopova 	if ((cstate & IEEE80211_CHANSTATE_NORADAR) != 0)
52809cbe818SShteryana Shopova 		cs |= (0x1 << WlanIfaceChannelStateType_radarClear);
52909cbe818SShteryana Shopova 
53009cbe818SShteryana Shopova 	return (cs);
53109cbe818SShteryana Shopova }
53209cbe818SShteryana Shopova 
53309cbe818SShteryana Shopova uint32_t
wlan_channel_flags_to_snmp(uint32_t cflags)53409cbe818SShteryana Shopova wlan_channel_flags_to_snmp(uint32_t cflags)
53509cbe818SShteryana Shopova {
53609cbe818SShteryana Shopova 	uint32_t cf = 0;
53709cbe818SShteryana Shopova 
53809cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_TURBO) != 0)
53909cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_turbo);
54009cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_CCK) != 0)
54109cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_cck);
54209cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_OFDM) != 0)
54309cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_ofdm);
54409cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_2GHZ) != 0)
54509cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum2Ghz);
54609cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_5GHZ) != 0)
54709cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum5Ghz);
54809cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_PASSIVE) != 0)
54909cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_passiveScan);
55009cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_DYN) != 0)
55109cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_dynamicCckOfdm);
55209cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_GFSK) != 0)
55309cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_gfsk);
55409cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_GSM) != 0)
55509cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum900Mhz);
55609cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_STURBO) != 0)
55709cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_dot11aStaticTurbo);
55809cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_HALF) != 0)
55909cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_halfRate);
56009cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_QUARTER) != 0)
56109cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_quarterRate);
56209cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_HT20) != 0)
56309cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_ht20);
56409cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_HT40U) != 0)
56509cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_ht40u);
56609cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_HT40D) != 0)
56709cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_ht40d);
56809cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_DFS) != 0)
56909cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_dfs);
57009cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_4MSXMIT) != 0)
57109cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_xmit4ms);
57209cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_NOADHOC) != 0)
57309cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_noAdhoc);
57409cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_NOHOSTAP) != 0)
57509cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_noHostAp);
57609cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_11D) != 0)
57709cbe818SShteryana Shopova 		cf |= (0x1 << WlanIfaceChannelFlagsType_dot11d);
57809cbe818SShteryana Shopova 
57909cbe818SShteryana Shopova 	return (cf);
58009cbe818SShteryana Shopova }
58109cbe818SShteryana Shopova 
58209cbe818SShteryana Shopova /* XXX: */
58309cbe818SShteryana Shopova #define WLAN_SNMP_MAX_CHANS	256
58409cbe818SShteryana Shopova int
wlan_get_channel_list(struct wlan_iface * wif)58509cbe818SShteryana Shopova wlan_get_channel_list(struct wlan_iface *wif)
58609cbe818SShteryana Shopova {
58709cbe818SShteryana Shopova 	int val = 0;
58809cbe818SShteryana Shopova 	uint32_t i, nchans;
58909cbe818SShteryana Shopova 	size_t argsize;
59009cbe818SShteryana Shopova 	struct ieee80211req_chaninfo *chaninfo;
59109cbe818SShteryana Shopova 	struct ieee80211req_chanlist active;
59209cbe818SShteryana Shopova 	const struct ieee80211_channel *c;
59309cbe818SShteryana Shopova 
59409cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211req_chaninfo) +
59509cbe818SShteryana Shopova 	    sizeof(struct ieee80211_channel) * WLAN_SNMP_MAX_CHANS;
59609cbe818SShteryana Shopova 	chaninfo = (struct ieee80211req_chaninfo *)malloc(argsize);
59709cbe818SShteryana Shopova 	if (chaninfo == NULL)
59809cbe818SShteryana Shopova 		return (-1);
59909cbe818SShteryana Shopova 
60009cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANINFO, &val, chaninfo,
60109cbe818SShteryana Shopova 	    &argsize, 0) < 0)
60209cbe818SShteryana Shopova 		return (-1);
60309cbe818SShteryana Shopova 
60409cbe818SShteryana Shopova 	argsize = sizeof(active);
60509cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANLIST, &val, &active,
60609cbe818SShteryana Shopova 	    &argsize, 0) < 0)
60709cbe818SShteryana Shopova 		goto error;
60809cbe818SShteryana Shopova 
60909cbe818SShteryana Shopova 	for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) {
61009cbe818SShteryana Shopova 		c = &chaninfo->ic_chans[i];
61109cbe818SShteryana Shopova 		if (!isset(active.ic_channels, c->ic_ieee))
61209cbe818SShteryana Shopova 				continue;
61309cbe818SShteryana Shopova 		nchans++;
61409cbe818SShteryana Shopova 	}
61509cbe818SShteryana Shopova 	wif->chanlist = (struct ieee80211_channel *)reallocf(wif->chanlist,
61609cbe818SShteryana Shopova 	    nchans * sizeof(*c));
61709cbe818SShteryana Shopova 	if (wif->chanlist == NULL)
61809cbe818SShteryana Shopova 		goto error;
61909cbe818SShteryana Shopova 	wif->nchannels = nchans;
62009cbe818SShteryana Shopova 	for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) {
62109cbe818SShteryana Shopova 		c = &chaninfo->ic_chans[i];
62209cbe818SShteryana Shopova 		if (!isset(active.ic_channels, c->ic_ieee))
62309cbe818SShteryana Shopova 				continue;
62409cbe818SShteryana Shopova 		memcpy(wif->chanlist + nchans, c, sizeof (*c));
62509cbe818SShteryana Shopova 		nchans++;
62609cbe818SShteryana Shopova 	}
62709cbe818SShteryana Shopova 
62809cbe818SShteryana Shopova 	free(chaninfo);
62909cbe818SShteryana Shopova 	return (0);
63009cbe818SShteryana Shopova error:
63109cbe818SShteryana Shopova 	wif->nchannels = 0;
63209cbe818SShteryana Shopova 	free(chaninfo);
63309cbe818SShteryana Shopova 	return (-1);
63409cbe818SShteryana Shopova }
63509cbe818SShteryana Shopova 
63609cbe818SShteryana Shopova static enum WlanIfPhyMode
wlan_channel_flags_to_snmp_phy(uint32_t cflags)63709cbe818SShteryana Shopova wlan_channel_flags_to_snmp_phy(uint32_t cflags)
63809cbe818SShteryana Shopova {
63909cbe818SShteryana Shopova 	/* XXX: recheck */
64009cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_A) != 0)
64109cbe818SShteryana Shopova 		return (WlanIfPhyMode_dot11a);
64209cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_B) != 0)
64309cbe818SShteryana Shopova 		return (WlanIfPhyMode_dot11b);
64409cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_G) != 0 ||
64509cbe818SShteryana Shopova 	    (cflags & IEEE80211_CHAN_PUREG) != 0)
64609cbe818SShteryana Shopova 		return (WlanIfPhyMode_dot11g);
64709cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_FHSS) != 0)
64809cbe818SShteryana Shopova 		return (WlanIfPhyMode_fh);
64909cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_TURBO) != 0 &&
65009cbe818SShteryana Shopova 	    (cflags & IEEE80211_CHAN_A) != 0)
65109cbe818SShteryana Shopova 		return (WlanIfPhyMode_turboA);
65209cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_TURBO) != 0 &&
65309cbe818SShteryana Shopova 	    (cflags & IEEE80211_CHAN_G) != 0)
65409cbe818SShteryana Shopova 		return (WlanIfPhyMode_turboG);
65509cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_STURBO) != 0)
65609cbe818SShteryana Shopova 		return (WlanIfPhyMode_sturboA);
65709cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_HALF) != 0)
65809cbe818SShteryana Shopova 		return (WlanIfPhyMode_ofdmHalf);
65909cbe818SShteryana Shopova 	if ((cflags & IEEE80211_CHAN_QUARTER) != 0)
66009cbe818SShteryana Shopova 		return (WlanIfPhyMode_ofdmQuarter);
66109cbe818SShteryana Shopova 
66209cbe818SShteryana Shopova 	return (WlanIfPhyMode_auto);
66309cbe818SShteryana Shopova }
66409cbe818SShteryana Shopova 
66509cbe818SShteryana Shopova int
wlan_get_roam_params(struct wlan_iface * wif)66609cbe818SShteryana Shopova wlan_get_roam_params(struct wlan_iface *wif)
66709cbe818SShteryana Shopova {
66809cbe818SShteryana Shopova 	int val = 0;
66909cbe818SShteryana Shopova 	size_t argsize;
67009cbe818SShteryana Shopova 
67109cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211_roamparams_req);
67209cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_ROAM, &val,
67309cbe818SShteryana Shopova 	    &wif->roamparams, &argsize, 0) < 0)
67409cbe818SShteryana Shopova 		return (-1);
67509cbe818SShteryana Shopova 
67609cbe818SShteryana Shopova 	return (0);
67709cbe818SShteryana Shopova }
67809cbe818SShteryana Shopova 
67909cbe818SShteryana Shopova int
wlan_get_tx_params(struct wlan_iface * wif)68009cbe818SShteryana Shopova wlan_get_tx_params(struct wlan_iface *wif)
68109cbe818SShteryana Shopova {
68209cbe818SShteryana Shopova 	int val = 0;
68309cbe818SShteryana Shopova 	size_t argsize;
68409cbe818SShteryana Shopova 
68509cbe818SShteryana Shopova 	/*
68609cbe818SShteryana Shopova 	 * XXX: Reset IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA
68709cbe818SShteryana Shopova 	 * and IEEE80211_MODE_11NG modes.
68809cbe818SShteryana Shopova 	 */
68909cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211_txparams_req);
69009cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val,
69109cbe818SShteryana Shopova 	    &wif->txparams, &argsize, 0) < 0)
69209cbe818SShteryana Shopova 		return (-1);
69309cbe818SShteryana Shopova 
69409cbe818SShteryana Shopova 	return (0);
69509cbe818SShteryana Shopova }
69609cbe818SShteryana Shopova 
69709cbe818SShteryana Shopova int
wlan_set_tx_params(struct wlan_iface * wif,int32_t pmode __unused)69809cbe818SShteryana Shopova wlan_set_tx_params(struct wlan_iface *wif, int32_t pmode __unused)
69909cbe818SShteryana Shopova {
70009cbe818SShteryana Shopova 	int val = 0;
70109cbe818SShteryana Shopova 	size_t argsize;
70209cbe818SShteryana Shopova 
70309cbe818SShteryana Shopova 	/*
70409cbe818SShteryana Shopova 	 * XXX: Set IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA
70509cbe818SShteryana Shopova 	 * and IEEE80211_MODE_11NG modes.
70609cbe818SShteryana Shopova 	 */
70709cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211_txparams_req);
70809cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val,
70909cbe818SShteryana Shopova 	    &wif->txparams, &argsize, 1) < 0)
71009cbe818SShteryana Shopova 		return (-1);
71109cbe818SShteryana Shopova 
71209cbe818SShteryana Shopova 	return (0);
71309cbe818SShteryana Shopova }
71409cbe818SShteryana Shopova 
71509cbe818SShteryana Shopova int
wlan_clone_create(struct wlan_iface * wif)71609cbe818SShteryana Shopova wlan_clone_create(struct wlan_iface *wif)
71709cbe818SShteryana Shopova {
71809cbe818SShteryana Shopova 	struct ifreq ifr;
71909cbe818SShteryana Shopova 	struct ieee80211_clone_params wcp;
72009cbe818SShteryana Shopova 	static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
72109cbe818SShteryana Shopova 
72209cbe818SShteryana Shopova 	memset(&wcp, 0, sizeof(wcp));
72309cbe818SShteryana Shopova 	memset(&ifr, 0, sizeof(ifr));
72409cbe818SShteryana Shopova 
72509cbe818SShteryana Shopova 	/* Sanity checks. */
72609cbe818SShteryana Shopova 	if (wif == NULL || wif->pname[0] == '\0' || wif->mode > WLAN_IFMODE_MAX)
72709cbe818SShteryana Shopova 		return (SNMP_ERR_INCONS_VALUE);
72809cbe818SShteryana Shopova 
72909cbe818SShteryana Shopova 	if (wif->mode == WlanIfaceOperatingModeType_wds &&
73009cbe818SShteryana Shopova 	    memcmp(wif->dbssid, zerobssid, IEEE80211_ADDR_LEN) == 0)
73109cbe818SShteryana Shopova 		return (SNMP_ERR_INCONS_VALUE);
73209cbe818SShteryana Shopova 
73309cbe818SShteryana Shopova 	strlcpy(wcp.icp_parent, wif->pname, IFNAMSIZ);
73409cbe818SShteryana Shopova 	if ((wif->flags & WlanIfaceFlagsType_uniqueBssid) != 0)
73509cbe818SShteryana Shopova 		wcp.icp_flags |= IEEE80211_CLONE_BSSID;
73609cbe818SShteryana Shopova 	if ((wif->flags & WlanIfaceFlagsType_noBeacons) != 0)
73709cbe818SShteryana Shopova 		wcp.icp_flags |= IEEE80211_CLONE_NOBEACONS;
73809cbe818SShteryana Shopova 	if (wif->mode == WlanIfaceOperatingModeType_wds &&
73909cbe818SShteryana Shopova 	    (wif->flags & WlanIfaceFlagsType_wdsLegacy) != 0)
74009cbe818SShteryana Shopova 		wcp.icp_flags |= IEEE80211_CLONE_WDSLEGACY;
74109cbe818SShteryana Shopova 
74209cbe818SShteryana Shopova 	switch (wif->mode) {
74309cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_ibss:
74409cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_IBSS;
74509cbe818SShteryana Shopova 		break;
74609cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_station:
74709cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_STA;
74809cbe818SShteryana Shopova 		break;
74909cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_wds:
75009cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_WDS;
75109cbe818SShteryana Shopova 		break;
75209cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_adhocDemo:
75309cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_AHDEMO;
75409cbe818SShteryana Shopova 		break;
75509cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_hostAp:
75609cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_HOSTAP;
75709cbe818SShteryana Shopova 		break;
75809cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_monitor:
75909cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_MONITOR;
76009cbe818SShteryana Shopova 		break;
76109cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_meshPoint:
76209cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_MBSS;
76309cbe818SShteryana Shopova 		break;
76409cbe818SShteryana Shopova 	case WlanIfaceOperatingModeType_tdma:
76509cbe818SShteryana Shopova 		wcp.icp_opmode = IEEE80211_M_AHDEMO;
76609cbe818SShteryana Shopova 		wcp.icp_flags |= IEEE80211_CLONE_TDMA;
76709cbe818SShteryana Shopova 		break;
76809cbe818SShteryana Shopova 	}
76909cbe818SShteryana Shopova 
77009cbe818SShteryana Shopova 	memcpy(wcp.icp_bssid, wif->dbssid, IEEE80211_ADDR_LEN);
77109cbe818SShteryana Shopova 	if (memcmp(wif->dlmac, zerobssid, IEEE80211_ADDR_LEN) != 0) {
77209cbe818SShteryana Shopova 		memcpy(wcp.icp_macaddr, wif->dlmac, IEEE80211_ADDR_LEN);
77309cbe818SShteryana Shopova 		wcp.icp_flags |= IEEE80211_CLONE_MACADDR;
77409cbe818SShteryana Shopova 	}
77509cbe818SShteryana Shopova 
77609cbe818SShteryana Shopova 	strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ);
77709cbe818SShteryana Shopova 	ifr.ifr_data = (caddr_t) &wcp;
77809cbe818SShteryana Shopova 
77909cbe818SShteryana Shopova 	if (ioctl(sock, SIOCIFCREATE2, (caddr_t) &ifr) < 0) {
78009cbe818SShteryana Shopova 		syslog(LOG_ERR, "wlan clone create: ioctl(SIOCIFCREATE2) "
78109cbe818SShteryana Shopova 		    "failed: %s", strerror(errno));
78209cbe818SShteryana Shopova 		return (SNMP_ERR_GENERR);
78309cbe818SShteryana Shopova 	}
78409cbe818SShteryana Shopova 
78509cbe818SShteryana Shopova 	return (SNMP_ERR_NOERROR);
78609cbe818SShteryana Shopova }
78709cbe818SShteryana Shopova 
78809cbe818SShteryana Shopova int
wlan_clone_destroy(struct wlan_iface * wif)78909cbe818SShteryana Shopova wlan_clone_destroy(struct wlan_iface *wif)
79009cbe818SShteryana Shopova {
79109cbe818SShteryana Shopova 	struct ifreq ifr;
79209cbe818SShteryana Shopova 
79309cbe818SShteryana Shopova 	if (wif == NULL)
79409cbe818SShteryana Shopova 		return (SNMP_ERR_INCONS_VALUE);
79509cbe818SShteryana Shopova 
79609cbe818SShteryana Shopova 	memset(&ifr, 0, sizeof(ifr));
79709cbe818SShteryana Shopova 	strcpy(ifr.ifr_name, wif->wname);
79809cbe818SShteryana Shopova 
79909cbe818SShteryana Shopova 	if (ioctl(sock, SIOCIFDESTROY, &ifr) < 0) {
80009cbe818SShteryana Shopova 		syslog(LOG_ERR, "wlan clone destroy: ioctl(SIOCIFDESTROY) "
80109cbe818SShteryana Shopova 		    "failed: %s", strerror(errno));
80209cbe818SShteryana Shopova 		return (SNMP_ERR_GENERR);
80309cbe818SShteryana Shopova 	}
80409cbe818SShteryana Shopova 
80509cbe818SShteryana Shopova 	return (SNMP_ERR_NOERROR);
80609cbe818SShteryana Shopova }
80709cbe818SShteryana Shopova 
80809cbe818SShteryana Shopova static int
wlan_config_snmp2ioctl(int which)80909cbe818SShteryana Shopova wlan_config_snmp2ioctl(int which)
81009cbe818SShteryana Shopova {
81109cbe818SShteryana Shopova 	int op;
81209cbe818SShteryana Shopova 
81309cbe818SShteryana Shopova 	switch (which) {
81409cbe818SShteryana Shopova 	case LEAF_wlanIfacePacketBurst:
81509cbe818SShteryana Shopova 		op = IEEE80211_IOC_BURST;
81609cbe818SShteryana Shopova 		break;
81709cbe818SShteryana Shopova 	case LEAF_wlanIfaceCountryCode:
81809cbe818SShteryana Shopova 		op = IEEE80211_IOC_REGDOMAIN;
81909cbe818SShteryana Shopova 		break;
82009cbe818SShteryana Shopova 	case LEAF_wlanIfaceRegDomain:
82109cbe818SShteryana Shopova 		op = IEEE80211_IOC_REGDOMAIN;
82209cbe818SShteryana Shopova 		break;
82309cbe818SShteryana Shopova 	case LEAF_wlanIfaceDesiredSsid:
82409cbe818SShteryana Shopova 		op = IEEE80211_IOC_SSID;
82509cbe818SShteryana Shopova 		break;
82609cbe818SShteryana Shopova 	case LEAF_wlanIfaceDesiredChannel:
82709cbe818SShteryana Shopova 		op = IEEE80211_IOC_CURCHAN;
82809cbe818SShteryana Shopova 		break;
82909cbe818SShteryana Shopova 	case LEAF_wlanIfaceDynamicFreqSelection:
83009cbe818SShteryana Shopova 		op = IEEE80211_IOC_DFS;
83109cbe818SShteryana Shopova 		break;
83209cbe818SShteryana Shopova 	case LEAF_wlanIfaceFastFrames:
83309cbe818SShteryana Shopova 		op = IEEE80211_IOC_FF;
83409cbe818SShteryana Shopova 		break;
83509cbe818SShteryana Shopova 	case LEAF_wlanIfaceDturbo:
83609cbe818SShteryana Shopova 		op = IEEE80211_IOC_TURBOP;
83709cbe818SShteryana Shopova 		break;
83809cbe818SShteryana Shopova 	case LEAF_wlanIfaceTxPower:
83909cbe818SShteryana Shopova 		op = IEEE80211_IOC_TXPOWER;
84009cbe818SShteryana Shopova 		break;
84109cbe818SShteryana Shopova 	case LEAF_wlanIfaceFragmentThreshold:
84209cbe818SShteryana Shopova 		op = IEEE80211_IOC_FRAGTHRESHOLD;
84309cbe818SShteryana Shopova 		break;
84409cbe818SShteryana Shopova 	case LEAF_wlanIfaceRTSThreshold:
84509cbe818SShteryana Shopova 		op = IEEE80211_IOC_RTSTHRESHOLD;
84609cbe818SShteryana Shopova 		break;
84709cbe818SShteryana Shopova 	case LEAF_wlanIfaceWlanPrivacySubscribe:
84809cbe818SShteryana Shopova 		op = IEEE80211_IOC_WPS;
84909cbe818SShteryana Shopova 		break;
85009cbe818SShteryana Shopova 	case LEAF_wlanIfaceBgScan:
85109cbe818SShteryana Shopova 		op = IEEE80211_IOC_BGSCAN;
85209cbe818SShteryana Shopova 		break;
85309cbe818SShteryana Shopova 	case LEAF_wlanIfaceBgScanIdle:
85409cbe818SShteryana Shopova 		op = IEEE80211_IOC_BGSCAN_IDLE;
85509cbe818SShteryana Shopova 		break;
85609cbe818SShteryana Shopova 	case LEAF_wlanIfaceBgScanInterval:
85709cbe818SShteryana Shopova 		op = IEEE80211_IOC_BGSCAN_INTERVAL;
85809cbe818SShteryana Shopova 		break;
85909cbe818SShteryana Shopova 	case LEAF_wlanIfaceBeaconMissedThreshold:
86009cbe818SShteryana Shopova 		op = IEEE80211_IOC_BMISSTHRESHOLD;
86109cbe818SShteryana Shopova 		break;
86209cbe818SShteryana Shopova 	case LEAF_wlanIfaceDesiredBssid:
86309cbe818SShteryana Shopova 		op = IEEE80211_IOC_BSSID;
86409cbe818SShteryana Shopova 		break;
86509cbe818SShteryana Shopova 	case LEAF_wlanIfaceRoamingMode:
86609cbe818SShteryana Shopova 		op = IEEE80211_IOC_ROAMING;
86709cbe818SShteryana Shopova 		break;
86809cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11d:
86909cbe818SShteryana Shopova 		op = IEEE80211_IOC_DOTD;
87009cbe818SShteryana Shopova 		break;
87109cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11h:
87209cbe818SShteryana Shopova 		op = IEEE80211_IOC_DOTH;
87309cbe818SShteryana Shopova 		break;
87409cbe818SShteryana Shopova 	case LEAF_wlanIfaceDynamicWds:
87509cbe818SShteryana Shopova 		op = IEEE80211_IOC_DWDS;
87609cbe818SShteryana Shopova 		break;
87709cbe818SShteryana Shopova 	case LEAF_wlanIfacePowerSave:
87809cbe818SShteryana Shopova 		op = IEEE80211_IOC_POWERSAVE;
87909cbe818SShteryana Shopova 		break;
88009cbe818SShteryana Shopova 	case LEAF_wlanIfaceApBridge:
88109cbe818SShteryana Shopova 		op = IEEE80211_IOC_APBRIDGE;
88209cbe818SShteryana Shopova 		break;
88309cbe818SShteryana Shopova 	case LEAF_wlanIfaceBeaconInterval:
88409cbe818SShteryana Shopova 		op = IEEE80211_IOC_BEACON_INTERVAL;
88509cbe818SShteryana Shopova 		break;
88609cbe818SShteryana Shopova 	case LEAF_wlanIfaceDtimPeriod:
88709cbe818SShteryana Shopova 		op = IEEE80211_IOC_DTIM_PERIOD;
88809cbe818SShteryana Shopova 		break;
88909cbe818SShteryana Shopova 	case LEAF_wlanIfaceHideSsid:
89009cbe818SShteryana Shopova 		op = IEEE80211_IOC_HIDESSID;
89109cbe818SShteryana Shopova 		break;
89209cbe818SShteryana Shopova 	case LEAF_wlanIfaceInactivityProccess:
89309cbe818SShteryana Shopova 		op = IEEE80211_IOC_INACTIVITY;
89409cbe818SShteryana Shopova 		break;
89509cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11gProtMode:
89609cbe818SShteryana Shopova 		op = IEEE80211_IOC_PROTMODE;
89709cbe818SShteryana Shopova 		break;
89809cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11gPureMode:
89909cbe818SShteryana Shopova 		op = IEEE80211_IOC_PUREG;
90009cbe818SShteryana Shopova 		break;
90109cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nPureMode:
90209cbe818SShteryana Shopova 		op = IEEE80211_IOC_PUREN;
90309cbe818SShteryana Shopova 		break;
90409cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nAmpdu:
90509cbe818SShteryana Shopova 		op = IEEE80211_IOC_AMPDU;
90609cbe818SShteryana Shopova 		break;
90709cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nAmpduDensity:
90809cbe818SShteryana Shopova 		op = IEEE80211_IOC_AMPDU_DENSITY;
90909cbe818SShteryana Shopova 		break;
91009cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nAmpduLimit:
91109cbe818SShteryana Shopova 		op = IEEE80211_IOC_AMPDU_LIMIT;
91209cbe818SShteryana Shopova 		break;
91309cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nAmsdu:
91409cbe818SShteryana Shopova 		op = IEEE80211_IOC_AMSDU;
91509cbe818SShteryana Shopova 		break;
91609cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nAmsduLimit:
91709cbe818SShteryana Shopova 		op = IEEE80211_IOC_AMSDU_LIMIT;
91809cbe818SShteryana Shopova 		break;
91909cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nHighThroughput:
92009cbe818SShteryana Shopova 		op = IEEE80211_IOC_HTCONF;
92109cbe818SShteryana Shopova 		break;
92209cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nHTCompatible:
92309cbe818SShteryana Shopova 		op = IEEE80211_IOC_HTCOMPAT;
92409cbe818SShteryana Shopova 		break;
92509cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nHTProtMode:
92609cbe818SShteryana Shopova 		op = IEEE80211_IOC_HTPROTMODE;
92709cbe818SShteryana Shopova 		break;
92809cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nRIFS:
92909cbe818SShteryana Shopova 		op = IEEE80211_IOC_RIFS;
93009cbe818SShteryana Shopova 		break;
93109cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nShortGI:
93209cbe818SShteryana Shopova 		op = IEEE80211_IOC_SHORTGI;
93309cbe818SShteryana Shopova 		break;
93409cbe818SShteryana Shopova 	case LEAF_wlanIfaceDot11nSMPSMode:
93509cbe818SShteryana Shopova 		op = IEEE80211_IOC_SMPS;
93609cbe818SShteryana Shopova 		break;
93709cbe818SShteryana Shopova 	case LEAF_wlanIfaceTdmaSlot:
93809cbe818SShteryana Shopova 		op = IEEE80211_IOC_TDMA_SLOT;
93909cbe818SShteryana Shopova 		break;
94009cbe818SShteryana Shopova 	case LEAF_wlanIfaceTdmaSlotCount:
94109cbe818SShteryana Shopova 		op = IEEE80211_IOC_TDMA_SLOTCNT;
94209cbe818SShteryana Shopova 		break;
94309cbe818SShteryana Shopova 	case LEAF_wlanIfaceTdmaSlotLength:
94409cbe818SShteryana Shopova 		op = IEEE80211_IOC_TDMA_SLOTLEN;
94509cbe818SShteryana Shopova 		break;
94609cbe818SShteryana Shopova 	case LEAF_wlanIfaceTdmaBeaconInterval:
94709cbe818SShteryana Shopova 		op = IEEE80211_IOC_TDMA_BINTERVAL;
94809cbe818SShteryana Shopova 		break;
94909cbe818SShteryana Shopova 	default:
95009cbe818SShteryana Shopova 		op = -1;
95109cbe818SShteryana Shopova 	}
95209cbe818SShteryana Shopova 
95309cbe818SShteryana Shopova 	return (op);
95409cbe818SShteryana Shopova }
95509cbe818SShteryana Shopova 
95609cbe818SShteryana Shopova static enum WlanRegDomainCode
wlan_regdomain_to_snmp(int which)95709cbe818SShteryana Shopova wlan_regdomain_to_snmp(int which)
95809cbe818SShteryana Shopova {
95909cbe818SShteryana Shopova 	enum WlanRegDomainCode reg_domain;
96009cbe818SShteryana Shopova 
96109cbe818SShteryana Shopova 	switch (which) {
96209cbe818SShteryana Shopova 	case SKU_FCC:
96309cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_fcc;
96409cbe818SShteryana Shopova 		break;
96509cbe818SShteryana Shopova 	case SKU_CA:
96609cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_ca;
96709cbe818SShteryana Shopova 		break;
96809cbe818SShteryana Shopova 	case SKU_ETSI:
96909cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_etsi;
97009cbe818SShteryana Shopova 		break;
97109cbe818SShteryana Shopova 	case SKU_ETSI2:
97209cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_etsi2;
97309cbe818SShteryana Shopova 		break;
97409cbe818SShteryana Shopova 	case SKU_ETSI3:
97509cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_etsi3;
97609cbe818SShteryana Shopova 		break;
97709cbe818SShteryana Shopova 	case SKU_FCC3:
97809cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_fcc3;
97909cbe818SShteryana Shopova 		break;
98009cbe818SShteryana Shopova 	case SKU_JAPAN:
98109cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_japan;
98209cbe818SShteryana Shopova 		break;
98309cbe818SShteryana Shopova 	case SKU_KOREA:
98409cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_korea;
98509cbe818SShteryana Shopova 		break;
98609cbe818SShteryana Shopova 	case SKU_APAC:
98709cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_apac;
98809cbe818SShteryana Shopova 		break;
98909cbe818SShteryana Shopova 	case SKU_APAC2:
99009cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_apac2;
99109cbe818SShteryana Shopova 		break;
99209cbe818SShteryana Shopova 	case SKU_APAC3:
99309cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_apac3;
99409cbe818SShteryana Shopova 		break;
99509cbe818SShteryana Shopova 	case SKU_ROW:
99609cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_row;
99709cbe818SShteryana Shopova 		break;
99809cbe818SShteryana Shopova 	case SKU_NONE:
99909cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_none;
100009cbe818SShteryana Shopova 		break;
100109cbe818SShteryana Shopova 	case SKU_DEBUG:
100209cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_debug;
100309cbe818SShteryana Shopova 		break;
100409cbe818SShteryana Shopova 	case SKU_SR9:
100509cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_sr9;
100609cbe818SShteryana Shopova 		break;
100709cbe818SShteryana Shopova 	case SKU_XR9:
100809cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_xr9;
100909cbe818SShteryana Shopova 		break;
101009cbe818SShteryana Shopova 	case SKU_GZ901:
101109cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_gz901;
101209cbe818SShteryana Shopova 		break;
101309cbe818SShteryana Shopova 	case 0:
101409cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_none;
101509cbe818SShteryana Shopova 		break;
101609cbe818SShteryana Shopova 	default:
101709cbe818SShteryana Shopova 		syslog(LOG_ERR, "unknown regdomain (0x%x) ", which);
101809cbe818SShteryana Shopova 		reg_domain = WlanRegDomainCode_none;
101909cbe818SShteryana Shopova 		break;
102009cbe818SShteryana Shopova 	}
102109cbe818SShteryana Shopova 
102209cbe818SShteryana Shopova 	return (reg_domain);
102309cbe818SShteryana Shopova }
102409cbe818SShteryana Shopova 
102509cbe818SShteryana Shopova static int
wlan_snmp_to_regdomain(enum WlanRegDomainCode regdomain)102609cbe818SShteryana Shopova wlan_snmp_to_regdomain(enum WlanRegDomainCode regdomain)
102709cbe818SShteryana Shopova {
102809cbe818SShteryana Shopova 	int which;
102909cbe818SShteryana Shopova 
103009cbe818SShteryana Shopova 	switch (regdomain) {
103109cbe818SShteryana Shopova 	case WlanRegDomainCode_fcc:
103209cbe818SShteryana Shopova 		which = SKU_FCC;
103309cbe818SShteryana Shopova 		break;
103409cbe818SShteryana Shopova 	case WlanRegDomainCode_ca:
103509cbe818SShteryana Shopova 		which = SKU_CA;
103609cbe818SShteryana Shopova 		break;
103709cbe818SShteryana Shopova 	case WlanRegDomainCode_etsi:
103809cbe818SShteryana Shopova 		which = SKU_ETSI;
103909cbe818SShteryana Shopova 		break;
104009cbe818SShteryana Shopova 	case WlanRegDomainCode_etsi2:
104109cbe818SShteryana Shopova 		which = SKU_ETSI2;
104209cbe818SShteryana Shopova 		break;
104309cbe818SShteryana Shopova 	case WlanRegDomainCode_etsi3:
104409cbe818SShteryana Shopova 		which = SKU_ETSI3;
104509cbe818SShteryana Shopova 		break;
104609cbe818SShteryana Shopova 	case WlanRegDomainCode_fcc3:
104709cbe818SShteryana Shopova 		which = SKU_FCC3;
104809cbe818SShteryana Shopova 		break;
104909cbe818SShteryana Shopova 	case WlanRegDomainCode_japan:
105009cbe818SShteryana Shopova 		which = SKU_JAPAN;
105109cbe818SShteryana Shopova 		break;
105209cbe818SShteryana Shopova 	case WlanRegDomainCode_korea:
105309cbe818SShteryana Shopova 		which = SKU_KOREA;
105409cbe818SShteryana Shopova 		break;
105509cbe818SShteryana Shopova 	case WlanRegDomainCode_apac:
105609cbe818SShteryana Shopova 		which = SKU_APAC;
105709cbe818SShteryana Shopova 		break;
105809cbe818SShteryana Shopova 	case WlanRegDomainCode_apac2:
105909cbe818SShteryana Shopova 		which = SKU_APAC2;
106009cbe818SShteryana Shopova 		break;
106109cbe818SShteryana Shopova 	case WlanRegDomainCode_apac3:
106209cbe818SShteryana Shopova 		which = SKU_APAC3;
106309cbe818SShteryana Shopova 		break;
106409cbe818SShteryana Shopova 	case WlanRegDomainCode_row:
106509cbe818SShteryana Shopova 		which = SKU_ROW;
106609cbe818SShteryana Shopova 		break;
106709cbe818SShteryana Shopova 	case WlanRegDomainCode_none:
106809cbe818SShteryana Shopova 		which = SKU_NONE;
106909cbe818SShteryana Shopova 		break;
107009cbe818SShteryana Shopova 	case WlanRegDomainCode_debug:
107109cbe818SShteryana Shopova 		which = SKU_DEBUG;
107209cbe818SShteryana Shopova 		break;
107309cbe818SShteryana Shopova 	case WlanRegDomainCode_sr9:
107409cbe818SShteryana Shopova 		which = SKU_SR9;
107509cbe818SShteryana Shopova 		break;
107609cbe818SShteryana Shopova 	case WlanRegDomainCode_xr9:
107709cbe818SShteryana Shopova 		which = SKU_XR9;
107809cbe818SShteryana Shopova 		break;
107909cbe818SShteryana Shopova 	case WlanRegDomainCode_gz901:
108009cbe818SShteryana Shopova 		which = SKU_GZ901;
108109cbe818SShteryana Shopova 		break;
108209cbe818SShteryana Shopova 	default:
108309cbe818SShteryana Shopova 		syslog(LOG_ERR, "unknown snmp regdomain (0x%x) ", regdomain);
108409cbe818SShteryana Shopova 		which = SKU_NONE;
108509cbe818SShteryana Shopova 		break;
108609cbe818SShteryana Shopova 	}
108709cbe818SShteryana Shopova 
108809cbe818SShteryana Shopova 	return (which);
108909cbe818SShteryana Shopova }
109009cbe818SShteryana Shopova 
109109cbe818SShteryana Shopova static int
wlan_config_get_country(struct wlan_iface * wif)109209cbe818SShteryana Shopova wlan_config_get_country(struct wlan_iface *wif)
109309cbe818SShteryana Shopova {
109409cbe818SShteryana Shopova 	int val = 0;
109509cbe818SShteryana Shopova 	size_t argsize;
109609cbe818SShteryana Shopova 	struct ieee80211_regdomain regdomain;
109709cbe818SShteryana Shopova 
109809cbe818SShteryana Shopova 	memset(&regdomain, 0, sizeof(regdomain));
109909cbe818SShteryana Shopova 	argsize = sizeof(regdomain);
110009cbe818SShteryana Shopova 
110109cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, &regdomain,
110209cbe818SShteryana Shopova 	    &argsize, 0) < 0)
110309cbe818SShteryana Shopova 		return (-1);
110409cbe818SShteryana Shopova 
110509cbe818SShteryana Shopova 	wif->reg_domain = wlan_regdomain_to_snmp(regdomain.regdomain);
110609cbe818SShteryana Shopova 	wif->country_code[0] = regdomain.isocc[0];
110709cbe818SShteryana Shopova 	wif->country_code[1] = regdomain.isocc[1];
110809cbe818SShteryana Shopova 	wif->country_code[2] = regdomain.location;
110909cbe818SShteryana Shopova 
111009cbe818SShteryana Shopova 	return (0);
111109cbe818SShteryana Shopova }
111209cbe818SShteryana Shopova 
111309cbe818SShteryana Shopova static int
wlan_config_set_country(struct wlan_iface * wif,char * ccode,int rdomain)111409cbe818SShteryana Shopova wlan_config_set_country(struct wlan_iface *wif, char *ccode, int rdomain)
111509cbe818SShteryana Shopova {
111609cbe818SShteryana Shopova 	int val = 0, txpowermax;
111709cbe818SShteryana Shopova 	uint32_t i;
111809cbe818SShteryana Shopova 	size_t argsize = 0;
111909cbe818SShteryana Shopova 	struct ieee80211_regdomain_req *regdomain;
112009cbe818SShteryana Shopova 
112109cbe818SShteryana Shopova 	if (wlan_get_channel_list(wif) < 0)
112209cbe818SShteryana Shopova 		return (-1);
112309cbe818SShteryana Shopova 
112409cbe818SShteryana Shopova 	if (wif->nchannels == 0) {
112509cbe818SShteryana Shopova 		syslog(LOG_ERR, "iface %s - set regdomain failed", wif->wname);
112609cbe818SShteryana Shopova 		return (-1);
112709cbe818SShteryana Shopova 	}
112809cbe818SShteryana Shopova 
112909cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPOWMAX, &txpowermax, 0,
113009cbe818SShteryana Shopova 	    &argsize, 0) < 0)
113109cbe818SShteryana Shopova 		return (-1);
113209cbe818SShteryana Shopova 
113309cbe818SShteryana Shopova 	regdomain = malloc(IEEE80211_REGDOMAIN_SIZE(wif->nchannels));
113409cbe818SShteryana Shopova 	if (regdomain == NULL)
113509cbe818SShteryana Shopova 		return (-1);
113609cbe818SShteryana Shopova 	memset(regdomain, 0, IEEE80211_REGDOMAIN_SIZE(wif->nchannels));
113709cbe818SShteryana Shopova 	argsize = IEEE80211_REGDOMAIN_SIZE(wif->nchannels);
113809cbe818SShteryana Shopova 
113909cbe818SShteryana Shopova 	/* XXX: recheck with how this is done by ifconfig(8) */
114009cbe818SShteryana Shopova 	regdomain->rd.regdomain = wlan_snmp_to_regdomain(rdomain);
114109cbe818SShteryana Shopova 	regdomain->rd.isocc[0] = ccode[0];
114209cbe818SShteryana Shopova 	regdomain->rd.isocc[1] = ccode[1];
114309cbe818SShteryana Shopova 	regdomain->rd.location = ccode[2];
114409cbe818SShteryana Shopova 
114509cbe818SShteryana Shopova 	/* XXX: fill the channel list properly */
114609cbe818SShteryana Shopova 	regdomain->chaninfo.ic_nchans = wif->nchannels;
114709cbe818SShteryana Shopova 	memcpy(regdomain->chaninfo.ic_chans, wif->chanlist,
114809cbe818SShteryana Shopova 	    wif->nchannels * sizeof(struct ieee80211_channel));
114909cbe818SShteryana Shopova 	for (i = 0; i < wif->nchannels; i++)
115009cbe818SShteryana Shopova 		regdomain->chaninfo.ic_chans[i].ic_maxregpower = txpowermax;
115109cbe818SShteryana Shopova 
115209cbe818SShteryana Shopova 	wif->state = wlanIfaceState_down;
115309cbe818SShteryana Shopova 	if (wlan_config_state(wif, 1) < 0 ||
115409cbe818SShteryana Shopova 	    wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, regdomain,
115509cbe818SShteryana Shopova 	    &argsize, 1) < 0) {
115609cbe818SShteryana Shopova 		free(regdomain);
115709cbe818SShteryana Shopova 		return (-1);
115809cbe818SShteryana Shopova 	}
115909cbe818SShteryana Shopova 
116009cbe818SShteryana Shopova 	wif->state = wlanIfaceState_up;
116109cbe818SShteryana Shopova 	(void)wlan_config_state(wif, 1);
116209cbe818SShteryana Shopova 	wif->reg_domain = wlan_regdomain_to_snmp(regdomain->rd.regdomain);
116309cbe818SShteryana Shopova 	wif->country_code[0] = regdomain->rd.isocc[0];
116409cbe818SShteryana Shopova 	wif->country_code[1] = regdomain->rd.isocc[1];
116509cbe818SShteryana Shopova 	wif->country_code[2] = regdomain->rd.location;
116609cbe818SShteryana Shopova 	free(regdomain);
116709cbe818SShteryana Shopova 
116809cbe818SShteryana Shopova 	return (0);
116909cbe818SShteryana Shopova }
117009cbe818SShteryana Shopova 
117109cbe818SShteryana Shopova int
wlan_config_get_dssid(struct wlan_iface * wif)117209cbe818SShteryana Shopova wlan_config_get_dssid(struct wlan_iface *wif)
117309cbe818SShteryana Shopova {
117409cbe818SShteryana Shopova 	int val = -1;
117509cbe818SShteryana Shopova 	size_t argsize = IEEE80211_NWID_LEN + 1;
117609cbe818SShteryana Shopova 	char ssid[IEEE80211_NWID_LEN + 1];
117709cbe818SShteryana Shopova 
117809cbe818SShteryana Shopova 	memset(ssid, 0, IEEE80211_NWID_LEN + 1);
117909cbe818SShteryana Shopova 
118009cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname,
118109cbe818SShteryana Shopova 	    (wif->mode == WlanIfaceOperatingModeType_meshPoint) ?
118209cbe818SShteryana Shopova 	    IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid,
118309cbe818SShteryana Shopova 	    &argsize, 0) < 0)
118409cbe818SShteryana Shopova 		return (-1);
118509cbe818SShteryana Shopova 
118609cbe818SShteryana Shopova 	if (argsize > IEEE80211_NWID_LEN)
118709cbe818SShteryana Shopova 		argsize = IEEE80211_NWID_LEN;
118809cbe818SShteryana Shopova 	memcpy(wif->desired_ssid, ssid, argsize);
118909cbe818SShteryana Shopova 	wif->desired_ssid[argsize] = '\0';
119009cbe818SShteryana Shopova 
119109cbe818SShteryana Shopova 	return (0);
119209cbe818SShteryana Shopova }
119309cbe818SShteryana Shopova 
119409cbe818SShteryana Shopova int
wlan_config_set_dssid(struct wlan_iface * wif,char * ssid,int slen)119509cbe818SShteryana Shopova wlan_config_set_dssid(struct wlan_iface *wif, char *ssid, int slen)
119609cbe818SShteryana Shopova {
119709cbe818SShteryana Shopova 	int val = 0;
119809cbe818SShteryana Shopova 	size_t argsize = slen;
119909cbe818SShteryana Shopova 
120009cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname,
120109cbe818SShteryana Shopova 	    (wif->mode == WlanIfaceOperatingModeType_meshPoint) ?
120209cbe818SShteryana Shopova 	    IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid,
120309cbe818SShteryana Shopova 	    &argsize, 1) < 0)
120409cbe818SShteryana Shopova 		return (-1);
120509cbe818SShteryana Shopova 
120609cbe818SShteryana Shopova 	if (argsize > IEEE80211_NWID_LEN)
120709cbe818SShteryana Shopova 		argsize = IEEE80211_NWID_LEN;
120809cbe818SShteryana Shopova 	memcpy(wif->desired_ssid, ssid, argsize);
120909cbe818SShteryana Shopova 	wif->desired_ssid[argsize] = '\0';
121009cbe818SShteryana Shopova 
121109cbe818SShteryana Shopova 	return (0);
121209cbe818SShteryana Shopova }
121309cbe818SShteryana Shopova 
121409cbe818SShteryana Shopova static int
wlan_config_get_dchannel(struct wlan_iface * wif)121509cbe818SShteryana Shopova wlan_config_get_dchannel(struct wlan_iface *wif)
121609cbe818SShteryana Shopova {
121709cbe818SShteryana Shopova 	uint32_t i = 0;
121809cbe818SShteryana Shopova 	int val = 0;
121909cbe818SShteryana Shopova 	size_t argsize = sizeof(struct ieee80211_channel);
122009cbe818SShteryana Shopova 	struct ieee80211_channel chan;
122109cbe818SShteryana Shopova 
122209cbe818SShteryana Shopova 	if (wlan_get_channel_list(wif) < 0)
122309cbe818SShteryana Shopova 		return (-1);
122409cbe818SShteryana Shopova 
122509cbe818SShteryana Shopova 	memset(&chan, 0, sizeof(chan));
122609cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan,
122709cbe818SShteryana Shopova 	    &argsize, 0) < 0)
122809cbe818SShteryana Shopova 		return (-1);
122909cbe818SShteryana Shopova 
123009cbe818SShteryana Shopova 	for (i = 0; i < wif->nchannels; i++)
123109cbe818SShteryana Shopova 		if (chan.ic_ieee == wif->chanlist[i].ic_ieee &&
123209cbe818SShteryana Shopova 		    chan.ic_flags == wif->chanlist[i].ic_flags) {
123309cbe818SShteryana Shopova 			wif->desired_channel = i + 1;
123409cbe818SShteryana Shopova 			break;
123509cbe818SShteryana Shopova 		}
123609cbe818SShteryana Shopova 
123709cbe818SShteryana Shopova 	return (0);
123809cbe818SShteryana Shopova }
123909cbe818SShteryana Shopova 
124009cbe818SShteryana Shopova static int
wlan_config_set_dchannel(struct wlan_iface * wif,uint32_t dchannel)124109cbe818SShteryana Shopova wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t dchannel)
124209cbe818SShteryana Shopova {
124309cbe818SShteryana Shopova 	int val = 0;
124409cbe818SShteryana Shopova 	size_t argsize = sizeof(struct ieee80211_channel);
124509cbe818SShteryana Shopova 	struct ieee80211_channel chan;
124609cbe818SShteryana Shopova 
124709cbe818SShteryana Shopova 	if (wlan_get_channel_list(wif) < 0)
124809cbe818SShteryana Shopova 		return (-1);
124909cbe818SShteryana Shopova 
125009cbe818SShteryana Shopova 	if (dchannel > wif->nchannels)
125109cbe818SShteryana Shopova 		return (-1);
125209cbe818SShteryana Shopova 
125309cbe818SShteryana Shopova 	memcpy(&chan, wif->chanlist + dchannel - 1, sizeof(chan));
125409cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan,
125509cbe818SShteryana Shopova 	    &argsize, 1) < 0)
125609cbe818SShteryana Shopova 		return (-1);
125709cbe818SShteryana Shopova 
125809cbe818SShteryana Shopova 	wif->desired_channel = dchannel;
125909cbe818SShteryana Shopova 
126009cbe818SShteryana Shopova 	return (0);
126109cbe818SShteryana Shopova }
126209cbe818SShteryana Shopova 
126309cbe818SShteryana Shopova static int
wlan_config_get_bssid(struct wlan_iface * wif)126409cbe818SShteryana Shopova wlan_config_get_bssid(struct wlan_iface *wif)
126509cbe818SShteryana Shopova {
126609cbe818SShteryana Shopova 	int val = 0;
126709cbe818SShteryana Shopova 	size_t argsize = IEEE80211_ADDR_LEN;
126809cbe818SShteryana Shopova 	char bssid[IEEE80211_ADDR_LEN];
126909cbe818SShteryana Shopova 
127009cbe818SShteryana Shopova 	memset(bssid, 0, IEEE80211_ADDR_LEN);
127109cbe818SShteryana Shopova 
127209cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid,
127309cbe818SShteryana Shopova 	    &argsize, 0) < 0 || argsize != IEEE80211_ADDR_LEN)
127409cbe818SShteryana Shopova 		return (-1);
127509cbe818SShteryana Shopova 
127609cbe818SShteryana Shopova 	memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN);
127709cbe818SShteryana Shopova 
127809cbe818SShteryana Shopova 	return (0);
127909cbe818SShteryana Shopova }
128009cbe818SShteryana Shopova 
128109cbe818SShteryana Shopova static int
wlan_config_set_bssid(struct wlan_iface * wif,uint8_t * bssid)128209cbe818SShteryana Shopova wlan_config_set_bssid(struct wlan_iface *wif, uint8_t *bssid)
128309cbe818SShteryana Shopova {
128409cbe818SShteryana Shopova 	int val = 0;
128509cbe818SShteryana Shopova 	size_t argsize = IEEE80211_ADDR_LEN;
128609cbe818SShteryana Shopova 
128709cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid,
128809cbe818SShteryana Shopova 	    &argsize, 1) < 0 || argsize != IEEE80211_ADDR_LEN)
128909cbe818SShteryana Shopova 		return (-1);
129009cbe818SShteryana Shopova 
129109cbe818SShteryana Shopova 	memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN);
129209cbe818SShteryana Shopova 
129309cbe818SShteryana Shopova 	return (0);
129409cbe818SShteryana Shopova }
129509cbe818SShteryana Shopova 
129609cbe818SShteryana Shopova /*
129709cbe818SShteryana Shopova  * Convert the value returned by the kernel to the appropriate SNMP
129809cbe818SShteryana Shopova  * representation and set the corresponding interface member accordingly.
129909cbe818SShteryana Shopova  */
130009cbe818SShteryana Shopova static void
wlan_config_set_snmp_intval(struct wlan_iface * wif,int op,int val)130109cbe818SShteryana Shopova wlan_config_set_snmp_intval(struct wlan_iface *wif, int op, int val)
130209cbe818SShteryana Shopova {
130309cbe818SShteryana Shopova 	switch (op) {
130409cbe818SShteryana Shopova 	case IEEE80211_IOC_BURST:
130509cbe818SShteryana Shopova 		if (val == 0)
130609cbe818SShteryana Shopova 			wif->packet_burst = TruthValue_false;
130709cbe818SShteryana Shopova 		else
130809cbe818SShteryana Shopova 			wif->packet_burst = TruthValue_true;
130909cbe818SShteryana Shopova 		break;
131009cbe818SShteryana Shopova 	case IEEE80211_IOC_DFS:
131109cbe818SShteryana Shopova 		if (val == 0)
131209cbe818SShteryana Shopova 			wif->dyn_frequency = TruthValue_false;
131309cbe818SShteryana Shopova 		else
131409cbe818SShteryana Shopova 			wif->dyn_frequency = TruthValue_true;
131509cbe818SShteryana Shopova 		break;
131609cbe818SShteryana Shopova 	case IEEE80211_IOC_FF:
131709cbe818SShteryana Shopova 		if (val == 0)
131809cbe818SShteryana Shopova 			wif->fast_frames = TruthValue_false;
131909cbe818SShteryana Shopova 		else
132009cbe818SShteryana Shopova 			wif->fast_frames = TruthValue_true;
132109cbe818SShteryana Shopova 		break;
132209cbe818SShteryana Shopova 	case IEEE80211_IOC_TURBOP:
132309cbe818SShteryana Shopova 		if (val == 0)
132409cbe818SShteryana Shopova 			wif->dturbo = TruthValue_false;
132509cbe818SShteryana Shopova 		else
132609cbe818SShteryana Shopova 			wif->dturbo = TruthValue_true;
132709cbe818SShteryana Shopova 		break;
132809cbe818SShteryana Shopova 	case IEEE80211_IOC_TXPOWER:
132909cbe818SShteryana Shopova 		wif->tx_power = val / 2;
133009cbe818SShteryana Shopova 		break;
133109cbe818SShteryana Shopova 	case IEEE80211_IOC_FRAGTHRESHOLD:
133209cbe818SShteryana Shopova 		wif->frag_threshold = val;
133309cbe818SShteryana Shopova 		break;
133409cbe818SShteryana Shopova 	case IEEE80211_IOC_RTSTHRESHOLD:
133509cbe818SShteryana Shopova 		wif->rts_threshold = val;
133609cbe818SShteryana Shopova 		break;
133709cbe818SShteryana Shopova 	case IEEE80211_IOC_WPS:
133809cbe818SShteryana Shopova 		if (val == 0)
133909cbe818SShteryana Shopova 			wif->priv_subscribe = TruthValue_false;
134009cbe818SShteryana Shopova 		else
134109cbe818SShteryana Shopova 			wif->priv_subscribe = TruthValue_true;
134209cbe818SShteryana Shopova 		break;
134309cbe818SShteryana Shopova 	case IEEE80211_IOC_BGSCAN:
134409cbe818SShteryana Shopova 		if (val == 0)
134509cbe818SShteryana Shopova 			wif->bg_scan = TruthValue_false;
134609cbe818SShteryana Shopova 		else
134709cbe818SShteryana Shopova 			wif->bg_scan = TruthValue_true;
134809cbe818SShteryana Shopova 		break;
134909cbe818SShteryana Shopova 	case IEEE80211_IOC_BGSCAN_IDLE:
135009cbe818SShteryana Shopova 		wif->bg_scan_idle = val;
135109cbe818SShteryana Shopova 		break;
135209cbe818SShteryana Shopova 	case IEEE80211_IOC_BGSCAN_INTERVAL:
135309cbe818SShteryana Shopova 		wif->bg_scan_interval = val;
135409cbe818SShteryana Shopova 		break;
135509cbe818SShteryana Shopova 	case IEEE80211_IOC_BMISSTHRESHOLD:
135609cbe818SShteryana Shopova 		wif->beacons_missed = val;
135709cbe818SShteryana Shopova 		break;
135809cbe818SShteryana Shopova 	case IEEE80211_IOC_ROAMING:
135909cbe818SShteryana Shopova 		switch (val) {
136009cbe818SShteryana Shopova 		case IEEE80211_ROAMING_DEVICE:
136109cbe818SShteryana Shopova 			wif->roam_mode = wlanIfaceRoamingMode_device;
136209cbe818SShteryana Shopova 			break;
136309cbe818SShteryana Shopova 		case IEEE80211_ROAMING_MANUAL:
136409cbe818SShteryana Shopova 			wif->roam_mode = wlanIfaceRoamingMode_manual;
136509cbe818SShteryana Shopova 			break;
136609cbe818SShteryana Shopova 		case IEEE80211_ROAMING_AUTO:
136709cbe818SShteryana Shopova 			/* FALTHROUGH */
136809cbe818SShteryana Shopova 		default:
136909cbe818SShteryana Shopova 			wif->roam_mode = wlanIfaceRoamingMode_auto;
137009cbe818SShteryana Shopova 			break;
137109cbe818SShteryana Shopova 		}
137209cbe818SShteryana Shopova 		break;
137309cbe818SShteryana Shopova 	case IEEE80211_IOC_DOTD:
137409cbe818SShteryana Shopova 		if (val == 0)
137509cbe818SShteryana Shopova 			wif->dot11d = TruthValue_false;
137609cbe818SShteryana Shopova 		else
137709cbe818SShteryana Shopova 			wif->dot11d = TruthValue_true;
137809cbe818SShteryana Shopova 		break;
137909cbe818SShteryana Shopova 	case IEEE80211_IOC_DOTH:
138009cbe818SShteryana Shopova 		if (val == 0)
138109cbe818SShteryana Shopova 			wif->dot11h = TruthValue_false;
138209cbe818SShteryana Shopova 		else
138309cbe818SShteryana Shopova 			wif->dot11h = TruthValue_true;
138409cbe818SShteryana Shopova 		break;
138509cbe818SShteryana Shopova 	case IEEE80211_IOC_DWDS:
138609cbe818SShteryana Shopova 		if (val == 0)
138709cbe818SShteryana Shopova 			wif->dynamic_wds = TruthValue_false;
138809cbe818SShteryana Shopova 		else
138909cbe818SShteryana Shopova 			wif->dynamic_wds = TruthValue_true;
139009cbe818SShteryana Shopova 		break;
139109cbe818SShteryana Shopova 	case IEEE80211_IOC_POWERSAVE:
139209cbe818SShteryana Shopova 		if (val == 0)
139309cbe818SShteryana Shopova 			wif->power_save = TruthValue_false;
139409cbe818SShteryana Shopova 		else
139509cbe818SShteryana Shopova 			wif->power_save = TruthValue_true;
139609cbe818SShteryana Shopova 		break;
139709cbe818SShteryana Shopova 	case IEEE80211_IOC_APBRIDGE:
139809cbe818SShteryana Shopova 		if (val == 0)
139909cbe818SShteryana Shopova 			wif->ap_bridge = TruthValue_false;
140009cbe818SShteryana Shopova 		else
140109cbe818SShteryana Shopova 			wif->ap_bridge = TruthValue_true;
140209cbe818SShteryana Shopova 		break;
140309cbe818SShteryana Shopova 	case IEEE80211_IOC_BEACON_INTERVAL:
140409cbe818SShteryana Shopova 		wif->beacon_interval = val;
140509cbe818SShteryana Shopova 		break;
140609cbe818SShteryana Shopova 	case IEEE80211_IOC_DTIM_PERIOD:
140709cbe818SShteryana Shopova 		wif->dtim_period = val;
140809cbe818SShteryana Shopova 		break;
140909cbe818SShteryana Shopova 	case IEEE80211_IOC_HIDESSID:
141009cbe818SShteryana Shopova 		if (val == 0)
141109cbe818SShteryana Shopova 			wif->hide_ssid = TruthValue_false;
141209cbe818SShteryana Shopova 		else
141309cbe818SShteryana Shopova 			wif->hide_ssid = TruthValue_true;
141409cbe818SShteryana Shopova 		break;
141509cbe818SShteryana Shopova 	case IEEE80211_IOC_INACTIVITY:
141609cbe818SShteryana Shopova 		if (val == 0)
141709cbe818SShteryana Shopova 			wif->inact_process = TruthValue_false;
141809cbe818SShteryana Shopova 		else
141909cbe818SShteryana Shopova 			wif->inact_process = TruthValue_true;
142009cbe818SShteryana Shopova 		break;
142109cbe818SShteryana Shopova 	case IEEE80211_IOC_PROTMODE:
142209cbe818SShteryana Shopova 		switch (val) {
142309cbe818SShteryana Shopova 		case IEEE80211_PROTMODE_CTS:
142409cbe818SShteryana Shopova 			wif->do11g_protect = wlanIfaceDot11gProtMode_cts;
142509cbe818SShteryana Shopova 			break;
142609cbe818SShteryana Shopova 		case IEEE80211_PROTMODE_RTSCTS:
142709cbe818SShteryana Shopova 			wif->do11g_protect = wlanIfaceDot11gProtMode_rtscts;
142809cbe818SShteryana Shopova 			break;
142909cbe818SShteryana Shopova 		case IEEE80211_PROTMODE_OFF:
143009cbe818SShteryana Shopova 			/* FALLTHROUGH */
143109cbe818SShteryana Shopova 		default:
143209cbe818SShteryana Shopova 			wif->do11g_protect = wlanIfaceDot11gProtMode_off;
143309cbe818SShteryana Shopova 			break;
143409cbe818SShteryana Shopova 		}
143509cbe818SShteryana Shopova 		break;
143609cbe818SShteryana Shopova 	case IEEE80211_IOC_PUREG:
143709cbe818SShteryana Shopova 		if (val == 0)
143809cbe818SShteryana Shopova 			wif->dot11g_pure = TruthValue_false;
143909cbe818SShteryana Shopova 		else
144009cbe818SShteryana Shopova 			wif->dot11g_pure = TruthValue_true;
144109cbe818SShteryana Shopova 		break;
144209cbe818SShteryana Shopova 	case IEEE80211_IOC_PUREN:
144309cbe818SShteryana Shopova 		if (val == 0)
144409cbe818SShteryana Shopova 			wif->dot11n_pure = TruthValue_false;
144509cbe818SShteryana Shopova 		else
144609cbe818SShteryana Shopova 			wif->dot11n_pure = TruthValue_true;
144709cbe818SShteryana Shopova 		break;
144809cbe818SShteryana Shopova 	case IEEE80211_IOC_AMPDU:
144909cbe818SShteryana Shopova 		switch (val) {
145009cbe818SShteryana Shopova 		case 0:
145109cbe818SShteryana Shopova 			wif->ampdu = WlanIfaceDot11nPduType_disabled;
145209cbe818SShteryana Shopova 			break;
145309cbe818SShteryana Shopova 		case 1:
145409cbe818SShteryana Shopova 			wif->ampdu = WlanIfaceDot11nPduType_txOnly;
145509cbe818SShteryana Shopova 			break;
145609cbe818SShteryana Shopova 		case 2:
145709cbe818SShteryana Shopova 			wif->ampdu = WlanIfaceDot11nPduType_rxOnly;
145809cbe818SShteryana Shopova 			break;
145909cbe818SShteryana Shopova 		case 3:
146009cbe818SShteryana Shopova 			/* FALLTHROUGH */
146109cbe818SShteryana Shopova 		default:
146209cbe818SShteryana Shopova 			wif->ampdu = WlanIfaceDot11nPduType_txAndRx;
146309cbe818SShteryana Shopova 			break;
146409cbe818SShteryana Shopova 		}
146509cbe818SShteryana Shopova 		break;
146609cbe818SShteryana Shopova 	case IEEE80211_IOC_AMPDU_DENSITY:
146709cbe818SShteryana Shopova 		switch (val) {
146809cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_025:
146909cbe818SShteryana Shopova 			wif->ampdu_density = 25;
147009cbe818SShteryana Shopova 			break;
147109cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_05:
147209cbe818SShteryana Shopova 			wif->ampdu_density = 50;
147309cbe818SShteryana Shopova 			break;
147409cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_1:
147509cbe818SShteryana Shopova 			wif->ampdu_density = 100;
147609cbe818SShteryana Shopova 			break;
147709cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_2:
147809cbe818SShteryana Shopova 			wif->ampdu_density = 200;
147909cbe818SShteryana Shopova 			break;
148009cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_4:
148109cbe818SShteryana Shopova 			wif->ampdu_density = 400;
148209cbe818SShteryana Shopova 			break;
148309cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_8:
148409cbe818SShteryana Shopova 			wif->ampdu_density = 800;
148509cbe818SShteryana Shopova 			break;
148609cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_16:
148709cbe818SShteryana Shopova 			wif->ampdu_density = 1600;
148809cbe818SShteryana Shopova 			break;
148909cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MPDUDENSITY_NA:
149009cbe818SShteryana Shopova 		default:
149109cbe818SShteryana Shopova 			wif->ampdu_density = 0;
149209cbe818SShteryana Shopova 			break;
149309cbe818SShteryana Shopova 		}
149409cbe818SShteryana Shopova 		break;
149509cbe818SShteryana Shopova 	case IEEE80211_IOC_AMPDU_LIMIT:
149609cbe818SShteryana Shopova 		switch (val) {
149709cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MAXRXAMPDU_8K:
149809cbe818SShteryana Shopova 			wif->ampdu_limit = 8192;
149909cbe818SShteryana Shopova 			break;
150009cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MAXRXAMPDU_16K:
150109cbe818SShteryana Shopova 			wif->ampdu_limit = 16384;
150209cbe818SShteryana Shopova 			break;
150309cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MAXRXAMPDU_32K:
150409cbe818SShteryana Shopova 			wif->ampdu_limit = 32768;
150509cbe818SShteryana Shopova 			break;
150609cbe818SShteryana Shopova 		case IEEE80211_HTCAP_MAXRXAMPDU_64K:
150709cbe818SShteryana Shopova 		default:
150809cbe818SShteryana Shopova 			wif->ampdu_limit = 65536;
150909cbe818SShteryana Shopova 			break;
151009cbe818SShteryana Shopova 		}
151109cbe818SShteryana Shopova 		break;
151209cbe818SShteryana Shopova 	case IEEE80211_IOC_AMSDU:
151309cbe818SShteryana Shopova 		switch (val) {
151409cbe818SShteryana Shopova 		case 0:
151509cbe818SShteryana Shopova 			wif->amsdu = WlanIfaceDot11nPduType_disabled;
151609cbe818SShteryana Shopova 			break;
151709cbe818SShteryana Shopova 		case 1:
151809cbe818SShteryana Shopova 			wif->amsdu = WlanIfaceDot11nPduType_txOnly;
151909cbe818SShteryana Shopova 			break;
152009cbe818SShteryana Shopova 		case 3:
152109cbe818SShteryana Shopova 			wif->amsdu = WlanIfaceDot11nPduType_txAndRx;
152209cbe818SShteryana Shopova 			break;
152309cbe818SShteryana Shopova 		case 2:
152409cbe818SShteryana Shopova 		default:
152509cbe818SShteryana Shopova 			/* FALLTHROUGH */
152609cbe818SShteryana Shopova 			wif->amsdu = WlanIfaceDot11nPduType_rxOnly;
152709cbe818SShteryana Shopova 			break;
152809cbe818SShteryana Shopova 		}
152909cbe818SShteryana Shopova 		break;
153009cbe818SShteryana Shopova 	case IEEE80211_IOC_AMSDU_LIMIT:
153109cbe818SShteryana Shopova 		wif->amsdu_limit = val;
153209cbe818SShteryana Shopova 		break;
153309cbe818SShteryana Shopova 	case IEEE80211_IOC_HTCONF:
153409cbe818SShteryana Shopova 		if (val == 0) /* XXX */
153509cbe818SShteryana Shopova 			wif->ht_enabled = TruthValue_false;
153609cbe818SShteryana Shopova 		else
153709cbe818SShteryana Shopova 			wif->ht_enabled = TruthValue_true;
153809cbe818SShteryana Shopova 		break;
153909cbe818SShteryana Shopova 	case IEEE80211_IOC_HTCOMPAT:
154009cbe818SShteryana Shopova 		if (val == 0)
154109cbe818SShteryana Shopova 			wif->ht_compatible = TruthValue_false;
154209cbe818SShteryana Shopova 		else
154309cbe818SShteryana Shopova 			wif->ht_compatible = TruthValue_true;
154409cbe818SShteryana Shopova 		break;
154509cbe818SShteryana Shopova 	case IEEE80211_IOC_HTPROTMODE:
154609cbe818SShteryana Shopova 		if (val == IEEE80211_PROTMODE_RTSCTS)
154709cbe818SShteryana Shopova 			wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_rts;
154809cbe818SShteryana Shopova 		else
154909cbe818SShteryana Shopova 			wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_off;
155009cbe818SShteryana Shopova 		break;
155109cbe818SShteryana Shopova 	case IEEE80211_IOC_RIFS:
155209cbe818SShteryana Shopova 		if (val == 0)
155309cbe818SShteryana Shopova 			wif->rifs = TruthValue_false;
155409cbe818SShteryana Shopova 		else
155509cbe818SShteryana Shopova 			wif->rifs = TruthValue_true;
155609cbe818SShteryana Shopova 		break;
155709cbe818SShteryana Shopova 	case IEEE80211_IOC_SHORTGI:
155809cbe818SShteryana Shopova 		if (val == 0)
155909cbe818SShteryana Shopova 			wif->short_gi = TruthValue_false;
156009cbe818SShteryana Shopova 		else
156109cbe818SShteryana Shopova 			wif->short_gi = TruthValue_true;
156209cbe818SShteryana Shopova 		break;
156309cbe818SShteryana Shopova 	case IEEE80211_IOC_SMPS:
156409cbe818SShteryana Shopova 		switch (val) {
156509cbe818SShteryana Shopova 		case IEEE80211_HTCAP_SMPS_DYNAMIC:
156609cbe818SShteryana Shopova 			wif->smps_mode = wlanIfaceDot11nSMPSMode_dynamic;
156709cbe818SShteryana Shopova 			break;
156809cbe818SShteryana Shopova 		case IEEE80211_HTCAP_SMPS_ENA:
156909cbe818SShteryana Shopova 			wif->smps_mode = wlanIfaceDot11nSMPSMode_static;
157009cbe818SShteryana Shopova 			break;
157109cbe818SShteryana Shopova 		case IEEE80211_HTCAP_SMPS_OFF:
157209cbe818SShteryana Shopova 			/* FALLTHROUGH */
157309cbe818SShteryana Shopova 		default:
157409cbe818SShteryana Shopova 			wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled;
157509cbe818SShteryana Shopova 			break;
157609cbe818SShteryana Shopova 		}
157709cbe818SShteryana Shopova 		break;
157809cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOT:
157909cbe818SShteryana Shopova 		wif->tdma_slot = val;
158009cbe818SShteryana Shopova 		break;
158109cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOTCNT:
158209cbe818SShteryana Shopova 		wif->tdma_slot_count = val;
158309cbe818SShteryana Shopova 		break;
158409cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOTLEN:
158509cbe818SShteryana Shopova 		wif->tdma_slot_length = val;
158609cbe818SShteryana Shopova 		break;
158709cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_BINTERVAL:
158809cbe818SShteryana Shopova 		wif->tdma_binterval = val;
158909cbe818SShteryana Shopova 		break;
159009cbe818SShteryana Shopova 	default:
159109cbe818SShteryana Shopova 		break;
159209cbe818SShteryana Shopova 	}
159309cbe818SShteryana Shopova }
159409cbe818SShteryana Shopova 
159509cbe818SShteryana Shopova /*
159609cbe818SShteryana Shopova  * Convert an SNMP value to the kernel equivalent and also do sanity check
159709cbe818SShteryana Shopova  * for each specific type.
159809cbe818SShteryana Shopova  */
159909cbe818SShteryana Shopova static int
wlan_config_snmp2value(int which,int sval,int * value)160009cbe818SShteryana Shopova wlan_config_snmp2value(int which, int sval, int *value)
160109cbe818SShteryana Shopova {
160209cbe818SShteryana Shopova 	*value = 0;
160309cbe818SShteryana Shopova 
160409cbe818SShteryana Shopova 	switch (which) {
160509cbe818SShteryana Shopova 	case IEEE80211_IOC_BURST:
160609cbe818SShteryana Shopova 	case IEEE80211_IOC_DFS:
160709cbe818SShteryana Shopova 	case IEEE80211_IOC_FF:
160809cbe818SShteryana Shopova 	case IEEE80211_IOC_TURBOP:
160909cbe818SShteryana Shopova 	case IEEE80211_IOC_WPS:
161009cbe818SShteryana Shopova 	case IEEE80211_IOC_BGSCAN:
161109cbe818SShteryana Shopova 	case IEEE80211_IOC_DOTD:
161209cbe818SShteryana Shopova 	case IEEE80211_IOC_DOTH:
161309cbe818SShteryana Shopova 	case IEEE80211_IOC_DWDS:
161409cbe818SShteryana Shopova 	case IEEE80211_IOC_POWERSAVE:
161509cbe818SShteryana Shopova 	case IEEE80211_IOC_APBRIDGE:
161609cbe818SShteryana Shopova 	case IEEE80211_IOC_HIDESSID:
161709cbe818SShteryana Shopova 	case IEEE80211_IOC_INACTIVITY:
161809cbe818SShteryana Shopova 	case IEEE80211_IOC_PUREG:
161909cbe818SShteryana Shopova 	case IEEE80211_IOC_PUREN:
162009cbe818SShteryana Shopova 	case IEEE80211_IOC_HTCONF:
162109cbe818SShteryana Shopova 	case IEEE80211_IOC_HTCOMPAT:
162209cbe818SShteryana Shopova 	case IEEE80211_IOC_RIFS:
162309cbe818SShteryana Shopova 		if (sval == TruthValue_true)
162409cbe818SShteryana Shopova 			*value = 1;
162509cbe818SShteryana Shopova 		else if (sval != TruthValue_false)
162609cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
162709cbe818SShteryana Shopova 		break;
162809cbe818SShteryana Shopova 	case IEEE80211_IOC_REGDOMAIN:
162909cbe818SShteryana Shopova 		break;
163009cbe818SShteryana Shopova 	case IEEE80211_IOC_SSID:
163109cbe818SShteryana Shopova 		break;
163209cbe818SShteryana Shopova 	case IEEE80211_IOC_CURCHAN:
163309cbe818SShteryana Shopova 		break;
163409cbe818SShteryana Shopova 	case IEEE80211_IOC_TXPOWER:
163509cbe818SShteryana Shopova 		*value = sval * 2;
163609cbe818SShteryana Shopova 		break;
163709cbe818SShteryana Shopova 	case IEEE80211_IOC_FRAGTHRESHOLD:
163809cbe818SShteryana Shopova 		if (sval < IEEE80211_FRAG_MIN || sval > IEEE80211_FRAG_MAX)
163909cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
164009cbe818SShteryana Shopova 		*value = sval;
164109cbe818SShteryana Shopova 		break;
164209cbe818SShteryana Shopova 	case IEEE80211_IOC_RTSTHRESHOLD:
164309cbe818SShteryana Shopova 		if (sval < IEEE80211_RTS_MIN || sval > IEEE80211_RTS_MAX)
164409cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
164509cbe818SShteryana Shopova 		*value = sval;
164609cbe818SShteryana Shopova 		break;
164709cbe818SShteryana Shopova 	case IEEE80211_IOC_BGSCAN_IDLE:
164809cbe818SShteryana Shopova 		if (sval < WLAN_BGSCAN_IDLE_MIN)
164909cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
165009cbe818SShteryana Shopova 		*value = sval;
165109cbe818SShteryana Shopova 		break;
165209cbe818SShteryana Shopova 	case IEEE80211_IOC_BGSCAN_INTERVAL:
165309cbe818SShteryana Shopova 		if (sval < WLAN_SCAN_VALID_MIN)
165409cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
165509cbe818SShteryana Shopova 		*value = sval;
165609cbe818SShteryana Shopova 		break;
165709cbe818SShteryana Shopova 	case IEEE80211_IOC_BMISSTHRESHOLD:
165809cbe818SShteryana Shopova 		if (sval < IEEE80211_HWBMISS_MIN || sval > IEEE80211_HWBMISS_MAX)
165909cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
166009cbe818SShteryana Shopova 		*value = sval;
166109cbe818SShteryana Shopova 		break;
166209cbe818SShteryana Shopova 	case IEEE80211_IOC_BSSID:
166309cbe818SShteryana Shopova 		break;
166409cbe818SShteryana Shopova 	case IEEE80211_IOC_ROAMING:
166509cbe818SShteryana Shopova 		switch (sval) {
166609cbe818SShteryana Shopova 		case wlanIfaceRoamingMode_device:
166709cbe818SShteryana Shopova 			*value = IEEE80211_ROAMING_DEVICE;
166809cbe818SShteryana Shopova 			break;
166909cbe818SShteryana Shopova 		case wlanIfaceRoamingMode_manual:
167009cbe818SShteryana Shopova 			*value = IEEE80211_ROAMING_MANUAL;
167109cbe818SShteryana Shopova 			break;
167209cbe818SShteryana Shopova 		case wlanIfaceRoamingMode_auto:
167309cbe818SShteryana Shopova 			*value = IEEE80211_ROAMING_AUTO;
167409cbe818SShteryana Shopova 			break;
167509cbe818SShteryana Shopova 		default:
167609cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
167709cbe818SShteryana Shopova 		}
167809cbe818SShteryana Shopova 		break;
167909cbe818SShteryana Shopova 	case IEEE80211_IOC_BEACON_INTERVAL:
168009cbe818SShteryana Shopova 		if (sval < IEEE80211_BINTVAL_MIN || sval > IEEE80211_BINTVAL_MAX)
168109cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
168209cbe818SShteryana Shopova 		*value = sval;
168309cbe818SShteryana Shopova 		break;
168409cbe818SShteryana Shopova 	case IEEE80211_IOC_DTIM_PERIOD:
168509cbe818SShteryana Shopova 		if (sval < IEEE80211_DTIM_MIN || sval > IEEE80211_DTIM_MAX)
168609cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
168709cbe818SShteryana Shopova 		*value = sval;
168809cbe818SShteryana Shopova 		break;
168909cbe818SShteryana Shopova 	case IEEE80211_IOC_PROTMODE:
169009cbe818SShteryana Shopova 		switch (sval) {
169109cbe818SShteryana Shopova 		case wlanIfaceDot11gProtMode_cts:
169209cbe818SShteryana Shopova 			*value = IEEE80211_PROTMODE_CTS;
169309cbe818SShteryana Shopova 			break;
169409cbe818SShteryana Shopova 		case wlanIfaceDot11gProtMode_rtscts:
169509cbe818SShteryana Shopova 			*value = IEEE80211_PROTMODE_RTSCTS;
169609cbe818SShteryana Shopova 			break;
169709cbe818SShteryana Shopova 		case wlanIfaceDot11gProtMode_off:
169809cbe818SShteryana Shopova 			*value = IEEE80211_PROTMODE_OFF;
169909cbe818SShteryana Shopova 			break;
170009cbe818SShteryana Shopova 		default:
170109cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
170209cbe818SShteryana Shopova 		}
170309cbe818SShteryana Shopova 		break;
170409cbe818SShteryana Shopova 	case IEEE80211_IOC_AMPDU:
170509cbe818SShteryana Shopova 		switch (sval) {
170609cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_disabled:
170709cbe818SShteryana Shopova 			break;
170809cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_txOnly:
170909cbe818SShteryana Shopova 			*value = 1;
171009cbe818SShteryana Shopova 			break;
171109cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_rxOnly:
171209cbe818SShteryana Shopova 			*value = 2;
171309cbe818SShteryana Shopova 			break;
171409cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_txAndRx:
171509cbe818SShteryana Shopova 			*value = 3;
171609cbe818SShteryana Shopova 			break;
171709cbe818SShteryana Shopova 		default:
171809cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
171909cbe818SShteryana Shopova 		}
172009cbe818SShteryana Shopova 		break;
172109cbe818SShteryana Shopova 	case IEEE80211_IOC_AMPDU_DENSITY:
172209cbe818SShteryana Shopova 		switch (sval) {
172309cbe818SShteryana Shopova 		case 0:
172409cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_NA;
172509cbe818SShteryana Shopova 			break;
172609cbe818SShteryana Shopova 		case 25:
172709cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_025;
172809cbe818SShteryana Shopova 			break;
172909cbe818SShteryana Shopova 		case 50:
173009cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_05;
173109cbe818SShteryana Shopova 			break;
173209cbe818SShteryana Shopova 		case 100:
173309cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_1;
173409cbe818SShteryana Shopova 			break;
173509cbe818SShteryana Shopova 		case 200:
173609cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_2;
173709cbe818SShteryana Shopova 			break;
173809cbe818SShteryana Shopova 		case 400:
173909cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_4;
174009cbe818SShteryana Shopova 			break;
174109cbe818SShteryana Shopova 		case 800:
174209cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_8;
174309cbe818SShteryana Shopova 			break;
174409cbe818SShteryana Shopova 		case 1600:
174509cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MPDUDENSITY_16;
174609cbe818SShteryana Shopova 			break;
174709cbe818SShteryana Shopova 		default:
174809cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
174909cbe818SShteryana Shopova 		}
175009cbe818SShteryana Shopova 		break;
175109cbe818SShteryana Shopova 	case IEEE80211_IOC_AMPDU_LIMIT:
175209cbe818SShteryana Shopova 		switch (sval) {
175309cbe818SShteryana Shopova 		case 8192:
175409cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MAXRXAMPDU_8K;
175509cbe818SShteryana Shopova 			break;
175609cbe818SShteryana Shopova 		case 16384:
175709cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MAXRXAMPDU_16K;
175809cbe818SShteryana Shopova 			break;
175909cbe818SShteryana Shopova 		case 32768:
176009cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MAXRXAMPDU_32K;
176109cbe818SShteryana Shopova 			break;
176209cbe818SShteryana Shopova 		case 65536:
176309cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MAXRXAMPDU_64K;
176409cbe818SShteryana Shopova 			break;
176509cbe818SShteryana Shopova 		default:
176609cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
176709cbe818SShteryana Shopova 		}
176809cbe818SShteryana Shopova 		break;
176909cbe818SShteryana Shopova 	case IEEE80211_IOC_AMSDU:
177009cbe818SShteryana Shopova 		switch (sval) {
177109cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_disabled:
177209cbe818SShteryana Shopova 			break;
177309cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_txOnly:
177409cbe818SShteryana Shopova 			*value = 1;
177509cbe818SShteryana Shopova 			break;
177609cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_rxOnly:
177709cbe818SShteryana Shopova 			*value = 2;
177809cbe818SShteryana Shopova 			break;
177909cbe818SShteryana Shopova 		case WlanIfaceDot11nPduType_txAndRx:
178009cbe818SShteryana Shopova 			*value = 3;
178109cbe818SShteryana Shopova 			break;
178209cbe818SShteryana Shopova 		default:
178309cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
178409cbe818SShteryana Shopova 		}
178509cbe818SShteryana Shopova 		break;
178609cbe818SShteryana Shopova 	case IEEE80211_IOC_AMSDU_LIMIT:
178709cbe818SShteryana Shopova 		if (sval == 3839 || sval == 0)
178809cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MAXAMSDU_3839;
178909cbe818SShteryana Shopova 		else if (sval == 7935)
179009cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_MAXAMSDU_7935;
179109cbe818SShteryana Shopova 		else
179209cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
179309cbe818SShteryana Shopova 		break;
179409cbe818SShteryana Shopova 	case IEEE80211_IOC_HTPROTMODE:
179509cbe818SShteryana Shopova 		switch (sval) {
179609cbe818SShteryana Shopova 		case wlanIfaceDot11nHTProtMode_rts:
179709cbe818SShteryana Shopova 			*value = IEEE80211_PROTMODE_RTSCTS;
179809cbe818SShteryana Shopova 			break;
179909cbe818SShteryana Shopova 		case wlanIfaceDot11nHTProtMode_off:
180009cbe818SShteryana Shopova 			break;
180109cbe818SShteryana Shopova 		default:
180209cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
180309cbe818SShteryana Shopova 		}
180409cbe818SShteryana Shopova 		break;
180509cbe818SShteryana Shopova 	case IEEE80211_IOC_SHORTGI:
180609cbe818SShteryana Shopova 		if (sval == TruthValue_true)
180709cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_SHORTGI20 |
180809cbe818SShteryana Shopova 			    IEEE80211_HTCAP_SHORTGI40;
180909cbe818SShteryana Shopova 		else if (sval != TruthValue_false)
181009cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
181109cbe818SShteryana Shopova 		break;
181209cbe818SShteryana Shopova 	case IEEE80211_IOC_SMPS:
181309cbe818SShteryana Shopova 		switch (sval) {
181409cbe818SShteryana Shopova 		case wlanIfaceDot11nSMPSMode_disabled:
181509cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_SMPS_OFF;
181609cbe818SShteryana Shopova 			break;
181709cbe818SShteryana Shopova 		case wlanIfaceDot11nSMPSMode_static:
181809cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_SMPS_ENA;
181909cbe818SShteryana Shopova 			break;
182009cbe818SShteryana Shopova 		case wlanIfaceDot11nSMPSMode_dynamic:
182109cbe818SShteryana Shopova 			*value = IEEE80211_HTCAP_SMPS_DYNAMIC;
182209cbe818SShteryana Shopova 			break;
182309cbe818SShteryana Shopova 		default:
182409cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
182509cbe818SShteryana Shopova 		}
182609cbe818SShteryana Shopova 		break;
182709cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOT:
182809cbe818SShteryana Shopova 		if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */
182909cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
183009cbe818SShteryana Shopova 		*value = sval;
183109cbe818SShteryana Shopova 		break;
183209cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOTCNT:
183309cbe818SShteryana Shopova 		if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */
183409cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
183509cbe818SShteryana Shopova 		*value = sval;
183609cbe818SShteryana Shopova 		break;
183709cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOTLEN:
183809cbe818SShteryana Shopova 		if (sval < 2*100 || sval > 0xfffff) /* XXX */
183909cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
184009cbe818SShteryana Shopova 		*value = sval;
184109cbe818SShteryana Shopova 		break;
184209cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_BINTERVAL:
184309cbe818SShteryana Shopova 		if (sval < 1) /* XXX */
184409cbe818SShteryana Shopova 			return (SNMP_ERR_INCONS_VALUE);
184509cbe818SShteryana Shopova 		*value = sval;
184609cbe818SShteryana Shopova 		break;
184709cbe818SShteryana Shopova 	default:
184809cbe818SShteryana Shopova 		return (SNMP_ERR_INCONS_VALUE);
184909cbe818SShteryana Shopova 	}
185009cbe818SShteryana Shopova 
185109cbe818SShteryana Shopova 	return (SNMP_ERR_NOERROR);
185209cbe818SShteryana Shopova }
185309cbe818SShteryana Shopova 
185409cbe818SShteryana Shopova /*
185509cbe818SShteryana Shopova  * Sanity checks for the wlanIfaceConfigTable.
185609cbe818SShteryana Shopova  */
185709cbe818SShteryana Shopova static int
wlan_config_check(struct wlan_iface * wif,int op)185809cbe818SShteryana Shopova wlan_config_check(struct wlan_iface *wif, int op)
185909cbe818SShteryana Shopova {
186009cbe818SShteryana Shopova 	switch (op) {
186109cbe818SShteryana Shopova 	case IEEE80211_IOC_BURST:
186209cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_burst)) == 0) {
186309cbe818SShteryana Shopova 			wif->packet_burst = TruthValue_false;
186409cbe818SShteryana Shopova 			return (-1);
186509cbe818SShteryana Shopova 		}
186609cbe818SShteryana Shopova 		break;
186709cbe818SShteryana Shopova 	case IEEE80211_IOC_DFS:
186809cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_dfs)) == 0) {
186909cbe818SShteryana Shopova 			wif->dyn_frequency = TruthValue_false;
187009cbe818SShteryana Shopova 			return (-1);
187109cbe818SShteryana Shopova 		}
187209cbe818SShteryana Shopova 		break;
187309cbe818SShteryana Shopova 	case IEEE80211_IOC_FF:
187409cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_athFastFrames))
187509cbe818SShteryana Shopova 		    == 0) {
187609cbe818SShteryana Shopova 			wif->fast_frames = TruthValue_false;
187709cbe818SShteryana Shopova 			return (-1);
187809cbe818SShteryana Shopova 		}
187909cbe818SShteryana Shopova 		break;
188009cbe818SShteryana Shopova 	case IEEE80211_IOC_TURBOP:
188109cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_athTurbo)) == 0) {
188209cbe818SShteryana Shopova 			wif->dturbo = TruthValue_false;
188309cbe818SShteryana Shopova 			return (-1);
188409cbe818SShteryana Shopova 		}
188509cbe818SShteryana Shopova 		break;
188609cbe818SShteryana Shopova 	case IEEE80211_IOC_TXPOWER:
188709cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_txPmgt)) == 0) {
188809cbe818SShteryana Shopova 			wif->tx_power = 0;
188909cbe818SShteryana Shopova 			return (-1);
189009cbe818SShteryana Shopova 		}
189109cbe818SShteryana Shopova 		break;
189209cbe818SShteryana Shopova 	case IEEE80211_IOC_FRAGTHRESHOLD:
189309cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_txFrag)) == 0) {
189409cbe818SShteryana Shopova 			wif->frag_threshold = IEEE80211_FRAG_MAX;
189509cbe818SShteryana Shopova 			return (-1);
189609cbe818SShteryana Shopova 		}
189709cbe818SShteryana Shopova 		break;
189809cbe818SShteryana Shopova 	case IEEE80211_IOC_DWDS:
189909cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_wds)) == 0) {
190009cbe818SShteryana Shopova 			wif->dynamic_wds = TruthValue_false;
190109cbe818SShteryana Shopova 			return (-1);
190209cbe818SShteryana Shopova 		}
190309cbe818SShteryana Shopova 		break;
190409cbe818SShteryana Shopova 	case IEEE80211_IOC_POWERSAVE:
190509cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_pmgt)) == 0) {
190609cbe818SShteryana Shopova 			wif->power_save = TruthValue_false;
190709cbe818SShteryana Shopova 			return (-1);
190809cbe818SShteryana Shopova 		}
190909cbe818SShteryana Shopova 		break;
191009cbe818SShteryana Shopova 	case IEEE80211_IOC_BEACON_INTERVAL:
191109cbe818SShteryana Shopova 		if (wif->mode != WlanIfaceOperatingModeType_hostAp &&
191209cbe818SShteryana Shopova 		    wif->mode != WlanIfaceOperatingModeType_meshPoint &&
191309cbe818SShteryana Shopova 		    wif->mode != WlanIfaceOperatingModeType_ibss) {
191409cbe818SShteryana Shopova 			wif->beacon_interval = 100; /* XXX */
191509cbe818SShteryana Shopova 			return (-1);
191609cbe818SShteryana Shopova 		}
191709cbe818SShteryana Shopova 		break;
191809cbe818SShteryana Shopova 	case IEEE80211_IOC_DTIM_PERIOD:
191909cbe818SShteryana Shopova 		if (wif->mode != WlanIfaceOperatingModeType_hostAp &&
192009cbe818SShteryana Shopova 		    wif->mode != WlanIfaceOperatingModeType_meshPoint &&
192109cbe818SShteryana Shopova 		    wif->mode != WlanIfaceOperatingModeType_ibss) {
192209cbe818SShteryana Shopova 			wif->dtim_period = 1; /* XXX */
192309cbe818SShteryana Shopova 			return (-1);
192409cbe818SShteryana Shopova 		}
192509cbe818SShteryana Shopova 		break;
192609cbe818SShteryana Shopova 	case IEEE80211_IOC_PUREN:
192709cbe818SShteryana Shopova 		if ((wif->htcaps & (0x1 << WlanHTCaps_htcHt)) == 0) {
192809cbe818SShteryana Shopova 			wif->dot11n_pure = TruthValue_false;
192909cbe818SShteryana Shopova 			return (-1);
193009cbe818SShteryana Shopova 		}
193109cbe818SShteryana Shopova 		break;
193209cbe818SShteryana Shopova 	case IEEE80211_IOC_AMPDU:
193309cbe818SShteryana Shopova 		if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmpdu)) == 0) {
193409cbe818SShteryana Shopova 			wif->ampdu = WlanIfaceDot11nPduType_disabled;
193509cbe818SShteryana Shopova 			return (-1);
193609cbe818SShteryana Shopova 		}
193709cbe818SShteryana Shopova 		break;
193809cbe818SShteryana Shopova 	case IEEE80211_IOC_AMSDU:
193909cbe818SShteryana Shopova 		if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmsdu)) == 0) {
194009cbe818SShteryana Shopova 			wif->amsdu = WlanIfaceDot11nPduType_disabled;
194109cbe818SShteryana Shopova 			return (-1);
194209cbe818SShteryana Shopova 		}
194309cbe818SShteryana Shopova 		break;
194409cbe818SShteryana Shopova 	case IEEE80211_IOC_RIFS:
194509cbe818SShteryana Shopova 		if ((wif->htcaps & (0x1 << WlanHTCaps_htcRifs)) == 0) {
194609cbe818SShteryana Shopova 			wif->rifs = TruthValue_false;
194709cbe818SShteryana Shopova 			return (-1);
194809cbe818SShteryana Shopova 		}
194909cbe818SShteryana Shopova 		break;
195009cbe818SShteryana Shopova 	case IEEE80211_IOC_SHORTGI:
195109cbe818SShteryana Shopova 		if ((wif->htcaps & (0x1 << WlanHTCaps_shortGi20 |
195209cbe818SShteryana Shopova 		    0x1 << WlanHTCaps_shortGi40)) == 0) {
195309cbe818SShteryana Shopova 			wif->short_gi = TruthValue_false;
195409cbe818SShteryana Shopova 			return (-1);
195509cbe818SShteryana Shopova 		}
195609cbe818SShteryana Shopova 		break;
195709cbe818SShteryana Shopova 	case IEEE80211_IOC_SMPS:
195809cbe818SShteryana Shopova 		if ((wif->htcaps & (0x1 << WlanHTCaps_htcSmps)) == 0) {
195909cbe818SShteryana Shopova 			wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled;
196009cbe818SShteryana Shopova 			return (-1);
196109cbe818SShteryana Shopova 		}
196209cbe818SShteryana Shopova 		break;
196309cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOT:
196409cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
196509cbe818SShteryana Shopova 			wif->tdma_slot = 0;
196609cbe818SShteryana Shopova 			return (-1);
196709cbe818SShteryana Shopova 		}
196809cbe818SShteryana Shopova 		break;
196909cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOTCNT:
197009cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
197109cbe818SShteryana Shopova 			wif->tdma_slot_count = 0;
197209cbe818SShteryana Shopova 			return (-1);
197309cbe818SShteryana Shopova 		}
197409cbe818SShteryana Shopova 		break;
197509cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_SLOTLEN:
197609cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
197709cbe818SShteryana Shopova 			wif->tdma_slot_length = 0;
197809cbe818SShteryana Shopova 			return (-1);
197909cbe818SShteryana Shopova 		}
198009cbe818SShteryana Shopova 		break;
198109cbe818SShteryana Shopova 	case IEEE80211_IOC_TDMA_BINTERVAL:
198209cbe818SShteryana Shopova 		if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
198309cbe818SShteryana Shopova 			wif->tdma_binterval = 0;
198409cbe818SShteryana Shopova 			return (-1);
198509cbe818SShteryana Shopova 		}
198609cbe818SShteryana Shopova 		break;
198709cbe818SShteryana Shopova 	default:
198809cbe818SShteryana Shopova 		break;
198909cbe818SShteryana Shopova 	}
199009cbe818SShteryana Shopova 
199109cbe818SShteryana Shopova 	return (0);
199209cbe818SShteryana Shopova }
199309cbe818SShteryana Shopova 
199409cbe818SShteryana Shopova static int
wlan_config_get_intval(struct wlan_iface * wif,int op)199509cbe818SShteryana Shopova wlan_config_get_intval(struct wlan_iface *wif, int op)
199609cbe818SShteryana Shopova {
199709cbe818SShteryana Shopova 	int val = 0;
199809cbe818SShteryana Shopova 	size_t argsize = 0;
199909cbe818SShteryana Shopova 
200009cbe818SShteryana Shopova 	if (wlan_config_check(wif, op) < 0)
200109cbe818SShteryana Shopova 		return (0);
200209cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0)
200309cbe818SShteryana Shopova 		return (-1);
200409cbe818SShteryana Shopova 	wlan_config_set_snmp_intval(wif, op, val);
200509cbe818SShteryana Shopova 
200609cbe818SShteryana Shopova 	return (0);
200709cbe818SShteryana Shopova }
200809cbe818SShteryana Shopova 
200909cbe818SShteryana Shopova static int
wlan_config_set_intval(struct wlan_iface * wif,int op,int sval)201009cbe818SShteryana Shopova wlan_config_set_intval(struct wlan_iface *wif, int op, int sval)
201109cbe818SShteryana Shopova {
201209cbe818SShteryana Shopova 	size_t argsize = 0;
201309cbe818SShteryana Shopova 	int val;
201409cbe818SShteryana Shopova 
201509cbe818SShteryana Shopova 	if (wlan_config_check(wif, op) < 0)
201609cbe818SShteryana Shopova 		return (-1);
201709cbe818SShteryana Shopova 	if (wlan_config_snmp2value(op, sval, &val) != SNMP_ERR_NOERROR)
201809cbe818SShteryana Shopova 		return (-1);
201909cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0)
202009cbe818SShteryana Shopova 		return (-1);
202109cbe818SShteryana Shopova 	wlan_config_set_snmp_intval(wif, op, val);
202209cbe818SShteryana Shopova 
202309cbe818SShteryana Shopova 	return (0);
202409cbe818SShteryana Shopova }
202509cbe818SShteryana Shopova 
202609cbe818SShteryana Shopova int
wlan_config_get_ioctl(struct wlan_iface * wif,int which)202709cbe818SShteryana Shopova wlan_config_get_ioctl(struct wlan_iface *wif, int which)
202809cbe818SShteryana Shopova {
202909cbe818SShteryana Shopova 	int op;
203009cbe818SShteryana Shopova 
203109cbe818SShteryana Shopova 	switch (which) {
203209cbe818SShteryana Shopova 		case LEAF_wlanIfaceCountryCode:
203309cbe818SShteryana Shopova 			/* FALLTHROUGH */
203409cbe818SShteryana Shopova 		case LEAF_wlanIfaceRegDomain:
203509cbe818SShteryana Shopova 			return (wlan_config_get_country(wif));
203609cbe818SShteryana Shopova 		case LEAF_wlanIfaceDesiredSsid:
203709cbe818SShteryana Shopova 			return (wlan_config_get_dssid(wif));
203809cbe818SShteryana Shopova 		case LEAF_wlanIfaceDesiredChannel:
203909cbe818SShteryana Shopova 			return (wlan_config_get_dchannel(wif));
204009cbe818SShteryana Shopova 		case LEAF_wlanIfaceDesiredBssid:
204109cbe818SShteryana Shopova 			return (wlan_config_get_bssid(wif));
204209cbe818SShteryana Shopova 		default:
204309cbe818SShteryana Shopova 			op = wlan_config_snmp2ioctl(which);
204409cbe818SShteryana Shopova 			return (wlan_config_get_intval(wif, op));
204509cbe818SShteryana Shopova 	}
204609cbe818SShteryana Shopova 
204709cbe818SShteryana Shopova 	return (-1);
204809cbe818SShteryana Shopova }
204909cbe818SShteryana Shopova 
205009cbe818SShteryana Shopova int
wlan_config_set_ioctl(struct wlan_iface * wif,int which,int val,char * strval,int len)205109cbe818SShteryana Shopova wlan_config_set_ioctl(struct wlan_iface *wif, int which, int val,
205209cbe818SShteryana Shopova     char *strval, int len)
205309cbe818SShteryana Shopova {
205409cbe818SShteryana Shopova 	int op;
205509cbe818SShteryana Shopova 
205609cbe818SShteryana Shopova 	switch (which) {
205709cbe818SShteryana Shopova 		case LEAF_wlanIfaceCountryCode:
205809cbe818SShteryana Shopova 			return (wlan_config_set_country(wif, strval,
205909cbe818SShteryana Shopova 			    wif->reg_domain));
206009cbe818SShteryana Shopova 		case LEAF_wlanIfaceRegDomain:
206109cbe818SShteryana Shopova 			return (wlan_config_set_country(wif, wif->country_code,
206209cbe818SShteryana Shopova 			    val));
206309cbe818SShteryana Shopova 		case LEAF_wlanIfaceDesiredSsid:
206409cbe818SShteryana Shopova 			return (wlan_config_set_dssid(wif, strval, len));
206509cbe818SShteryana Shopova 		case LEAF_wlanIfaceDesiredChannel:
206609cbe818SShteryana Shopova 			return (wlan_config_set_dchannel(wif, val));
206709cbe818SShteryana Shopova 		case LEAF_wlanIfaceDesiredBssid:
206809cbe818SShteryana Shopova 			return (wlan_config_set_bssid(wif, strval));
206909cbe818SShteryana Shopova 		default:
207009cbe818SShteryana Shopova 			op = wlan_config_snmp2ioctl(which);
207109cbe818SShteryana Shopova 			return (wlan_config_set_intval(wif, op, val));
207209cbe818SShteryana Shopova 	}
207309cbe818SShteryana Shopova 
207409cbe818SShteryana Shopova 	return (-1);
207509cbe818SShteryana Shopova }
207609cbe818SShteryana Shopova 
207709cbe818SShteryana Shopova static uint32_t
wlan_snmp_to_scan_flags(int flags)207809cbe818SShteryana Shopova wlan_snmp_to_scan_flags(int flags)
207909cbe818SShteryana Shopova {
208009cbe818SShteryana Shopova 	int sr_flags = 0;
208109cbe818SShteryana Shopova 
208209cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_noSelection)) != 0)
208309cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_NOPICK;
208409cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_activeScan)) != 0)
208509cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_ACTIVE;
208609cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_pickFirst)) != 0)
208709cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_PICK1ST;
208809cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_backgroundScan)) != 0)
208909cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_BGSCAN;
209009cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_once)) != 0)
209109cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_ONCE;
209209cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_noBroadcast)) != 0)
209309cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_NOBCAST;
209409cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_noAutoSequencing)) != 0)
209509cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_NOJOIN;
209609cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_flushCashe)) != 0)
209709cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_FLUSH;
209809cbe818SShteryana Shopova 	if ((flags & (0x1 << WlanScanFlagsType_chechCashe)) != 0)
209909cbe818SShteryana Shopova 		sr_flags |= IEEE80211_IOC_SCAN_CHECK;
210009cbe818SShteryana Shopova 
210109cbe818SShteryana Shopova 	return (sr_flags);
210209cbe818SShteryana Shopova }
210309cbe818SShteryana Shopova 
210409cbe818SShteryana Shopova int
wlan_set_scan_config(struct wlan_iface * wif)210509cbe818SShteryana Shopova wlan_set_scan_config(struct wlan_iface *wif)
210609cbe818SShteryana Shopova {
210709cbe818SShteryana Shopova 	int val = 0;
210809cbe818SShteryana Shopova 	size_t argsize;
210909cbe818SShteryana Shopova 	struct ieee80211_scan_req sr;
211009cbe818SShteryana Shopova 
211109cbe818SShteryana Shopova 
211209cbe818SShteryana Shopova 	memset(&sr, 0, sizeof(sr));
211309cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211_scan_req);
211409cbe818SShteryana Shopova 	sr.sr_flags = wlan_snmp_to_scan_flags(wif->scan_flags);
211509cbe818SShteryana Shopova 	sr.sr_flags |= IEEE80211_IOC_SCAN_BGSCAN;
211609cbe818SShteryana Shopova 	sr.sr_duration = wif->scan_duration;
211709cbe818SShteryana Shopova 	sr.sr_mindwell = wif->scan_mindwell;
211809cbe818SShteryana Shopova 	sr.sr_maxdwell = wif->scan_maxdwell;
211909cbe818SShteryana Shopova 	sr.sr_nssid = 0;
212009cbe818SShteryana Shopova 
212109cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_REQ,
212209cbe818SShteryana Shopova 	    &val, &sr, &argsize, 1) < 0)
212309cbe818SShteryana Shopova 		return (-1);
212409cbe818SShteryana Shopova 
212509cbe818SShteryana Shopova 	wif->scan_status = wlanScanConfigStatus_running;
212609cbe818SShteryana Shopova 	return (0);
212709cbe818SShteryana Shopova }
212809cbe818SShteryana Shopova 
212909cbe818SShteryana Shopova static uint32_t
wlan_peercaps_to_snmp(uint32_t pcaps)213009cbe818SShteryana Shopova wlan_peercaps_to_snmp(uint32_t pcaps)
213109cbe818SShteryana Shopova {
213209cbe818SShteryana Shopova 	uint32_t scaps = 0;
213309cbe818SShteryana Shopova 
213409cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_ESS) != 0)
213509cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_ess);
213609cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_IBSS) != 0)
213709cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_ibss);
213809cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_CF_POLLABLE) != 0)
213909cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollable);
214009cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_CF_POLLREQ) != 0)
214109cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollRequest);
214209cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_PRIVACY) != 0)
214309cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_privacy);
214409cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_SHORT_PREAMBLE) != 0)
214509cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_shortPreamble);
214609cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_PBCC) != 0)
214709cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_pbcc);
214809cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_CHNL_AGILITY) != 0)
214909cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_channelAgility);
215009cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_SHORT_SLOTTIME) != 0)
215109cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_shortSlotTime);
215209cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_RSN) != 0)
215309cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_rsn);
215409cbe818SShteryana Shopova 	if ((pcaps & IEEE80211_CAPINFO_DSSSOFDM) != 0)
215509cbe818SShteryana Shopova 		scaps |= (0x1 << WlanPeerCapabilityFlags_dsssofdm);
215609cbe818SShteryana Shopova 
215709cbe818SShteryana Shopova 	return (scaps);
215809cbe818SShteryana Shopova }
215909cbe818SShteryana Shopova 
216009cbe818SShteryana Shopova static int
wlan_add_new_scan_result(struct wlan_iface * wif,const struct ieee80211req_scan_result * isr,uint8_t * ssid)216109cbe818SShteryana Shopova wlan_add_new_scan_result(struct wlan_iface *wif,
216209cbe818SShteryana Shopova     const struct ieee80211req_scan_result *isr, uint8_t *ssid)
216309cbe818SShteryana Shopova {
216409cbe818SShteryana Shopova 	struct wlan_scan_result *sr;
216509cbe818SShteryana Shopova 
216609cbe818SShteryana Shopova 	if ((sr = wlan_scan_new_result(ssid, isr->isr_bssid)) == NULL)
216709cbe818SShteryana Shopova 		return (-1);
216809cbe818SShteryana Shopova 
216909cbe818SShteryana Shopova 	sr->opchannel = wlan_channel_flags_to_snmp_phy(isr->isr_flags);
217009cbe818SShteryana Shopova 	sr->rssi = isr->isr_rssi;
217109cbe818SShteryana Shopova 	sr->frequency = isr->isr_freq;
217209cbe818SShteryana Shopova 	sr->noise = isr->isr_noise;
217309cbe818SShteryana Shopova 	sr->bintval = isr->isr_intval;
217409cbe818SShteryana Shopova 	sr->capinfo = wlan_peercaps_to_snmp(isr->isr_capinfo);
217509cbe818SShteryana Shopova 
217609cbe818SShteryana Shopova 	if (wlan_scan_add_result(wif, sr) < 0) {
217709cbe818SShteryana Shopova 		wlan_scan_free_result(sr);
217809cbe818SShteryana Shopova 		return (-1);
217909cbe818SShteryana Shopova 	}
218009cbe818SShteryana Shopova 
218109cbe818SShteryana Shopova 	return (0);
218209cbe818SShteryana Shopova }
218309cbe818SShteryana Shopova 
218409cbe818SShteryana Shopova int
wlan_get_scan_results(struct wlan_iface * wif)218509cbe818SShteryana Shopova wlan_get_scan_results(struct wlan_iface *wif)
218609cbe818SShteryana Shopova {
218709cbe818SShteryana Shopova 	int ssidlen, val = 0;
218809cbe818SShteryana Shopova 	uint8_t buf[24 * 1024];
218909cbe818SShteryana Shopova 	size_t argsize;
219009cbe818SShteryana Shopova 	const uint8_t *cp, *idp;
219109cbe818SShteryana Shopova 	uint8_t ssid[IEEE80211_NWID_LEN + 1];
219209cbe818SShteryana Shopova 	struct ieee80211req_scan_result isr;
219309cbe818SShteryana Shopova 
219409cbe818SShteryana Shopova 	argsize = sizeof(buf);
219509cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_RESULTS, &val, &buf,
219609cbe818SShteryana Shopova 	    &argsize, 0) < 0)
219709cbe818SShteryana Shopova 		return (-1);
219809cbe818SShteryana Shopova 
219909cbe818SShteryana Shopova 	if (argsize < sizeof(struct ieee80211req_scan_result))
220009cbe818SShteryana Shopova 		return (0);
220109cbe818SShteryana Shopova 
220209cbe818SShteryana Shopova 	cp = buf;
220309cbe818SShteryana Shopova 	do {
220409cbe818SShteryana Shopova 		memcpy(&isr, cp, sizeof(struct ieee80211req_scan_result));
220509cbe818SShteryana Shopova 		memset(ssid, 0, IEEE80211_NWID_LEN + 1);
220609cbe818SShteryana Shopova 
220709cbe818SShteryana Shopova 		if (isr.isr_meshid_len) {
220809cbe818SShteryana Shopova 			idp = cp + isr.isr_ie_off + isr.isr_ssid_len;
220909cbe818SShteryana Shopova 			ssidlen = isr.isr_meshid_len;
221009cbe818SShteryana Shopova 		} else {
221109cbe818SShteryana Shopova 			idp = cp + isr.isr_ie_off;
221209cbe818SShteryana Shopova 			ssidlen = isr.isr_ssid_len;
221309cbe818SShteryana Shopova 		}
221409cbe818SShteryana Shopova 		if (ssidlen > IEEE80211_NWID_LEN)
221509cbe818SShteryana Shopova 			ssidlen = IEEE80211_NWID_LEN;
221609cbe818SShteryana Shopova 		memcpy(ssid, idp, ssidlen);
221709cbe818SShteryana Shopova 		ssid[IEEE80211_NWID_LEN] = '\0';
221809cbe818SShteryana Shopova 		(void)wlan_add_new_scan_result(wif, &isr, ssid);
221909cbe818SShteryana Shopova 		cp += isr.isr_len;
222009cbe818SShteryana Shopova 		argsize -= isr.isr_len;
222109cbe818SShteryana Shopova 	} while (argsize >= sizeof(struct ieee80211req_scan_result));
222209cbe818SShteryana Shopova 
222309cbe818SShteryana Shopova 	return (0);
222409cbe818SShteryana Shopova }
222509cbe818SShteryana Shopova 
222609cbe818SShteryana Shopova int
wlan_get_stats(struct wlan_iface * wif)222709cbe818SShteryana Shopova wlan_get_stats(struct wlan_iface *wif)
222809cbe818SShteryana Shopova {
222909cbe818SShteryana Shopova 	struct ifreq ifr;
223009cbe818SShteryana Shopova 
223109cbe818SShteryana Shopova 	memset(&ifr, 0, sizeof(struct ifreq));
223209cbe818SShteryana Shopova 	strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ);
223309cbe818SShteryana Shopova 
223409cbe818SShteryana Shopova 	ifr.ifr_data = (caddr_t) &wif->stats;
223509cbe818SShteryana Shopova 
223609cbe818SShteryana Shopova 	if (ioctl(sock, SIOCG80211STATS, &ifr) < 0) {
223709cbe818SShteryana Shopova 		syslog(LOG_ERR, "iface %s - ioctl(SIOCG80211STATS) failed: %s",
223809cbe818SShteryana Shopova 		    wif->wname, strerror(errno));
223909cbe818SShteryana Shopova 		return (-1);
224009cbe818SShteryana Shopova 	}
224109cbe818SShteryana Shopova 
224209cbe818SShteryana Shopova 	return (0);
224309cbe818SShteryana Shopova }
224409cbe818SShteryana Shopova 
224509cbe818SShteryana Shopova int
wlan_get_wepmode(struct wlan_iface * wif)224609cbe818SShteryana Shopova wlan_get_wepmode(struct wlan_iface *wif)
224709cbe818SShteryana Shopova {
224809cbe818SShteryana Shopova 	int val = 0;
224909cbe818SShteryana Shopova 	size_t argsize = 0;
225009cbe818SShteryana Shopova 
225109cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL,
225209cbe818SShteryana Shopova 	    &argsize, 0) < 0 || val == IEEE80211_WEP_NOSUP) {
225309cbe818SShteryana Shopova 		wif->wepsupported = 0; /* XXX */
225409cbe818SShteryana Shopova 		wif->wepmode = wlanWepMode_off;
225509cbe818SShteryana Shopova 		wif->weptxkey = 0;
225609cbe818SShteryana Shopova 		return (-1);
225709cbe818SShteryana Shopova 	}
225809cbe818SShteryana Shopova 
225909cbe818SShteryana Shopova 	wif->wepsupported = 1;
226009cbe818SShteryana Shopova 
226109cbe818SShteryana Shopova 	switch (val) {
226209cbe818SShteryana Shopova 	case IEEE80211_WEP_ON:
226309cbe818SShteryana Shopova 		wif->wepmode = wlanWepMode_on;
226409cbe818SShteryana Shopova 		break;
226509cbe818SShteryana Shopova 	case IEEE80211_WEP_MIXED:
226609cbe818SShteryana Shopova 		wif->wepmode = wlanWepMode_mixed;
226709cbe818SShteryana Shopova 		break;
226809cbe818SShteryana Shopova 	case IEEE80211_WEP_OFF:
226909cbe818SShteryana Shopova 		/* FALLTHROUGH */
227009cbe818SShteryana Shopova 	default:
227109cbe818SShteryana Shopova 		wif->wepmode = wlanWepMode_off;
227209cbe818SShteryana Shopova 		break;
227309cbe818SShteryana Shopova 	}
227409cbe818SShteryana Shopova 
227509cbe818SShteryana Shopova 	return (0);
227609cbe818SShteryana Shopova }
227709cbe818SShteryana Shopova 
227809cbe818SShteryana Shopova int
wlan_set_wepmode(struct wlan_iface * wif)227909cbe818SShteryana Shopova wlan_set_wepmode(struct wlan_iface *wif)
228009cbe818SShteryana Shopova {
228109cbe818SShteryana Shopova 	int val;
228209cbe818SShteryana Shopova 	size_t argsize = 0;
228309cbe818SShteryana Shopova 
228409cbe818SShteryana Shopova 	if (!wif->wepsupported)
228509cbe818SShteryana Shopova 		return (-1);
228609cbe818SShteryana Shopova 
228709cbe818SShteryana Shopova 	switch (wif->wepmode) {
228809cbe818SShteryana Shopova 	case wlanWepMode_off:
228909cbe818SShteryana Shopova 		val = IEEE80211_WEP_OFF;
229009cbe818SShteryana Shopova 		break;
229109cbe818SShteryana Shopova 	case wlanWepMode_on:
229209cbe818SShteryana Shopova 		val = IEEE80211_WEP_ON;
229309cbe818SShteryana Shopova 		break;
229409cbe818SShteryana Shopova 	case wlanWepMode_mixed:
229509cbe818SShteryana Shopova 		val = IEEE80211_WEP_MIXED;
229609cbe818SShteryana Shopova 		break;
229709cbe818SShteryana Shopova 	default:
229809cbe818SShteryana Shopova 		return (-1);
229909cbe818SShteryana Shopova 	}
230009cbe818SShteryana Shopova 
230109cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL,
230209cbe818SShteryana Shopova 	    &argsize, 1) < 0)
230309cbe818SShteryana Shopova 		return (-1);
230409cbe818SShteryana Shopova 
230509cbe818SShteryana Shopova 	return (0);
230609cbe818SShteryana Shopova }
230709cbe818SShteryana Shopova 
230809cbe818SShteryana Shopova int
wlan_get_weptxkey(struct wlan_iface * wif)230909cbe818SShteryana Shopova wlan_get_weptxkey(struct wlan_iface *wif)
231009cbe818SShteryana Shopova {
231109cbe818SShteryana Shopova 	int val;
231209cbe818SShteryana Shopova 	size_t argsize = 0;
231309cbe818SShteryana Shopova 
231409cbe818SShteryana Shopova 	if (!wif->wepsupported)
231509cbe818SShteryana Shopova 		return (0);
231609cbe818SShteryana Shopova 
231709cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL,
231809cbe818SShteryana Shopova 	    &argsize, 0) < 0)
231909cbe818SShteryana Shopova 		return (-1);
232009cbe818SShteryana Shopova 
232109cbe818SShteryana Shopova 	if (val == IEEE80211_KEYIX_NONE)
232209cbe818SShteryana Shopova 		wif->weptxkey = 0;
232309cbe818SShteryana Shopova 	else
232409cbe818SShteryana Shopova 		wif->weptxkey = val + 1;
232509cbe818SShteryana Shopova 
232609cbe818SShteryana Shopova 	return (0);
232709cbe818SShteryana Shopova }
232809cbe818SShteryana Shopova 
232909cbe818SShteryana Shopova int
wlan_set_weptxkey(struct wlan_iface * wif)233009cbe818SShteryana Shopova wlan_set_weptxkey(struct wlan_iface *wif)
233109cbe818SShteryana Shopova {
233209cbe818SShteryana Shopova 	int val;
233309cbe818SShteryana Shopova 	size_t argsize = 0;
233409cbe818SShteryana Shopova 
233509cbe818SShteryana Shopova 	if (!wif->wepsupported)
233609cbe818SShteryana Shopova 		return (0);
233709cbe818SShteryana Shopova 
233809cbe818SShteryana Shopova 	if (wif->weptxkey >= IEEE80211_WEP_NKID)
233909cbe818SShteryana Shopova 		return (-1);
234009cbe818SShteryana Shopova 
234109cbe818SShteryana Shopova 	if (wif->weptxkey == 0)
234209cbe818SShteryana Shopova 		val = IEEE80211_KEYIX_NONE;
234309cbe818SShteryana Shopova 	else
234409cbe818SShteryana Shopova 		val = wif->weptxkey - 1;
234509cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL,
234609cbe818SShteryana Shopova 	    &argsize, 1) < 0)
234709cbe818SShteryana Shopova 		return (-1);
234809cbe818SShteryana Shopova 
234909cbe818SShteryana Shopova 	return (0);
235009cbe818SShteryana Shopova }
235109cbe818SShteryana Shopova 
235209cbe818SShteryana Shopova int
wlan_get_wepkeys(struct wlan_iface * wif __unused)235309cbe818SShteryana Shopova wlan_get_wepkeys(struct wlan_iface *wif __unused)
235409cbe818SShteryana Shopova {
235509cbe818SShteryana Shopova 	/* XXX: should they be visible via SNMP */
235609cbe818SShteryana Shopova 	return (0);
235709cbe818SShteryana Shopova }
235809cbe818SShteryana Shopova 
235909cbe818SShteryana Shopova int
wlan_set_wepkeys(struct wlan_iface * wif __unused)236009cbe818SShteryana Shopova wlan_set_wepkeys(struct wlan_iface *wif __unused)
236109cbe818SShteryana Shopova {
236209cbe818SShteryana Shopova 	/* XXX: should they be configurable via SNMP */
236309cbe818SShteryana Shopova 	return (0);
236409cbe818SShteryana Shopova }
236509cbe818SShteryana Shopova 
236609cbe818SShteryana Shopova int
wlan_get_mac_policy(struct wlan_iface * wif)236709cbe818SShteryana Shopova wlan_get_mac_policy(struct wlan_iface *wif)
236809cbe818SShteryana Shopova {
236909cbe818SShteryana Shopova 	int val = IEEE80211_MACCMD_POLICY;
237009cbe818SShteryana Shopova 	size_t argsize = 0;
237109cbe818SShteryana Shopova 	struct ieee80211req ireq;
237209cbe818SShteryana Shopova 
237309cbe818SShteryana Shopova 	memset(&ireq, 0, sizeof(struct ieee80211req));
237409cbe818SShteryana Shopova 	strlcpy(ireq.i_name, wif->wname, IFNAMSIZ);
237509cbe818SShteryana Shopova 	ireq.i_type = IEEE80211_IOC_MACCMD;
237609cbe818SShteryana Shopova 	ireq.i_val = IEEE80211_MACCMD_POLICY;
237709cbe818SShteryana Shopova 
237809cbe818SShteryana Shopova 	if (ioctl(sock, SIOCG80211, &ireq) < 0) {
237909cbe818SShteryana Shopova 		if (errno != EINVAL) {
238009cbe818SShteryana Shopova 			syslog(LOG_ERR, "iface %s - get param: ioctl(%d) "
238109cbe818SShteryana Shopova 			    "failed: %s", wif->wname, ireq.i_type,
238209cbe818SShteryana Shopova 			    strerror(errno));
238309cbe818SShteryana Shopova 			wif->macsupported = 0;
238409cbe818SShteryana Shopova 			return (-1);
238509cbe818SShteryana Shopova 		} else {
238609cbe818SShteryana Shopova 			wif->macsupported = 1;
238709cbe818SShteryana Shopova 			wif->mac_policy = wlanMACAccessControlPolicy_open;
238809cbe818SShteryana Shopova 			return (0);
238909cbe818SShteryana Shopova 		}
239009cbe818SShteryana Shopova 
239109cbe818SShteryana Shopova 	}
239209cbe818SShteryana Shopova 
239309cbe818SShteryana Shopova 	wif->macsupported = 1;
239409cbe818SShteryana Shopova 
239509cbe818SShteryana Shopova 	switch (val) {
239609cbe818SShteryana Shopova 	case IEEE80211_MACCMD_POLICY_ALLOW:
239709cbe818SShteryana Shopova 		wif->mac_policy = wlanMACAccessControlPolicy_allow;
239809cbe818SShteryana Shopova 		break;
239909cbe818SShteryana Shopova 	case IEEE80211_MACCMD_POLICY_DENY:
240009cbe818SShteryana Shopova 		wif->mac_policy = wlanMACAccessControlPolicy_deny;
240109cbe818SShteryana Shopova 		break;
240209cbe818SShteryana Shopova 	case IEEE80211_MACCMD_POLICY_RADIUS:
240309cbe818SShteryana Shopova 		wif->mac_policy = wlanMACAccessControlPolicy_radius;
240409cbe818SShteryana Shopova 		break;
240509cbe818SShteryana Shopova 	case IEEE80211_MACCMD_POLICY_OPEN:
240609cbe818SShteryana Shopova 		/* FALLTHROUGH */
240709cbe818SShteryana Shopova 	default:
240809cbe818SShteryana Shopova 		wif->mac_policy = wlanMACAccessControlPolicy_open;
240909cbe818SShteryana Shopova 		break;
241009cbe818SShteryana Shopova 	}
241109cbe818SShteryana Shopova 
241209cbe818SShteryana Shopova 	argsize = 0;
241309cbe818SShteryana Shopova 	val = IEEE80211_MACCMD_LIST;
241409cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL,
241509cbe818SShteryana Shopova 	    &argsize, 0) < 0)
241609cbe818SShteryana Shopova 		return (-1);
241709cbe818SShteryana Shopova 
241809cbe818SShteryana Shopova 	wif->mac_nacls = argsize / sizeof(struct ieee80211req_maclist *);
241909cbe818SShteryana Shopova 	return (0);
242009cbe818SShteryana Shopova }
242109cbe818SShteryana Shopova 
242209cbe818SShteryana Shopova int
wlan_set_mac_policy(struct wlan_iface * wif)242309cbe818SShteryana Shopova wlan_set_mac_policy(struct wlan_iface *wif)
242409cbe818SShteryana Shopova {
242509cbe818SShteryana Shopova 	int val;
242609cbe818SShteryana Shopova 	size_t argsize = 0;
242709cbe818SShteryana Shopova 
242809cbe818SShteryana Shopova 	if (!wif->macsupported)
242909cbe818SShteryana Shopova 		return (-1);
243009cbe818SShteryana Shopova 
243109cbe818SShteryana Shopova 	switch (wif->mac_policy) {
243209cbe818SShteryana Shopova 	case wlanMACAccessControlPolicy_allow:
243309cbe818SShteryana Shopova 		val = IEEE80211_MACCMD_POLICY_ALLOW;
243409cbe818SShteryana Shopova 		break;
243509cbe818SShteryana Shopova 	case wlanMACAccessControlPolicy_deny:
243609cbe818SShteryana Shopova 		val = IEEE80211_MACCMD_POLICY_DENY;
243709cbe818SShteryana Shopova 		break;
243809cbe818SShteryana Shopova 	case wlanMACAccessControlPolicy_radius:
243909cbe818SShteryana Shopova 		val = IEEE80211_MACCMD_POLICY_RADIUS;
244009cbe818SShteryana Shopova 		break;
244109cbe818SShteryana Shopova 	case wlanMACAccessControlPolicy_open:
244209cbe818SShteryana Shopova 		val = IEEE80211_MACCMD_POLICY_OPEN;
244309cbe818SShteryana Shopova 		break;
244409cbe818SShteryana Shopova 	default:
244509cbe818SShteryana Shopova 		return (-1);
244609cbe818SShteryana Shopova 	}
244709cbe818SShteryana Shopova 
244809cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL,
244909cbe818SShteryana Shopova 	    &argsize, 1) < 0)
245009cbe818SShteryana Shopova 		return (-1);
245109cbe818SShteryana Shopova 
245209cbe818SShteryana Shopova 	return (0);
245309cbe818SShteryana Shopova }
245409cbe818SShteryana Shopova 
245509cbe818SShteryana Shopova int
wlan_flush_mac_mac(struct wlan_iface * wif)245609cbe818SShteryana Shopova wlan_flush_mac_mac(struct wlan_iface *wif)
245709cbe818SShteryana Shopova {
245809cbe818SShteryana Shopova 	int val = IEEE80211_MACCMD_FLUSH;
245909cbe818SShteryana Shopova 	size_t argsize = 0;
246009cbe818SShteryana Shopova 
246109cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL,
246209cbe818SShteryana Shopova 	    &argsize, 1) < 0)
246309cbe818SShteryana Shopova 		return (-1);
246409cbe818SShteryana Shopova 
246509cbe818SShteryana Shopova 	return (0);
246609cbe818SShteryana Shopova }
246709cbe818SShteryana Shopova 
246809cbe818SShteryana Shopova static int
wlan_add_mac_macinfo(struct wlan_iface * wif,const struct ieee80211req_maclist * ml)246909cbe818SShteryana Shopova wlan_add_mac_macinfo(struct wlan_iface *wif,
247009cbe818SShteryana Shopova     const struct ieee80211req_maclist *ml)
247109cbe818SShteryana Shopova {
247209cbe818SShteryana Shopova 	struct wlan_mac_mac *mmac;
247309cbe818SShteryana Shopova 
247409cbe818SShteryana Shopova 	if ((mmac = wlan_mac_new_mac(ml->ml_macaddr)) == NULL)
247509cbe818SShteryana Shopova 		return (-1);
247609cbe818SShteryana Shopova 
247709cbe818SShteryana Shopova 	mmac->mac_status = RowStatus_active;
247809cbe818SShteryana Shopova 	if (wlan_mac_add_mac(wif, mmac) < 0) {
247909cbe818SShteryana Shopova 		wlan_mac_free_mac(mmac);
248009cbe818SShteryana Shopova 		return (-1);
248109cbe818SShteryana Shopova 	}
248209cbe818SShteryana Shopova 
248309cbe818SShteryana Shopova 	return (0);
248409cbe818SShteryana Shopova }
248509cbe818SShteryana Shopova 
248609cbe818SShteryana Shopova int
wlan_get_mac_acl_macs(struct wlan_iface * wif)248709cbe818SShteryana Shopova wlan_get_mac_acl_macs(struct wlan_iface *wif)
248809cbe818SShteryana Shopova {
248909cbe818SShteryana Shopova 	int i, nacls, val = IEEE80211_MACCMD_LIST;
249009cbe818SShteryana Shopova 	size_t argsize = 0;
249109cbe818SShteryana Shopova 	uint8_t *data;
249209cbe818SShteryana Shopova 	struct ieee80211req ireq;
249309cbe818SShteryana Shopova 	const struct ieee80211req_maclist *acllist;
249409cbe818SShteryana Shopova 
249509cbe818SShteryana Shopova 	if (wif->mac_policy == wlanMACAccessControlPolicy_radius) {
249609cbe818SShteryana Shopova 		wif->mac_nacls = 0;
249709cbe818SShteryana Shopova 		return (0);
249809cbe818SShteryana Shopova 	}
249909cbe818SShteryana Shopova 
250009cbe818SShteryana Shopova 	memset(&ireq, 0, sizeof(struct ieee80211req));
250109cbe818SShteryana Shopova 	strlcpy(ireq.i_name, wif->wname, IFNAMSIZ);
250209cbe818SShteryana Shopova 	ireq.i_type = IEEE80211_IOC_MACCMD;
250309cbe818SShteryana Shopova 	ireq.i_val = IEEE80211_MACCMD_LIST;
250409cbe818SShteryana Shopova 
250509cbe818SShteryana Shopova 
250609cbe818SShteryana Shopova 	if (ioctl(sock, SIOCG80211, &ireq) < 0) {
250709cbe818SShteryana Shopova 		if (errno != EINVAL) {
250809cbe818SShteryana Shopova 			syslog(LOG_ERR, "iface %s - get param: ioctl(%d) "
250909cbe818SShteryana Shopova 			    "failed: %s", wif->wname, ireq.i_type,
251009cbe818SShteryana Shopova 			    strerror(errno));
251109cbe818SShteryana Shopova 			wif->macsupported = 0;
251209cbe818SShteryana Shopova 			return (-1);
251309cbe818SShteryana Shopova 		}
251409cbe818SShteryana Shopova 	}
251509cbe818SShteryana Shopova 
251609cbe818SShteryana Shopova 	if (argsize == 0) {
251709cbe818SShteryana Shopova 		wif->mac_nacls = 0;
251809cbe818SShteryana Shopova 		return (0);
251909cbe818SShteryana Shopova 	}
252009cbe818SShteryana Shopova 
252109cbe818SShteryana Shopova 	if ((data = (uint8_t *)malloc(argsize)) == NULL)
252209cbe818SShteryana Shopova 		return (-1);
252309cbe818SShteryana Shopova 
252409cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, data,
252509cbe818SShteryana Shopova 	    &argsize, 0) < 0)
252609cbe818SShteryana Shopova 		return (-1);
252709cbe818SShteryana Shopova 
252809cbe818SShteryana Shopova 	nacls = argsize / sizeof(*acllist);
252909cbe818SShteryana Shopova 	acllist = (struct ieee80211req_maclist *) data;
253009cbe818SShteryana Shopova 	for (i = 0; i < nacls; i++)
253109cbe818SShteryana Shopova 		(void)wlan_add_mac_macinfo(wif, acllist + i);
253209cbe818SShteryana Shopova 
253309cbe818SShteryana Shopova 	wif->mac_nacls = nacls;
253409cbe818SShteryana Shopova 	return (0);
253509cbe818SShteryana Shopova }
253609cbe818SShteryana Shopova 
253709cbe818SShteryana Shopova int
wlan_add_mac_acl_mac(struct wlan_iface * wif,struct wlan_mac_mac * mmac)253809cbe818SShteryana Shopova wlan_add_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac)
253909cbe818SShteryana Shopova {
254009cbe818SShteryana Shopova 	int val = 0;
254109cbe818SShteryana Shopova 	size_t argsize = IEEE80211_ADDR_LEN;
254209cbe818SShteryana Shopova 	struct ieee80211req_mlme mlme;
254309cbe818SShteryana Shopova 
254409cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_ADDMAC, &val,
254509cbe818SShteryana Shopova 	    mmac->mac, &argsize, 1) < 0)
254609cbe818SShteryana Shopova 		return (-1);
254709cbe818SShteryana Shopova 
254809cbe818SShteryana Shopova 	mmac->mac_status = RowStatus_active;
254909cbe818SShteryana Shopova 
255009cbe818SShteryana Shopova 	/* If policy is deny, try to kick the station just in case. */
255109cbe818SShteryana Shopova 	if (wif->mac_policy != wlanMACAccessControlPolicy_deny)
255209cbe818SShteryana Shopova 		return (0);
255309cbe818SShteryana Shopova 
255409cbe818SShteryana Shopova 	memset(&mlme, 0, sizeof(mlme));
255509cbe818SShteryana Shopova 	mlme.im_op = IEEE80211_MLME_DEAUTH;
255609cbe818SShteryana Shopova 	mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE;
255709cbe818SShteryana Shopova 	memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN);
255809cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211req_mlme);
255909cbe818SShteryana Shopova 
256009cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme,
256109cbe818SShteryana Shopova 	    &argsize, 1) < 0 && errno != ENOENT)
256209cbe818SShteryana Shopova 		return (-1);
256309cbe818SShteryana Shopova 
256409cbe818SShteryana Shopova 	return (0);
256509cbe818SShteryana Shopova }
256609cbe818SShteryana Shopova 
256709cbe818SShteryana Shopova int
wlan_del_mac_acl_mac(struct wlan_iface * wif,struct wlan_mac_mac * mmac)256809cbe818SShteryana Shopova wlan_del_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac)
256909cbe818SShteryana Shopova {
257009cbe818SShteryana Shopova 	int val = 0;
257109cbe818SShteryana Shopova 	size_t argsize = IEEE80211_ADDR_LEN;
257209cbe818SShteryana Shopova 	struct ieee80211req_mlme mlme;
257309cbe818SShteryana Shopova 
257409cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_DELMAC, &val,
257509cbe818SShteryana Shopova 	    mmac->mac, &argsize, 1) < 0)
257609cbe818SShteryana Shopova 		return (-1);
257709cbe818SShteryana Shopova 
257809cbe818SShteryana Shopova 	mmac->mac_status = RowStatus_active;
257909cbe818SShteryana Shopova 
258009cbe818SShteryana Shopova 	/* If policy is allow, try to kick the station just in case. */
258109cbe818SShteryana Shopova 	if (wif->mac_policy != wlanMACAccessControlPolicy_allow)
258209cbe818SShteryana Shopova 		return (0);
258309cbe818SShteryana Shopova 
258409cbe818SShteryana Shopova 	memset(&mlme, 0, sizeof(mlme));
258509cbe818SShteryana Shopova 	mlme.im_op = IEEE80211_MLME_DEAUTH;
258609cbe818SShteryana Shopova 	mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE;
258709cbe818SShteryana Shopova 	memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN);
258809cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211req_mlme);
258909cbe818SShteryana Shopova 
259009cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme,
259109cbe818SShteryana Shopova 	    &argsize, 1) < 0 && errno != ENOENT)
259209cbe818SShteryana Shopova 		return (-1);
259309cbe818SShteryana Shopova 
259409cbe818SShteryana Shopova 	return (0);
259509cbe818SShteryana Shopova }
259609cbe818SShteryana Shopova 
259709cbe818SShteryana Shopova int
wlan_peer_set_vlan(struct wlan_iface * wif,struct wlan_peer * wip,int vlan)259809cbe818SShteryana Shopova wlan_peer_set_vlan(struct wlan_iface *wif, struct wlan_peer *wip, int vlan)
259909cbe818SShteryana Shopova {
260009cbe818SShteryana Shopova 	int val = 0;
260109cbe818SShteryana Shopova 	size_t argsize;
260209cbe818SShteryana Shopova 	struct ieee80211req_sta_vlan vreq;
260309cbe818SShteryana Shopova 
260409cbe818SShteryana Shopova 	memcpy(vreq.sv_macaddr, wip->pmac, IEEE80211_ADDR_LEN);
260509cbe818SShteryana Shopova 	vreq.sv_vlan = vlan;
260609cbe818SShteryana Shopova 	argsize = sizeof(struct ieee80211req_sta_vlan);
260709cbe818SShteryana Shopova 
260809cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_VLAN,
260909cbe818SShteryana Shopova 	    &val, &vreq, &argsize, 1) < 0)
261009cbe818SShteryana Shopova 		return (-1);
261109cbe818SShteryana Shopova 
261209cbe818SShteryana Shopova 	wip->vlan = vlan;
261309cbe818SShteryana Shopova 
261409cbe818SShteryana Shopova 	return (0);
261509cbe818SShteryana Shopova }
261609cbe818SShteryana Shopova 
261709cbe818SShteryana Shopova /* XXX */
261809cbe818SShteryana Shopova #ifndef IEEE80211_NODE_AUTH
261909cbe818SShteryana Shopova #define	IEEE80211_NODE_AUTH	0x000001	/* authorized for data */
262009cbe818SShteryana Shopova #define	IEEE80211_NODE_QOS	0x000002	/* QoS enabled */
262109cbe818SShteryana Shopova #define	IEEE80211_NODE_ERP	0x000004	/* ERP enabled */
262209cbe818SShteryana Shopova #define	IEEE80211_NODE_PWR_MGT	0x000010	/* power save mode enabled */
262309cbe818SShteryana Shopova #define	IEEE80211_NODE_AREF	0x000020	/* authentication ref held */
262409cbe818SShteryana Shopova #define	IEEE80211_NODE_HT	0x000040	/* HT enabled */
262509cbe818SShteryana Shopova #define	IEEE80211_NODE_HTCOMPAT	0x000080	/* HT setup w/ vendor OUI's */
262609cbe818SShteryana Shopova #define	IEEE80211_NODE_WPS	0x000100	/* WPS association */
262709cbe818SShteryana Shopova #define	IEEE80211_NODE_TSN	0x000200	/* TSN association */
262809cbe818SShteryana Shopova #define	IEEE80211_NODE_AMPDU_RX	0x000400	/* AMPDU rx enabled */
262909cbe818SShteryana Shopova #define	IEEE80211_NODE_AMPDU_TX	0x000800	/* AMPDU tx enabled */
263009cbe818SShteryana Shopova #define	IEEE80211_NODE_MIMO_PS	0x001000	/* MIMO power save enabled */
263109cbe818SShteryana Shopova #define	IEEE80211_NODE_MIMO_RTS	0x002000	/* send RTS in MIMO PS */
263209cbe818SShteryana Shopova #define	IEEE80211_NODE_RIFS	0x004000	/* RIFS enabled */
263309cbe818SShteryana Shopova #define	IEEE80211_NODE_SGI20	0x008000	/* Short GI in HT20 enabled */
263409cbe818SShteryana Shopova #define	IEEE80211_NODE_SGI40	0x010000	/* Short GI in HT40 enabled */
263509cbe818SShteryana Shopova #define	IEEE80211_NODE_ASSOCID	0x020000	/* xmit requires associd */
263609cbe818SShteryana Shopova #define	IEEE80211_NODE_AMSDU_RX	0x040000	/* AMSDU rx enabled */
263709cbe818SShteryana Shopova #define	IEEE80211_NODE_AMSDU_TX	0x080000	/* AMSDU tx enabled */
263809cbe818SShteryana Shopova #endif
263909cbe818SShteryana Shopova 
264009cbe818SShteryana Shopova static uint32_t
wlan_peerstate_to_snmp(uint32_t pstate)264109cbe818SShteryana Shopova wlan_peerstate_to_snmp(uint32_t pstate)
264209cbe818SShteryana Shopova {
264309cbe818SShteryana Shopova 	uint32_t sstate = 0;
264409cbe818SShteryana Shopova 
264509cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_AUTH) != 0)
264609cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_authorizedForData);
264709cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_QOS) != 0)
264809cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_qosEnabled);
264909cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_ERP) != 0)
265009cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_erpEnabled);
265109cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_PWR_MGT) != 0)
265209cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_powerSaveMode);
265309cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_AREF) != 0)
265409cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_authRefHeld);
265509cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_HT) != 0)
265609cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_htEnabled);
265709cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_HTCOMPAT) != 0)
265809cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_htCompat);
265909cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_WPS) != 0)
266009cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_wpsAssoc);
266109cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_TSN) != 0)
266209cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_tsnAssoc);
266309cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_AMPDU_RX) != 0)
266409cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_ampduRx);
266509cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_AMPDU_TX) != 0)
266609cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_ampduTx);
266709cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_MIMO_PS) != 0)
266809cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_mimoPowerSave);
266909cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_MIMO_RTS) != 0)
267009cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_sendRts);
267109cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_RIFS) != 0)
267209cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_rifs);
267309cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_SGI20) != 0)
267409cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT20);
267509cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_SGI40) != 0)
267609cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT40);
267709cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_AMSDU_RX) != 0)
267809cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_amsduRx);
267909cbe818SShteryana Shopova 	if ((pstate & IEEE80211_NODE_AMSDU_TX) != 0)
268009cbe818SShteryana Shopova 		sstate |= (0x1 << WlanIfacePeerFlagsType_amsduTx);
268109cbe818SShteryana Shopova 
268209cbe818SShteryana Shopova 	return (sstate);
268309cbe818SShteryana Shopova }
268409cbe818SShteryana Shopova 
268509cbe818SShteryana Shopova static struct wlan_peer *
wlan_add_peerinfo(const struct ieee80211req_sta_info * si)268609cbe818SShteryana Shopova wlan_add_peerinfo(const struct ieee80211req_sta_info *si)
268709cbe818SShteryana Shopova {
268809cbe818SShteryana Shopova 	struct wlan_peer *wip;
268909cbe818SShteryana Shopova 
269009cbe818SShteryana Shopova 	if ((wip = wlan_new_peer(si->isi_macaddr))== NULL)
269109cbe818SShteryana Shopova 		return (NULL);
269209cbe818SShteryana Shopova 
269309cbe818SShteryana Shopova 	wip->associd = IEEE80211_AID(si->isi_associd);
269409cbe818SShteryana Shopova 	wip->vlan = si->isi_vlan;
269509cbe818SShteryana Shopova 	wip->frequency =  si->isi_freq;
269609cbe818SShteryana Shopova 	wip->fflags = si->isi_flags;
269709cbe818SShteryana Shopova 	wip->txrate = si->isi_txrate;
269809cbe818SShteryana Shopova 	wip->rssi = si->isi_rssi;
269909cbe818SShteryana Shopova 	wip->idle = si->isi_inact;
270009cbe818SShteryana Shopova 	wip->txseqs = si->isi_txseqs[0]; /* XXX */
270109cbe818SShteryana Shopova 	wip->rxseqs = si->isi_rxseqs[0]; /* XXX */
270209cbe818SShteryana Shopova 	wip->txpower = si->isi_txpower;
270309cbe818SShteryana Shopova 	wip->capinfo = wlan_peercaps_to_snmp(si->isi_capinfo);
270409cbe818SShteryana Shopova 	wip->state = wlan_peerstate_to_snmp(si->isi_state);
270509cbe818SShteryana Shopova 	wip->local_id = si->isi_localid;
270609cbe818SShteryana Shopova 	wip->peer_id = si->isi_peerid;
270709cbe818SShteryana Shopova 
270809cbe818SShteryana Shopova 	return (wip);
270909cbe818SShteryana Shopova }
271009cbe818SShteryana Shopova 
271109cbe818SShteryana Shopova int
wlan_get_peerinfo(struct wlan_iface * wif)271209cbe818SShteryana Shopova wlan_get_peerinfo(struct wlan_iface *wif)
271309cbe818SShteryana Shopova {
271409cbe818SShteryana Shopova 	union {
271509cbe818SShteryana Shopova 		struct ieee80211req_sta_req req;
271609cbe818SShteryana Shopova 		uint8_t buf[24 * 1024];
271709cbe818SShteryana Shopova 	} u;
271809cbe818SShteryana Shopova 	const uint8_t *cp;
271909cbe818SShteryana Shopova 	int val = 0;
272009cbe818SShteryana Shopova 	size_t len;
272109cbe818SShteryana Shopova 	struct ieee80211req_sta_info si;
272209cbe818SShteryana Shopova 	struct wlan_peer *wip;
272309cbe818SShteryana Shopova 
272409cbe818SShteryana Shopova 	/* Get all stations - broadcast address */
272509cbe818SShteryana Shopova 	(void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN);
272609cbe818SShteryana Shopova 	len =  sizeof(u);
272709cbe818SShteryana Shopova 
272809cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_INFO,
272909cbe818SShteryana Shopova 	    & val, &u, &len, 0) < 0)
273009cbe818SShteryana Shopova 		return (-1);
273109cbe818SShteryana Shopova 
273209cbe818SShteryana Shopova 	if (len < sizeof(struct ieee80211req_sta_info))
273309cbe818SShteryana Shopova 		return (-1);
273409cbe818SShteryana Shopova 
273509cbe818SShteryana Shopova 	cp = (const uint8_t *) u.req.info;
273609cbe818SShteryana Shopova 	do {
273709cbe818SShteryana Shopova 		memcpy(&si, cp, sizeof(struct ieee80211req_sta_info));
273809cbe818SShteryana Shopova 		if ((wip = wlan_add_peerinfo(&si)) != NULL &&
273909cbe818SShteryana Shopova 		    wlan_add_peer(wif, wip) < 0)
274009cbe818SShteryana Shopova 			wlan_free_peer(wip);
274109cbe818SShteryana Shopova 		cp += si.isi_len, len -= si.isi_len;
274209cbe818SShteryana Shopova 	} while (len >= sizeof(struct ieee80211req_sta_info));
274309cbe818SShteryana Shopova 
274409cbe818SShteryana Shopova 	return (0);
274509cbe818SShteryana Shopova }
274609cbe818SShteryana Shopova 
274709cbe818SShteryana Shopova /************************************************************************
274809cbe818SShteryana Shopova  * Wireless MESH & HWMP sysctl config.
274909cbe818SShteryana Shopova  */
275009cbe818SShteryana Shopova const char wlan_sysctl_name[] = "net.wlan.";
275109cbe818SShteryana Shopova 
275209cbe818SShteryana Shopova static const char *wlan_sysctl[] = {
275309cbe818SShteryana Shopova 	"mesh.retrytimeout",
275409cbe818SShteryana Shopova 	"mesh.holdingtimeout",
275509cbe818SShteryana Shopova 	"mesh.confirmtimeout",
275609cbe818SShteryana Shopova 	"mesh.maxretries",
275709cbe818SShteryana Shopova 	"hwmp.targetonly",
275809cbe818SShteryana Shopova 	"hwmp.replyforward",
275909cbe818SShteryana Shopova 	"hwmp.pathlifetime",
276009cbe818SShteryana Shopova 	"hwmp.roottimeout",
276109cbe818SShteryana Shopova 	"hwmp.rootint",
276209cbe818SShteryana Shopova 	"hwmp.rannint",
276309cbe818SShteryana Shopova 	"hwmp.inact",
276409cbe818SShteryana Shopova };
276509cbe818SShteryana Shopova 
276609cbe818SShteryana Shopova int32_t
wlan_do_sysctl(struct wlan_config * cfg,enum wlan_syscl which,int set)276709cbe818SShteryana Shopova wlan_do_sysctl(struct wlan_config *cfg, enum wlan_syscl which, int set)
276809cbe818SShteryana Shopova {
276909cbe818SShteryana Shopova 	char mib_name[100];
277009cbe818SShteryana Shopova 	int val, sval;
277109cbe818SShteryana Shopova 	size_t len, vlen;
277209cbe818SShteryana Shopova 
277309cbe818SShteryana Shopova 	if (set) {
277409cbe818SShteryana Shopova 		vlen = sizeof(sval);
277509cbe818SShteryana Shopova 		switch (which) {
277609cbe818SShteryana Shopova 		case WLAN_MESH_RETRY_TO:
277709cbe818SShteryana Shopova 			sval = cfg->mesh_retryto;
277809cbe818SShteryana Shopova 			break;
277909cbe818SShteryana Shopova 		case WLAN_MESH_HOLDING_TO:
278009cbe818SShteryana Shopova 			sval = cfg->mesh_holdingto;
278109cbe818SShteryana Shopova 			break;
278209cbe818SShteryana Shopova 		case WLAN_MESH_CONFIRM_TO:
278309cbe818SShteryana Shopova 			sval = cfg->mesh_confirmto;
278409cbe818SShteryana Shopova 			break;
278509cbe818SShteryana Shopova 		case WLAN_MESH_MAX_RETRIES:
278609cbe818SShteryana Shopova 			sval = cfg->mesh_maxretries;
278709cbe818SShteryana Shopova 			break;
278809cbe818SShteryana Shopova 		case WLAN_HWMP_TARGET_ONLY:
278909cbe818SShteryana Shopova 			sval = cfg->hwmp_targetonly;
279009cbe818SShteryana Shopova 			break;
279109cbe818SShteryana Shopova 		case WLAN_HWMP_REPLY_FORWARD:
279209cbe818SShteryana Shopova 			sval = cfg->hwmp_replyforward;
279309cbe818SShteryana Shopova 			break;
279409cbe818SShteryana Shopova 		case WLAN_HWMP_PATH_LIFETIME:
279509cbe818SShteryana Shopova 			sval = cfg->hwmp_pathlifetime;
279609cbe818SShteryana Shopova 			break;
279709cbe818SShteryana Shopova 		case WLAN_HWMP_ROOT_TO:
279809cbe818SShteryana Shopova 			sval = cfg->hwmp_roottimeout;
279909cbe818SShteryana Shopova 			break;
280009cbe818SShteryana Shopova 		case WLAN_HWMP_ROOT_INT:
280109cbe818SShteryana Shopova 			sval = cfg->hwmp_rootint;
280209cbe818SShteryana Shopova 			break;
280309cbe818SShteryana Shopova 		case WLAN_HWMP_RANN_INT:
280409cbe818SShteryana Shopova 			sval = cfg->hwmp_rannint;
280509cbe818SShteryana Shopova 			break;
280609cbe818SShteryana Shopova 		case WLAN_HWMP_INACTIVITY_TO:
280709cbe818SShteryana Shopova 			sval = cfg->hwmp_inact;
280809cbe818SShteryana Shopova 			break;
280909cbe818SShteryana Shopova 		default:
281009cbe818SShteryana Shopova 			return (-1);
281109cbe818SShteryana Shopova 		}
281209cbe818SShteryana Shopova 	} else {
281309cbe818SShteryana Shopova 		if (which >= WLAN_SYSCTL_MAX)
281409cbe818SShteryana Shopova 			return (-1);
281509cbe818SShteryana Shopova 		vlen = 0;
281609cbe818SShteryana Shopova 	}
281709cbe818SShteryana Shopova 
281809cbe818SShteryana Shopova 	strlcpy(mib_name, wlan_sysctl_name, sizeof(mib_name));
281909cbe818SShteryana Shopova 	strlcat(mib_name, wlan_sysctl[which], sizeof(mib_name));
282009cbe818SShteryana Shopova 	len = sizeof (val);
282109cbe818SShteryana Shopova 
282209cbe818SShteryana Shopova 	if (sysctlbyname(mib_name, &val, &len, (set? &sval : NULL), vlen) < 0) {
282309cbe818SShteryana Shopova 		syslog(LOG_ERR, "sysctl(%s) failed - %s", mib_name,
282409cbe818SShteryana Shopova 		    strerror(errno));
282509cbe818SShteryana Shopova 		return (-1);
282609cbe818SShteryana Shopova 	}
282709cbe818SShteryana Shopova 
282809cbe818SShteryana Shopova 	switch (which) {
282909cbe818SShteryana Shopova 	case WLAN_MESH_RETRY_TO:
283009cbe818SShteryana Shopova 		cfg->mesh_retryto = val;
283109cbe818SShteryana Shopova 		break;
283209cbe818SShteryana Shopova 	case WLAN_MESH_HOLDING_TO:
283309cbe818SShteryana Shopova 		cfg->mesh_holdingto = val;
283409cbe818SShteryana Shopova 		break;
283509cbe818SShteryana Shopova 	case WLAN_MESH_CONFIRM_TO:
283609cbe818SShteryana Shopova 		cfg->mesh_confirmto = val;
283709cbe818SShteryana Shopova 		break;
283809cbe818SShteryana Shopova 	case WLAN_MESH_MAX_RETRIES:
283909cbe818SShteryana Shopova 		cfg->mesh_maxretries = val;
284009cbe818SShteryana Shopova 		break;
284109cbe818SShteryana Shopova 	case WLAN_HWMP_TARGET_ONLY:
284209cbe818SShteryana Shopova 		cfg->hwmp_targetonly = val;
284309cbe818SShteryana Shopova 		break;
284409cbe818SShteryana Shopova 	case WLAN_HWMP_REPLY_FORWARD:
284509cbe818SShteryana Shopova 		cfg->hwmp_replyforward = val;
284609cbe818SShteryana Shopova 		break;
284709cbe818SShteryana Shopova 	case WLAN_HWMP_PATH_LIFETIME:
284809cbe818SShteryana Shopova 		cfg->hwmp_pathlifetime = val;
284909cbe818SShteryana Shopova 		break;
285009cbe818SShteryana Shopova 	case WLAN_HWMP_ROOT_TO:
285109cbe818SShteryana Shopova 		cfg->hwmp_roottimeout = val;
285209cbe818SShteryana Shopova 		break;
285309cbe818SShteryana Shopova 	case WLAN_HWMP_ROOT_INT:
285409cbe818SShteryana Shopova 		cfg->hwmp_rootint = val;
285509cbe818SShteryana Shopova 		break;
285609cbe818SShteryana Shopova 	case WLAN_HWMP_RANN_INT:
285709cbe818SShteryana Shopova 		cfg->hwmp_rannint = val;
285809cbe818SShteryana Shopova 		break;
285909cbe818SShteryana Shopova 	case WLAN_HWMP_INACTIVITY_TO:
286009cbe818SShteryana Shopova 		cfg->hwmp_inact = val;
286109cbe818SShteryana Shopova 		break;
286209cbe818SShteryana Shopova 	default:
286309cbe818SShteryana Shopova 		/* NOTREACHED */
286409cbe818SShteryana Shopova 		abort();
286509cbe818SShteryana Shopova 	}
286609cbe818SShteryana Shopova 
286709cbe818SShteryana Shopova 	return (0);
286809cbe818SShteryana Shopova }
286909cbe818SShteryana Shopova 
287009cbe818SShteryana Shopova int
wlan_mesh_config_get(struct wlan_iface * wif,int which)287109cbe818SShteryana Shopova wlan_mesh_config_get(struct wlan_iface *wif, int which)
287209cbe818SShteryana Shopova {
287309cbe818SShteryana Shopova 	int op, val = 0;
287409cbe818SShteryana Shopova 	size_t argsize = 0;
287509cbe818SShteryana Shopova 	uint8_t data[32], *pd = NULL;
287609cbe818SShteryana Shopova 
287709cbe818SShteryana Shopova 	switch (which) {
287809cbe818SShteryana Shopova 	case LEAF_wlanMeshTTL:
287909cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_TTL;
288009cbe818SShteryana Shopova 		break;
288109cbe818SShteryana Shopova 	case LEAF_wlanMeshPeeringEnabled:
288209cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_AP;
288309cbe818SShteryana Shopova 		break;
288409cbe818SShteryana Shopova 	case LEAF_wlanMeshForwardingEnabled:
288509cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_FWRD;
288609cbe818SShteryana Shopova 		break;
288709cbe818SShteryana Shopova 	case LEAF_wlanMeshMetric:
288809cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_PR_METRIC;
288909cbe818SShteryana Shopova 		pd = data;
289009cbe818SShteryana Shopova 		argsize = sizeof(data);
289109cbe818SShteryana Shopova 		break;
289209cbe818SShteryana Shopova 	case LEAF_wlanMeshPath:
289309cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_PR_PATH;
289409cbe818SShteryana Shopova 		pd = data;
289509cbe818SShteryana Shopova 		argsize = sizeof(data);
289609cbe818SShteryana Shopova 		break;
289709cbe818SShteryana Shopova 	case LEAF_wlanMeshRoutesFlush:
289809cbe818SShteryana Shopova 		return (0);
289909cbe818SShteryana Shopova 	default:
290009cbe818SShteryana Shopova 		return (-1);
290109cbe818SShteryana Shopova 	}
290209cbe818SShteryana Shopova 
290309cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 0) < 0)
290409cbe818SShteryana Shopova 		return (-1);
290509cbe818SShteryana Shopova 
290609cbe818SShteryana Shopova 	switch (which) {
290709cbe818SShteryana Shopova 	case LEAF_wlanMeshTTL:
290809cbe818SShteryana Shopova 		wif->mesh_ttl = val;
290909cbe818SShteryana Shopova 		break;
291009cbe818SShteryana Shopova 	case LEAF_wlanMeshPeeringEnabled:
291109cbe818SShteryana Shopova 		if (val)
291209cbe818SShteryana Shopova 			wif->mesh_peering = wlanMeshPeeringEnabled_true;
291309cbe818SShteryana Shopova 		else
291409cbe818SShteryana Shopova 			wif->mesh_peering = wlanMeshPeeringEnabled_false;
291509cbe818SShteryana Shopova 		break;
291609cbe818SShteryana Shopova 	case LEAF_wlanMeshForwardingEnabled:
291709cbe818SShteryana Shopova 		if (val)
291809cbe818SShteryana Shopova 			wif->mesh_forwarding = wlanMeshForwardingEnabled_true;
291909cbe818SShteryana Shopova 		else
292009cbe818SShteryana Shopova 			wif->mesh_forwarding = wlanMeshForwardingEnabled_false;
292109cbe818SShteryana Shopova 		break;
292209cbe818SShteryana Shopova 	case LEAF_wlanMeshMetric:
292309cbe818SShteryana Shopova 		data[argsize] = '\0';
292409cbe818SShteryana Shopova 		if (strcmp(data, "AIRTIME") == 0)
292509cbe818SShteryana Shopova 			wif->mesh_metric = wlanMeshMetric_airtime;
292609cbe818SShteryana Shopova 		else
292709cbe818SShteryana Shopova 			wif->mesh_metric = wlanMeshMetric_unknown;
292809cbe818SShteryana Shopova 		break;
292909cbe818SShteryana Shopova 	case LEAF_wlanMeshPath:
293009cbe818SShteryana Shopova 		data[argsize] = '\0';
293109cbe818SShteryana Shopova 		if (strcmp(data, "HWMP") == 0)
293209cbe818SShteryana Shopova 			wif->mesh_path = wlanMeshPath_hwmp;
293309cbe818SShteryana Shopova 		else
293409cbe818SShteryana Shopova 			wif->mesh_path = wlanMeshPath_unknown;
293509cbe818SShteryana Shopova 	}
293609cbe818SShteryana Shopova 
293709cbe818SShteryana Shopova 	return (0);
293809cbe818SShteryana Shopova }
293909cbe818SShteryana Shopova 
294009cbe818SShteryana Shopova int
wlan_mesh_config_set(struct wlan_iface * wif,int which)294109cbe818SShteryana Shopova wlan_mesh_config_set(struct wlan_iface *wif, int which)
294209cbe818SShteryana Shopova {
294309cbe818SShteryana Shopova 	int op, val = 0;
294409cbe818SShteryana Shopova 	size_t argsize = 0;
294509cbe818SShteryana Shopova 	uint8_t data[32], *pd = NULL;
294609cbe818SShteryana Shopova 
294709cbe818SShteryana Shopova 	switch (which) {
294809cbe818SShteryana Shopova 	case LEAF_wlanMeshTTL:
294909cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_TTL;
295009cbe818SShteryana Shopova 		val = wif->mesh_ttl;
295109cbe818SShteryana Shopova 		break;
295209cbe818SShteryana Shopova 	case LEAF_wlanMeshPeeringEnabled:
295309cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_AP;
295409cbe818SShteryana Shopova 		if (wif->mesh_peering == wlanMeshPeeringEnabled_true)
295509cbe818SShteryana Shopova 			val = 1;
295609cbe818SShteryana Shopova 		break;
295709cbe818SShteryana Shopova 	case LEAF_wlanMeshForwardingEnabled:
295809cbe818SShteryana Shopova 		if (wif->mesh_forwarding == wlanMeshForwardingEnabled_true)
295909cbe818SShteryana Shopova 			val = 1;
296009cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_FWRD;
296109cbe818SShteryana Shopova 		break;
296209cbe818SShteryana Shopova 	case LEAF_wlanMeshMetric:
296309cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_PR_METRIC;
296409cbe818SShteryana Shopova 		if (wif->mesh_metric == wlanMeshMetric_airtime)
296509cbe818SShteryana Shopova 			strcpy(data, "AIRTIME");
296609cbe818SShteryana Shopova 		else
296709cbe818SShteryana Shopova 			return (-1);
296809cbe818SShteryana Shopova 		pd = data;
296909cbe818SShteryana Shopova 		argsize = sizeof(data);
297009cbe818SShteryana Shopova 		break;
297109cbe818SShteryana Shopova 	case LEAF_wlanMeshPath:
297209cbe818SShteryana Shopova 		op = IEEE80211_IOC_MESH_PR_PATH;
297309cbe818SShteryana Shopova 		if (wif->mesh_path == wlanMeshPath_hwmp)
297409cbe818SShteryana Shopova 			strcpy(data, "HWMP");
297509cbe818SShteryana Shopova 		else
297609cbe818SShteryana Shopova 			return (-1);
297709cbe818SShteryana Shopova 		pd = data;
297809cbe818SShteryana Shopova 		argsize = sizeof(data);
297909cbe818SShteryana Shopova 		break;
298009cbe818SShteryana Shopova 	default:
298109cbe818SShteryana Shopova 		return (-1);
298209cbe818SShteryana Shopova 	}
298309cbe818SShteryana Shopova 
298409cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 1) < 0)
298509cbe818SShteryana Shopova 		return (-1);
298609cbe818SShteryana Shopova 
298709cbe818SShteryana Shopova 	return(0);
298809cbe818SShteryana Shopova }
298909cbe818SShteryana Shopova 
299009cbe818SShteryana Shopova int
wlan_mesh_flush_routes(struct wlan_iface * wif)299109cbe818SShteryana Shopova wlan_mesh_flush_routes(struct wlan_iface *wif)
299209cbe818SShteryana Shopova {
299309cbe818SShteryana Shopova 	int val = IEEE80211_MESH_RTCMD_FLUSH;
299409cbe818SShteryana Shopova 	size_t argsize = 0;
299509cbe818SShteryana Shopova 
299609cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, NULL,
299709cbe818SShteryana Shopova 	    &argsize, 1) < 0)
299809cbe818SShteryana Shopova 		return (-1);
299909cbe818SShteryana Shopova 
300009cbe818SShteryana Shopova 	return (0);
300109cbe818SShteryana Shopova }
300209cbe818SShteryana Shopova 
300309cbe818SShteryana Shopova int
wlan_mesh_add_route(struct wlan_iface * wif,struct wlan_mesh_route * wmr)300409cbe818SShteryana Shopova wlan_mesh_add_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr)
300509cbe818SShteryana Shopova {
300609cbe818SShteryana Shopova 	int val = IEEE80211_MESH_RTCMD_ADD;
300709cbe818SShteryana Shopova 	size_t argsize = IEEE80211_ADDR_LEN;
300809cbe818SShteryana Shopova 
300909cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val,
301009cbe818SShteryana Shopova 	    wmr->imroute.imr_dest, &argsize, 1) < 0)
301109cbe818SShteryana Shopova 		return (-1);
301209cbe818SShteryana Shopova 
301309cbe818SShteryana Shopova 	wmr->mroute_status = RowStatus_active;
301409cbe818SShteryana Shopova 
301509cbe818SShteryana Shopova 	return (0);
301609cbe818SShteryana Shopova }
301709cbe818SShteryana Shopova 
301809cbe818SShteryana Shopova int
wlan_mesh_del_route(struct wlan_iface * wif,struct wlan_mesh_route * wmr)301909cbe818SShteryana Shopova wlan_mesh_del_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr)
302009cbe818SShteryana Shopova {
302109cbe818SShteryana Shopova 	int val = IEEE80211_MESH_RTCMD_DELETE;
302209cbe818SShteryana Shopova 	size_t argsize = IEEE80211_ADDR_LEN;
302309cbe818SShteryana Shopova 
302409cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val,
302509cbe818SShteryana Shopova 	    wmr->imroute.imr_dest, &argsize, 1) < 0)
302609cbe818SShteryana Shopova 		return (-1);
302709cbe818SShteryana Shopova 
302809cbe818SShteryana Shopova 	wmr->mroute_status = RowStatus_destroy;
302909cbe818SShteryana Shopova 
303009cbe818SShteryana Shopova 	return (0);
303109cbe818SShteryana Shopova }
303209cbe818SShteryana Shopova 
303309cbe818SShteryana Shopova int
wlan_mesh_get_routelist(struct wlan_iface * wif)303409cbe818SShteryana Shopova wlan_mesh_get_routelist(struct wlan_iface *wif)
303509cbe818SShteryana Shopova {
303609cbe818SShteryana Shopova 	int i, nroutes, val = IEEE80211_MESH_RTCMD_LIST;
303709cbe818SShteryana Shopova 	size_t argsize;
303809cbe818SShteryana Shopova 	struct ieee80211req_mesh_route routes[128];
303909cbe818SShteryana Shopova 	struct ieee80211req_mesh_route *rt;
304009cbe818SShteryana Shopova 	struct wlan_mesh_route *wmr;
304109cbe818SShteryana Shopova 
304209cbe818SShteryana Shopova 	argsize = sizeof(routes);
304309cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, routes,
304409cbe818SShteryana Shopova 	    &argsize, 0) < 0) /* XXX: ENOMEM? */
304509cbe818SShteryana Shopova 		return (-1);
304609cbe818SShteryana Shopova 
304709cbe818SShteryana Shopova 	nroutes = argsize / sizeof(*rt);
304809cbe818SShteryana Shopova 	for (i = 0; i < nroutes; i++) {
304909cbe818SShteryana Shopova 		rt = routes + i;
305009cbe818SShteryana Shopova 		if ((wmr = wlan_mesh_new_route(rt->imr_dest)) == NULL)
305109cbe818SShteryana Shopova 			return (-1);
305209cbe818SShteryana Shopova 		memcpy(&wmr->imroute, rt, sizeof(*rt));
305309cbe818SShteryana Shopova 		wmr->mroute_status = RowStatus_active;
305409cbe818SShteryana Shopova 		if (wlan_mesh_add_rtentry(wif, wmr) < 0)
305509cbe818SShteryana Shopova 			wlan_mesh_free_route(wmr);
305609cbe818SShteryana Shopova 	}
305709cbe818SShteryana Shopova 
305809cbe818SShteryana Shopova 	return (0);
305909cbe818SShteryana Shopova }
306009cbe818SShteryana Shopova 
306109cbe818SShteryana Shopova int
wlan_hwmp_config_get(struct wlan_iface * wif,int which)306209cbe818SShteryana Shopova wlan_hwmp_config_get(struct wlan_iface *wif, int which)
306309cbe818SShteryana Shopova {
306409cbe818SShteryana Shopova 	int op, val = 0;
306509cbe818SShteryana Shopova 	size_t argsize = 0;
306609cbe818SShteryana Shopova 
306709cbe818SShteryana Shopova 	switch (which) {
306809cbe818SShteryana Shopova 	case LEAF_wlanHWMPRootMode:
306909cbe818SShteryana Shopova 		op = IEEE80211_IOC_HWMP_ROOTMODE;
307009cbe818SShteryana Shopova 		break;
307109cbe818SShteryana Shopova 	case LEAF_wlanHWMPMaxHops:
307209cbe818SShteryana Shopova 		op = IEEE80211_IOC_HWMP_MAXHOPS;
307309cbe818SShteryana Shopova 		break;
307409cbe818SShteryana Shopova 	default:
307509cbe818SShteryana Shopova 		return (-1);
307609cbe818SShteryana Shopova 	}
307709cbe818SShteryana Shopova 
307809cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0)
307909cbe818SShteryana Shopova 		return (-1);
308009cbe818SShteryana Shopova 
308109cbe818SShteryana Shopova 	switch (which) {
308209cbe818SShteryana Shopova 	case LEAF_wlanHWMPRootMode:
308309cbe818SShteryana Shopova 		switch (val) {
308409cbe818SShteryana Shopova 		case IEEE80211_HWMP_ROOTMODE_NORMAL:
308509cbe818SShteryana Shopova 			wif->hwmp_root_mode = wlanHWMPRootMode_normal;
308609cbe818SShteryana Shopova 			break;
308709cbe818SShteryana Shopova 		case IEEE80211_HWMP_ROOTMODE_PROACTIVE:
308809cbe818SShteryana Shopova 			wif->hwmp_root_mode = wlanHWMPRootMode_proactive;
308909cbe818SShteryana Shopova 			break;
309009cbe818SShteryana Shopova 		case IEEE80211_HWMP_ROOTMODE_RANN:
309109cbe818SShteryana Shopova 			wif->hwmp_root_mode = wlanHWMPRootMode_rann;
309209cbe818SShteryana Shopova 			break;
309309cbe818SShteryana Shopova 		case IEEE80211_HWMP_ROOTMODE_DISABLED:
309409cbe818SShteryana Shopova 		default:
309509cbe818SShteryana Shopova 			wif->hwmp_root_mode = wlanHWMPRootMode_disabled;
309609cbe818SShteryana Shopova 			break;
309709cbe818SShteryana Shopova 		}
309809cbe818SShteryana Shopova 		break;
309909cbe818SShteryana Shopova 	case LEAF_wlanHWMPMaxHops:
310009cbe818SShteryana Shopova 		wif->hwmp_max_hops = val;
310109cbe818SShteryana Shopova 		break;
310209cbe818SShteryana Shopova 	}
310309cbe818SShteryana Shopova 
310409cbe818SShteryana Shopova 	return (0);
310509cbe818SShteryana Shopova }
310609cbe818SShteryana Shopova 
310709cbe818SShteryana Shopova int
wlan_hwmp_config_set(struct wlan_iface * wif,int which)310809cbe818SShteryana Shopova wlan_hwmp_config_set(struct wlan_iface *wif, int which)
310909cbe818SShteryana Shopova {
311009cbe818SShteryana Shopova 	int op, val = 0;
311109cbe818SShteryana Shopova 	size_t argsize = 0;
311209cbe818SShteryana Shopova 
311309cbe818SShteryana Shopova 	switch (which) {
311409cbe818SShteryana Shopova 	case LEAF_wlanHWMPRootMode:
311509cbe818SShteryana Shopova 		op = IEEE80211_IOC_HWMP_ROOTMODE;
311609cbe818SShteryana Shopova 		switch (wif->hwmp_root_mode) {
311709cbe818SShteryana Shopova 		case wlanHWMPRootMode_disabled:
311809cbe818SShteryana Shopova 			val = IEEE80211_HWMP_ROOTMODE_DISABLED;
311909cbe818SShteryana Shopova 			break;
312009cbe818SShteryana Shopova 		case wlanHWMPRootMode_normal:
312109cbe818SShteryana Shopova 			val = IEEE80211_HWMP_ROOTMODE_NORMAL;
312209cbe818SShteryana Shopova 			break;
312309cbe818SShteryana Shopova 		case wlanHWMPRootMode_proactive:
312409cbe818SShteryana Shopova 			val = IEEE80211_HWMP_ROOTMODE_PROACTIVE;
312509cbe818SShteryana Shopova 			break;
312609cbe818SShteryana Shopova 		case wlanHWMPRootMode_rann:
312709cbe818SShteryana Shopova 			val = IEEE80211_HWMP_ROOTMODE_RANN;
312809cbe818SShteryana Shopova 			break;
312909cbe818SShteryana Shopova 		default:
313009cbe818SShteryana Shopova 			return (-1);
313109cbe818SShteryana Shopova 		}
313209cbe818SShteryana Shopova 		break;
313309cbe818SShteryana Shopova 	case LEAF_wlanHWMPMaxHops:
313409cbe818SShteryana Shopova 		op = IEEE80211_IOC_HWMP_MAXHOPS;
313509cbe818SShteryana Shopova 		val = wif->hwmp_max_hops;
313609cbe818SShteryana Shopova 		break;
313709cbe818SShteryana Shopova 	default:
313809cbe818SShteryana Shopova 		return (-1);
313909cbe818SShteryana Shopova 	}
314009cbe818SShteryana Shopova 
314109cbe818SShteryana Shopova 	if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0)
314209cbe818SShteryana Shopova 		return (-1);
314309cbe818SShteryana Shopova 
314409cbe818SShteryana Shopova 	return (0);
314509cbe818SShteryana Shopova }
3146