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(®domain, 0, sizeof(regdomain));
109909cbe818SShteryana Shopova argsize = sizeof(regdomain);
110009cbe818SShteryana Shopova
110109cbe818SShteryana Shopova if (wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, ®domain,
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