diff options
Diffstat (limited to 'usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c')
-rw-r--r-- | usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c | 3145 |
1 files changed, 0 insertions, 3145 deletions
diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c b/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c deleted file mode 100644 index 739f11f..0000000 --- a/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c +++ /dev/null @@ -1,3145 +0,0 @@ -/*- - * Copyright (c) 2010 The FreeBSD Foundation - * All rights reserved. - - * This software was developed by Shteryana Sotirova Shopova under - * sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/ioctl.h> -#include <sys/param.h> -#include <sys/module.h> -#include <sys/linker.h> -#include <sys/socket.h> -#include <sys/sysctl.h> - -#include <net/if.h> -#include <net/if_dl.h> -#include <net/if_media.h> -#include <net/if_mib.h> -#include <net/if_types.h> -#include <net80211/ieee80211.h> -#include <net80211/ieee80211_ioctl.h> -#include <net80211/ieee80211_regdomain.h> - -#include <errno.h> -#include <ifaddrs.h> -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> - -#include <bsnmp/snmpmod.h> -#include <bsnmp/snmp_mibII.h> - -#include "wlan_tree.h" -#include "wlan_snmp.h" - -static int sock = -1; - -static int wlan_ioctl(char *, uint16_t, int *, void *, size_t *, int); -static int wlan_kmod_load(const char *); -static uint32_t wlan_drivercaps_to_snmp(uint32_t); -static uint32_t wlan_cryptocaps_to_snmp(uint32_t); -static uint32_t wlan_htcaps_to_snmp(uint32_t); -static uint32_t wlan_peerstate_to_snmp(uint32_t); -static uint32_t wlan_peercaps_to_snmp(uint32_t ); -static uint32_t wlan_channel_flags_to_snmp_phy(uint32_t); -static uint32_t wlan_regdomain_to_snmp(int); -static uint32_t wlan_snmp_to_scan_flags(int); -static int wlan_config_snmp2ioctl(int); -static int wlan_snmp_to_regdomain(enum WlanRegDomainCode); -static int wlan_config_get_country(struct wlan_iface *); -static int wlan_config_set_country(struct wlan_iface *, char *, int); -static int wlan_config_get_dchannel(struct wlan_iface *wif); -static int wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t); -static int wlan_config_get_bssid(struct wlan_iface *); -static int wlan_config_set_bssid(struct wlan_iface *, uint8_t *); -static void wlan_config_set_snmp_intval(struct wlan_iface *, int, int); -static int wlan_config_snmp2value(int, int, int *); -static int wlan_config_check(struct wlan_iface *, int); -static int wlan_config_get_intval(struct wlan_iface *, int); -static int wlan_config_set_intval(struct wlan_iface *, int, int); -static int wlan_add_new_scan_result(struct wlan_iface *, - const struct ieee80211req_scan_result *, uint8_t *); -static int wlan_add_mac_macinfo(struct wlan_iface *, - const struct ieee80211req_maclist *); -static struct wlan_peer *wlan_add_peerinfo(const struct ieee80211req_sta_info *); - -int -wlan_ioctl_init(void) -{ - if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "cannot open socket : %s", strerror(errno)); - return (-1); - } - - return (0); -} -/* - * Load the needed modules in kernel if not already there. - */ -enum wlan_kmodules { - WLAN_KMOD = 0, - WLAN_KMOD_ACL, - WLAN_KMOD_WEP, - WLAN_KMODS_MAX -}; - -static const char *wmod_names[] = { - "wlan", - "wlan_wlan_acl", - "wlan_wep", - NULL -}; - -static int -wlan_kmod_load(const char *modname) -{ - int fileid, modid; - struct module_stat mstat; - - mstat.version = sizeof(struct module_stat); - for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { - for (modid = kldfirstmod(fileid); modid > 0; - modid = modfnext(modid)) { - if (modstat(modid, &mstat) < 0) - continue; - if (strcmp(modname, mstat.name) == 0) - return (0); - } - } - - /* Not present - load it. */ - if (kldload(modname) < 0) { - syslog(LOG_ERR, "failed to load %s kernel module - %s", modname, - strerror(errno)); - return (-1); - } - - return (1); -} - -int -wlan_kmodules_load(void) -{ - if (wlan_kmod_load(wmod_names[WLAN_KMOD]) < 0) - return (-1); - - if (wlan_kmod_load(wmod_names[WLAN_KMOD_ACL]) > 0) - syslog(LOG_NOTICE, "SNMP wlan loaded %s module", - wmod_names[WLAN_KMOD_ACL]); - - if (wlan_kmod_load(wmod_names[WLAN_KMOD_WEP]) > 0) - syslog(LOG_NOTICE, "SNMP wlan loaded %s module", - wmod_names[WLAN_KMOD_WEP]); - - return (0); -} - -/* XXX: FIXME */ -static int -wlan_ioctl(char *wif_name, uint16_t req_type, int *val, void *arg, - size_t *argsize, int set) -{ - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(struct ieee80211req)); - strlcpy(ireq.i_name, wif_name, IFNAMSIZ); - - ireq.i_type = req_type; - ireq.i_val = *val; - ireq.i_len = *argsize; - ireq.i_data = arg; - - if (ioctl(sock, set ? SIOCS80211 : SIOCG80211, &ireq) < 0) { - syslog(LOG_ERR, "iface %s - %s param: ioctl(%d) " - "failed: %s", wif_name, set ? "set" : "get", - req_type, strerror(errno)); - return (-1); - } - - *argsize = ireq.i_len; - *val = ireq.i_val; - - return (0); -} - -int -wlan_check_media(char *ifname) -{ - struct ifmediareq ifmr; - - memset(&ifmr, 0, sizeof(struct ifmediareq)); - strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); - - if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0 || ifmr.ifm_count == 0) - return (0); /* Interface doesn't support SIOCGIFMEDIA. */ - - if ((ifmr.ifm_status & IFM_AVALID) == 0) - return (0); - - return (IFM_TYPE(ifmr.ifm_active)); -} - -int -wlan_get_opmode(struct wlan_iface *wif) -{ - struct ifmediareq ifmr; - - memset(&ifmr, 0, sizeof(struct ifmediareq)); - strlcpy(ifmr.ifm_name, wif->wname, sizeof(ifmr.ifm_name)); - - if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0) { - if (errno == ENXIO) - return (-1); - wif->mode = WlanIfaceOperatingModeType_station; - return (0); - } - - if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) { - if (ifmr.ifm_current & IFM_FLAG0) - wif->mode = WlanIfaceOperatingModeType_adhocDemo; - else - wif->mode = WlanIfaceOperatingModeType_ibss; - } else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) - wif->mode = WlanIfaceOperatingModeType_hostAp; - else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) - wif->mode = WlanIfaceOperatingModeType_monitor; - else if (ifmr.ifm_current & IFM_IEEE80211_MBSS) - wif->mode = WlanIfaceOperatingModeType_meshPoint; - else if (ifmr.ifm_current & IFM_IEEE80211_WDS) - wif->mode = WlanIfaceOperatingModeType_wds; - - return (0); -} - -int -wlan_config_state(struct wlan_iface *wif, uint8_t set) -{ - int flags; - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, wif->wname); - - if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "set %s status: ioctl(SIOCGIFFLAGS) " - "failed: %s", wif->wname, strerror(errno)); - return (-1); - } - - if (set == 0) { - if ((ifr.ifr_flags & IFF_UP) != 0) - wif->state = wlanIfaceState_up; - else - wif->state = wlanIfaceState_down; - return (0); - } - - flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); - - if (wif->state == wlanIfaceState_up) - flags |= IFF_UP; - else - flags &= ~IFF_UP; - - ifr.ifr_flags = flags & 0xffff; - ifr.ifr_flagshigh = flags >> 16; - if (ioctl(sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "set %s %s: ioctl(SIOCSIFFLAGS) failed: %s", - wif->wname, wif->state == wlanIfaceState_up?"up":"down", - strerror(errno)); - return (-1); - } - - return (0); -} - -int -wlan_get_local_addr(struct wlan_iface *wif) -{ - int len; - char ifname[IFNAMSIZ]; - struct ifaddrs *ifap, *ifa; - struct sockaddr_dl sdl; - - if (getifaddrs(&ifap) != 0) { - syslog(LOG_ERR, "wlan get mac: getifaddrs() failed - %s", - strerror(errno)); - return (-1); - } - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family != AF_LINK) - continue; - memcpy(&sdl, ifa->ifa_addr, sizeof(struct sockaddr_dl)); - if (sdl.sdl_alen > IEEE80211_ADDR_LEN) - continue; - if ((len = sdl.sdl_nlen) >= IFNAMSIZ) - len = IFNAMSIZ - 1; - memcpy(ifname, sdl.sdl_data, len); - ifname[len] = '\0'; - if (strcmp(wif->wname, ifname) == 0) - break; - } - - freeifaddrs(ifap); - return (0); -} - -int -wlan_get_parent(struct wlan_iface *wif __unused) -{ - /* XXX: There's no way to fetch this from the kernel. */ - return (0); -} - -/* XXX */ -#define IEEE80211_C_STA 0x00000001 /* CAPABILITY: STA available */ -#define IEEE80211_C_8023ENCAP 0x00000002 /* CAPABILITY: 802.3 encap */ -#define IEEE80211_C_FF 0x00000040 /* CAPABILITY: ATH FF avail */ -#define IEEE80211_C_TURBOP 0x00000080 /* CAPABILITY: ATH Turbo avail*/ -#define IEEE80211_C_IBSS 0x00000100 /* CAPABILITY: IBSS available */ -#define IEEE80211_C_PMGT 0x00000200 /* CAPABILITY: Power mgmt */ -#define IEEE80211_C_HOSTAP 0x00000400 /* CAPABILITY: HOSTAP avail */ -#define IEEE80211_C_AHDEMO 0x00000800 /* CAPABILITY: Old Adhoc Demo */ -#define IEEE80211_C_SWRETRY 0x00001000 /* CAPABILITY: sw tx retry */ -#define IEEE80211_C_TXPMGT 0x00002000 /* CAPABILITY: tx power mgmt */ -#define IEEE80211_C_SHSLOT 0x00004000 /* CAPABILITY: short slottime */ -#define IEEE80211_C_SHPREAMBLE 0x00008000 /* CAPABILITY: short preamble */ -#define IEEE80211_C_MONITOR 0x00010000 /* CAPABILITY: monitor mode */ -#define IEEE80211_C_DFS 0x00020000 /* CAPABILITY: DFS/radar avail*/ -#define IEEE80211_C_MBSS 0x00040000 /* CAPABILITY: MBSS available */ -/* 0x7c0000 available */ -#define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */ -#define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */ -#define IEEE80211_C_WPA 0x01800000 /* CAPABILITY: WPA1+WPA2 avail*/ -#define IEEE80211_C_BURST 0x02000000 /* CAPABILITY: frame bursting */ -#define IEEE80211_C_WME 0x04000000 /* CAPABILITY: WME avail */ -#define IEEE80211_C_WDS 0x08000000 /* CAPABILITY: 4-addr support */ -/* 0x10000000 reserved */ -#define IEEE80211_C_BGSCAN 0x20000000 /* CAPABILITY: bg scanning */ -#define IEEE80211_C_TXFRAG 0x40000000 /* CAPABILITY: tx fragments */ -#define IEEE80211_C_TDMA 0x80000000 /* CAPABILITY: TDMA avail */ - -static uint32_t -wlan_drivercaps_to_snmp(uint32_t dcaps) -{ - uint32_t scaps = 0; - - if ((dcaps & IEEE80211_C_STA) != 0) - scaps |= (0x1 << WlanDriverCaps_station); - if ((dcaps & IEEE80211_C_8023ENCAP) != 0) - scaps |= (0x1 << WlanDriverCaps_ieee8023encap); - if ((dcaps & IEEE80211_C_FF) != 0) - scaps |= (0x1 << WlanDriverCaps_athFastFrames); - if ((dcaps & IEEE80211_C_TURBOP) != 0) - scaps |= (0x1 << WlanDriverCaps_athTurbo); - if ((dcaps & IEEE80211_C_IBSS) != 0) - scaps |= (0x1 << WlanDriverCaps_ibss); - if ((dcaps & IEEE80211_C_PMGT) != 0) - scaps |= (0x1 << WlanDriverCaps_pmgt); - if ((dcaps & IEEE80211_C_HOSTAP) != 0) - scaps |= (0x1 << WlanDriverCaps_hostAp); - if ((dcaps & IEEE80211_C_AHDEMO) != 0) - scaps |= (0x1 << WlanDriverCaps_ahDemo); - if ((dcaps & IEEE80211_C_SWRETRY) != 0) - scaps |= (0x1 << WlanDriverCaps_swRetry); - if ((dcaps & IEEE80211_C_TXPMGT) != 0) - scaps |= (0x1 << WlanDriverCaps_txPmgt); - if ((dcaps & IEEE80211_C_SHSLOT) != 0) - scaps |= (0x1 << WlanDriverCaps_shortSlot); - if ((dcaps & IEEE80211_C_SHPREAMBLE) != 0) - scaps |= (0x1 << WlanDriverCaps_shortPreamble); - if ((dcaps & IEEE80211_C_MONITOR) != 0) - scaps |= (0x1 << WlanDriverCaps_monitor); - if ((dcaps & IEEE80211_C_DFS) != 0) - scaps |= (0x1 << WlanDriverCaps_dfs); - if ((dcaps & IEEE80211_C_MBSS) != 0) - scaps |= (0x1 << WlanDriverCaps_mbss); - if ((dcaps & IEEE80211_C_WPA1) != 0) - scaps |= (0x1 << WlanDriverCaps_wpa1); - if ((dcaps & IEEE80211_C_WPA2) != 0) - scaps |= (0x1 << WlanDriverCaps_wpa2); - if ((dcaps & IEEE80211_C_BURST) != 0) - scaps |= (0x1 << WlanDriverCaps_burst); - if ((dcaps & IEEE80211_C_WME) != 0) - scaps |= (0x1 << WlanDriverCaps_wme); - if ((dcaps & IEEE80211_C_WDS) != 0) - scaps |= (0x1 << WlanDriverCaps_wds); - if ((dcaps & IEEE80211_C_BGSCAN) != 0) - scaps |= (0x1 << WlanDriverCaps_bgScan); - if ((dcaps & IEEE80211_C_TXFRAG) != 0) - scaps |= (0x1 << WlanDriverCaps_txFrag); - if ((dcaps & IEEE80211_C_TDMA) != 0) - scaps |= (0x1 << WlanDriverCaps_tdma); - - return (scaps); -} - -static uint32_t -wlan_cryptocaps_to_snmp(uint32_t ccaps) -{ - uint32_t scaps = 0; - -#if NOT_YET - if ((ccaps & IEEE80211_CRYPTO_WEP) != 0) - scaps |= (0x1 << wlanCryptoCaps_wep); - if ((ccaps & IEEE80211_CRYPTO_TKIP) != 0) - scaps |= (0x1 << wlanCryptoCaps_tkip); - if ((ccaps & IEEE80211_CRYPTO_AES_OCB) != 0) - scaps |= (0x1 << wlanCryptoCaps_aes); - if ((ccaps & IEEE80211_CRYPTO_AES_CCM) != 0) - scaps |= (0x1 << wlanCryptoCaps_aesCcm); - if ((ccaps & IEEE80211_CRYPTO_TKIPMIC) != 0) - scaps |= (0x1 << wlanCryptoCaps_tkipMic); - if ((ccaps & IEEE80211_CRYPTO_CKIP) != 0) - scaps |= (0x1 << wlanCryptoCaps_ckip); -#else /* !NOT_YET */ - scaps = ccaps; -#endif - return (scaps); -} - -#define IEEE80211_HTC_AMPDU 0x00010000 /* CAPABILITY: A-MPDU tx */ -#define IEEE80211_HTC_AMSDU 0x00020000 /* CAPABILITY: A-MSDU tx */ -/* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */ -#define IEEE80211_HTC_HT 0x00040000 /* CAPABILITY: HT operation */ -#define IEEE80211_HTC_SMPS 0x00080000 /* CAPABILITY: MIMO power save*/ -#define IEEE80211_HTC_RIFS 0x00100000 /* CAPABILITY: RIFS support */ - -static uint32_t -wlan_htcaps_to_snmp(uint32_t hcaps) -{ - uint32_t scaps = 0; - - if ((hcaps & IEEE80211_HTCAP_LDPC) != 0) - scaps |= (0x1 << WlanHTCaps_ldpc); - if ((hcaps & IEEE80211_HTCAP_CHWIDTH40) != 0) - scaps |= (0x1 << WlanHTCaps_chwidth40); - if ((hcaps & IEEE80211_HTCAP_GREENFIELD) != 0) - scaps |= (0x1 << WlanHTCaps_greenField); - if ((hcaps & IEEE80211_HTCAP_SHORTGI20) != 0) - scaps |= (0x1 << WlanHTCaps_shortGi20); - if ((hcaps & IEEE80211_HTCAP_SHORTGI40) != 0) - scaps |= (0x1 << WlanHTCaps_shortGi40); - if ((hcaps & IEEE80211_HTCAP_TXSTBC) != 0) - scaps |= (0x1 << WlanHTCaps_txStbc); - if ((hcaps & IEEE80211_HTCAP_DELBA) != 0) - scaps |= (0x1 << WlanHTCaps_delba); - if ((hcaps & IEEE80211_HTCAP_MAXAMSDU_7935) != 0) - scaps |= (0x1 << WlanHTCaps_amsdu7935); - if ((hcaps & IEEE80211_HTCAP_DSSSCCK40) != 0) - scaps |= (0x1 << WlanHTCaps_dssscck40); - if ((hcaps & IEEE80211_HTCAP_PSMP) != 0) - scaps |= (0x1 << WlanHTCaps_psmp); - if ((hcaps & IEEE80211_HTCAP_40INTOLERANT) != 0) - scaps |= (0x1 << WlanHTCaps_fortyMHzIntolerant); - if ((hcaps & IEEE80211_HTCAP_LSIGTXOPPROT) != 0) - scaps |= (0x1 << WlanHTCaps_lsigTxOpProt); - if ((hcaps & IEEE80211_HTC_AMPDU) != 0) - scaps |= (0x1 << WlanHTCaps_htcAmpdu); - if ((hcaps & IEEE80211_HTC_AMSDU) != 0) - scaps |= (0x1 << WlanHTCaps_htcAmsdu); - if ((hcaps & IEEE80211_HTC_HT) != 0) - scaps |= (0x1 << WlanHTCaps_htcHt); - if ((hcaps & IEEE80211_HTC_SMPS) != 0) - scaps |= (0x1 << WlanHTCaps_htcSmps); - if ((hcaps & IEEE80211_HTC_RIFS) != 0) - scaps |= (0x1 << WlanHTCaps_htcRifs); - - return (scaps); -} - -/* XXX: Not here? */ -#define WLAN_SET_TDMA_OPMODE(w) do { \ - if ((w)->mode == WlanIfaceOperatingModeType_adhocDemo && \ - ((w)->drivercaps & WlanDriverCaps_tdma) != 0) \ - (w)->mode = WlanIfaceOperatingModeType_tdma; \ -} while (0) -int -wlan_get_driver_caps(struct wlan_iface *wif) -{ - int val = 0; - size_t argsize; - struct ieee80211_devcaps_req dc; - - memset(&dc, 0, sizeof(struct ieee80211_devcaps_req)); - argsize = sizeof(struct ieee80211_devcaps_req); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_DEVCAPS, &val, &dc, - &argsize, 0) < 0) - return (-1); - - wif->drivercaps = wlan_drivercaps_to_snmp(dc.dc_drivercaps); - wif->cryptocaps = wlan_cryptocaps_to_snmp(dc.dc_cryptocaps); - wif->htcaps = wlan_htcaps_to_snmp(dc.dc_htcaps); - - WLAN_SET_TDMA_OPMODE(wif); - - argsize = dc.dc_chaninfo.ic_nchans * sizeof(struct ieee80211_channel); - wif->chanlist = (struct ieee80211_channel *)malloc(argsize); - if (wif->chanlist == NULL) - return (0); - - memcpy(wif->chanlist, dc.dc_chaninfo.ic_chans, argsize); - wif->nchannels = dc.dc_chaninfo.ic_nchans; - - return (0); -} - -uint8_t -wlan_channel_state_to_snmp(uint8_t cstate) -{ - uint8_t cs = 0; - - if ((cstate & IEEE80211_CHANSTATE_RADAR) != 0) - cs |= (0x1 << WlanIfaceChannelStateType_radar); - if ((cstate & IEEE80211_CHANSTATE_CACDONE) != 0) - cs |= (0x1 << WlanIfaceChannelStateType_cacDone); - if ((cstate & IEEE80211_CHANSTATE_CWINT) != 0) - cs |= (0x1 << WlanIfaceChannelStateType_interferenceDetected); - if ((cstate & IEEE80211_CHANSTATE_NORADAR) != 0) - cs |= (0x1 << WlanIfaceChannelStateType_radarClear); - - return (cs); -} - -uint32_t -wlan_channel_flags_to_snmp(uint32_t cflags) -{ - uint32_t cf = 0; - - if ((cflags & IEEE80211_CHAN_TURBO) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_turbo); - if ((cflags & IEEE80211_CHAN_CCK) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_cck); - if ((cflags & IEEE80211_CHAN_OFDM) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_ofdm); - if ((cflags & IEEE80211_CHAN_2GHZ) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum2Ghz); - if ((cflags & IEEE80211_CHAN_5GHZ) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum5Ghz); - if ((cflags & IEEE80211_CHAN_PASSIVE) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_passiveScan); - if ((cflags & IEEE80211_CHAN_DYN) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_dynamicCckOfdm); - if ((cflags & IEEE80211_CHAN_GFSK) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_gfsk); - if ((cflags & IEEE80211_CHAN_GSM) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum900Mhz); - if ((cflags & IEEE80211_CHAN_STURBO) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_dot11aStaticTurbo); - if ((cflags & IEEE80211_CHAN_HALF) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_halfRate); - if ((cflags & IEEE80211_CHAN_QUARTER) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_quarterRate); - if ((cflags & IEEE80211_CHAN_HT20) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_ht20); - if ((cflags & IEEE80211_CHAN_HT40U) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_ht40u); - if ((cflags & IEEE80211_CHAN_HT40D) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_ht40d); - if ((cflags & IEEE80211_CHAN_DFS) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_dfs); - if ((cflags & IEEE80211_CHAN_4MSXMIT) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_xmit4ms); - if ((cflags & IEEE80211_CHAN_NOADHOC) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_noAdhoc); - if ((cflags & IEEE80211_CHAN_NOHOSTAP) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_noHostAp); - if ((cflags & IEEE80211_CHAN_11D) != 0) - cf |= (0x1 << WlanIfaceChannelFlagsType_dot11d); - - return (cf); -} - -/* XXX: */ -#define WLAN_SNMP_MAX_CHANS 256 -int -wlan_get_channel_list(struct wlan_iface *wif) -{ - int val = 0; - uint32_t i, nchans; - size_t argsize; - struct ieee80211req_chaninfo *chaninfo; - struct ieee80211req_chanlist active; - const struct ieee80211_channel *c; - - argsize = sizeof(struct ieee80211req_chaninfo) + - sizeof(struct ieee80211_channel) * WLAN_SNMP_MAX_CHANS; - chaninfo = (struct ieee80211req_chaninfo *)malloc(argsize); - if (chaninfo == NULL) - return (-1); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANINFO, &val, chaninfo, - &argsize, 0) < 0) - return (-1); - - argsize = sizeof(active); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANLIST, &val, &active, - &argsize, 0) < 0) - goto error; - - for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) { - c = &chaninfo->ic_chans[i]; - if (!isset(active.ic_channels, c->ic_ieee)) - continue; - nchans++; - } - wif->chanlist = (struct ieee80211_channel *)reallocf(wif->chanlist, - nchans * sizeof(*c)); - if (wif->chanlist == NULL) - goto error; - wif->nchannels = nchans; - for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) { - c = &chaninfo->ic_chans[i]; - if (!isset(active.ic_channels, c->ic_ieee)) - continue; - memcpy(wif->chanlist + nchans, c, sizeof (*c)); - nchans++; - } - - free(chaninfo); - return (0); -error: - wif->nchannels = 0; - free(chaninfo); - return (-1); -} - -static enum WlanIfPhyMode -wlan_channel_flags_to_snmp_phy(uint32_t cflags) -{ - /* XXX: recheck */ - if ((cflags & IEEE80211_CHAN_A) != 0) - return (WlanIfPhyMode_dot11a); - if ((cflags & IEEE80211_CHAN_B) != 0) - return (WlanIfPhyMode_dot11b); - if ((cflags & IEEE80211_CHAN_G) != 0 || - (cflags & IEEE80211_CHAN_PUREG) != 0) - return (WlanIfPhyMode_dot11g); - if ((cflags & IEEE80211_CHAN_FHSS) != 0) - return (WlanIfPhyMode_fh); - if ((cflags & IEEE80211_CHAN_TURBO) != 0 && - (cflags & IEEE80211_CHAN_A) != 0) - return (WlanIfPhyMode_turboA); - if ((cflags & IEEE80211_CHAN_TURBO) != 0 && - (cflags & IEEE80211_CHAN_G) != 0) - return (WlanIfPhyMode_turboG); - if ((cflags & IEEE80211_CHAN_STURBO) != 0) - return (WlanIfPhyMode_sturboA); - if ((cflags & IEEE80211_CHAN_HALF) != 0) - return (WlanIfPhyMode_ofdmHalf); - if ((cflags & IEEE80211_CHAN_QUARTER) != 0) - return (WlanIfPhyMode_ofdmQuarter); - - return (WlanIfPhyMode_auto); -} - -int -wlan_get_roam_params(struct wlan_iface *wif) -{ - int val = 0; - size_t argsize; - - argsize = sizeof(struct ieee80211_roamparams_req); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_ROAM, &val, - &wif->roamparams, &argsize, 0) < 0) - return (-1); - - return (0); -} - -int -wlan_get_tx_params(struct wlan_iface *wif) -{ - int val = 0; - size_t argsize; - - /* - * XXX: Reset IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA - * and IEEE80211_MODE_11NG modes. - */ - argsize = sizeof(struct ieee80211_txparams_req); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val, - &wif->txparams, &argsize, 0) < 0) - return (-1); - - return (0); -} - -int -wlan_set_tx_params(struct wlan_iface *wif, int32_t pmode __unused) -{ - int val = 0; - size_t argsize; - - /* - * XXX: Set IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA - * and IEEE80211_MODE_11NG modes. - */ - argsize = sizeof(struct ieee80211_txparams_req); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val, - &wif->txparams, &argsize, 1) < 0) - return (-1); - - return (0); -} - -int -wlan_clone_create(struct wlan_iface *wif) -{ - struct ifreq ifr; - struct ieee80211_clone_params wcp; - static const uint8_t zerobssid[IEEE80211_ADDR_LEN]; - - memset(&wcp, 0, sizeof(wcp)); - memset(&ifr, 0, sizeof(ifr)); - - /* Sanity checks. */ - if (wif == NULL || wif->pname[0] == '\0' || wif->mode > WLAN_IFMODE_MAX) - return (SNMP_ERR_INCONS_VALUE); - - if (wif->mode == WlanIfaceOperatingModeType_wds && - memcmp(wif->dbssid, zerobssid, IEEE80211_ADDR_LEN) == 0) - return (SNMP_ERR_INCONS_VALUE); - - strlcpy(wcp.icp_parent, wif->pname, IFNAMSIZ); - if ((wif->flags & WlanIfaceFlagsType_uniqueBssid) != 0) - wcp.icp_flags |= IEEE80211_CLONE_BSSID; - if ((wif->flags & WlanIfaceFlagsType_noBeacons) != 0) - wcp.icp_flags |= IEEE80211_CLONE_NOBEACONS; - if (wif->mode == WlanIfaceOperatingModeType_wds && - (wif->flags & WlanIfaceFlagsType_wdsLegacy) != 0) - wcp.icp_flags |= IEEE80211_CLONE_WDSLEGACY; - - switch (wif->mode) { - case WlanIfaceOperatingModeType_ibss: - wcp.icp_opmode = IEEE80211_M_IBSS; - break; - case WlanIfaceOperatingModeType_station: - wcp.icp_opmode = IEEE80211_M_STA; - break; - case WlanIfaceOperatingModeType_wds: - wcp.icp_opmode = IEEE80211_M_WDS; - break; - case WlanIfaceOperatingModeType_adhocDemo: - wcp.icp_opmode = IEEE80211_M_AHDEMO; - break; - case WlanIfaceOperatingModeType_hostAp: - wcp.icp_opmode = IEEE80211_M_HOSTAP; - break; - case WlanIfaceOperatingModeType_monitor: - wcp.icp_opmode = IEEE80211_M_MONITOR; - break; - case WlanIfaceOperatingModeType_meshPoint: - wcp.icp_opmode = IEEE80211_M_MBSS; - break; - case WlanIfaceOperatingModeType_tdma: - wcp.icp_opmode = IEEE80211_M_AHDEMO; - wcp.icp_flags |= IEEE80211_CLONE_TDMA; - break; - } - - memcpy(wcp.icp_bssid, wif->dbssid, IEEE80211_ADDR_LEN); - if (memcmp(wif->dlmac, zerobssid, IEEE80211_ADDR_LEN) != 0) { - memcpy(wcp.icp_macaddr, wif->dlmac, IEEE80211_ADDR_LEN); - wcp.icp_flags |= IEEE80211_CLONE_MACADDR; - } - - strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ); - ifr.ifr_data = (caddr_t) &wcp; - - if (ioctl(sock, SIOCIFCREATE2, (caddr_t) &ifr) < 0) { - syslog(LOG_ERR, "wlan clone create: ioctl(SIOCIFCREATE2) " - "failed: %s", strerror(errno)); - return (SNMP_ERR_GENERR); - } - - return (SNMP_ERR_NOERROR); -} - -int -wlan_clone_destroy(struct wlan_iface *wif) -{ - struct ifreq ifr; - - if (wif == NULL) - return (SNMP_ERR_INCONS_VALUE); - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, wif->wname); - - if (ioctl(sock, SIOCIFDESTROY, &ifr) < 0) { - syslog(LOG_ERR, "wlan clone destroy: ioctl(SIOCIFDESTROY) " - "failed: %s", strerror(errno)); - return (SNMP_ERR_GENERR); - } - - return (SNMP_ERR_NOERROR); -} - -static int -wlan_config_snmp2ioctl(int which) -{ - int op; - - switch (which) { - case LEAF_wlanIfacePacketBurst: - op = IEEE80211_IOC_BURST; - break; - case LEAF_wlanIfaceCountryCode: - op = IEEE80211_IOC_REGDOMAIN; - break; - case LEAF_wlanIfaceRegDomain: - op = IEEE80211_IOC_REGDOMAIN; - break; - case LEAF_wlanIfaceDesiredSsid: - op = IEEE80211_IOC_SSID; - break; - case LEAF_wlanIfaceDesiredChannel: - op = IEEE80211_IOC_CURCHAN; - break; - case LEAF_wlanIfaceDynamicFreqSelection: - op = IEEE80211_IOC_DFS; - break; - case LEAF_wlanIfaceFastFrames: - op = IEEE80211_IOC_FF; - break; - case LEAF_wlanIfaceDturbo: - op = IEEE80211_IOC_TURBOP; - break; - case LEAF_wlanIfaceTxPower: - op = IEEE80211_IOC_TXPOWER; - break; - case LEAF_wlanIfaceFragmentThreshold: - op = IEEE80211_IOC_FRAGTHRESHOLD; - break; - case LEAF_wlanIfaceRTSThreshold: - op = IEEE80211_IOC_RTSTHRESHOLD; - break; - case LEAF_wlanIfaceWlanPrivacySubscribe: - op = IEEE80211_IOC_WPS; - break; - case LEAF_wlanIfaceBgScan: - op = IEEE80211_IOC_BGSCAN; - break; - case LEAF_wlanIfaceBgScanIdle: - op = IEEE80211_IOC_BGSCAN_IDLE; - break; - case LEAF_wlanIfaceBgScanInterval: - op = IEEE80211_IOC_BGSCAN_INTERVAL; - break; - case LEAF_wlanIfaceBeaconMissedThreshold: - op = IEEE80211_IOC_BMISSTHRESHOLD; - break; - case LEAF_wlanIfaceDesiredBssid: - op = IEEE80211_IOC_BSSID; - break; - case LEAF_wlanIfaceRoamingMode: - op = IEEE80211_IOC_ROAMING; - break; - case LEAF_wlanIfaceDot11d: - op = IEEE80211_IOC_DOTD; - break; - case LEAF_wlanIfaceDot11h: - op = IEEE80211_IOC_DOTH; - break; - case LEAF_wlanIfaceDynamicWds: - op = IEEE80211_IOC_DWDS; - break; - case LEAF_wlanIfacePowerSave: - op = IEEE80211_IOC_POWERSAVE; - break; - case LEAF_wlanIfaceApBridge: - op = IEEE80211_IOC_APBRIDGE; - break; - case LEAF_wlanIfaceBeaconInterval: - op = IEEE80211_IOC_BEACON_INTERVAL; - break; - case LEAF_wlanIfaceDtimPeriod: - op = IEEE80211_IOC_DTIM_PERIOD; - break; - case LEAF_wlanIfaceHideSsid: - op = IEEE80211_IOC_HIDESSID; - break; - case LEAF_wlanIfaceInactivityProccess: - op = IEEE80211_IOC_INACTIVITY; - break; - case LEAF_wlanIfaceDot11gProtMode: - op = IEEE80211_IOC_PROTMODE; - break; - case LEAF_wlanIfaceDot11gPureMode: - op = IEEE80211_IOC_PUREG; - break; - case LEAF_wlanIfaceDot11nPureMode: - op = IEEE80211_IOC_PUREN; - break; - case LEAF_wlanIfaceDot11nAmpdu: - op = IEEE80211_IOC_AMPDU; - break; - case LEAF_wlanIfaceDot11nAmpduDensity: - op = IEEE80211_IOC_AMPDU_DENSITY; - break; - case LEAF_wlanIfaceDot11nAmpduLimit: - op = IEEE80211_IOC_AMPDU_LIMIT; - break; - case LEAF_wlanIfaceDot11nAmsdu: - op = IEEE80211_IOC_AMSDU; - break; - case LEAF_wlanIfaceDot11nAmsduLimit: - op = IEEE80211_IOC_AMSDU_LIMIT; - break; - case LEAF_wlanIfaceDot11nHighThroughput: - op = IEEE80211_IOC_HTCONF; - break; - case LEAF_wlanIfaceDot11nHTCompatible: - op = IEEE80211_IOC_HTCOMPAT; - break; - case LEAF_wlanIfaceDot11nHTProtMode: - op = IEEE80211_IOC_HTPROTMODE; - break; - case LEAF_wlanIfaceDot11nRIFS: - op = IEEE80211_IOC_RIFS; - break; - case LEAF_wlanIfaceDot11nShortGI: - op = IEEE80211_IOC_SHORTGI; - break; - case LEAF_wlanIfaceDot11nSMPSMode: - op = IEEE80211_IOC_SMPS; - break; - case LEAF_wlanIfaceTdmaSlot: - op = IEEE80211_IOC_TDMA_SLOT; - break; - case LEAF_wlanIfaceTdmaSlotCount: - op = IEEE80211_IOC_TDMA_SLOTCNT; - break; - case LEAF_wlanIfaceTdmaSlotLength: - op = IEEE80211_IOC_TDMA_SLOTLEN; - break; - case LEAF_wlanIfaceTdmaBeaconInterval: - op = IEEE80211_IOC_TDMA_BINTERVAL; - break; - default: - op = -1; - } - - return (op); -} - -static enum WlanRegDomainCode -wlan_regdomain_to_snmp(int which) -{ - enum WlanRegDomainCode reg_domain; - - switch (which) { - case SKU_FCC: - reg_domain = WlanRegDomainCode_fcc; - break; - case SKU_CA: - reg_domain = WlanRegDomainCode_ca; - break; - case SKU_ETSI: - reg_domain = WlanRegDomainCode_etsi; - break; - case SKU_ETSI2: - reg_domain = WlanRegDomainCode_etsi2; - break; - case SKU_ETSI3: - reg_domain = WlanRegDomainCode_etsi3; - break; - case SKU_FCC3: - reg_domain = WlanRegDomainCode_fcc3; - break; - case SKU_JAPAN: - reg_domain = WlanRegDomainCode_japan; - break; - case SKU_KOREA: - reg_domain = WlanRegDomainCode_korea; - break; - case SKU_APAC: - reg_domain = WlanRegDomainCode_apac; - break; - case SKU_APAC2: - reg_domain = WlanRegDomainCode_apac2; - break; - case SKU_APAC3: - reg_domain = WlanRegDomainCode_apac3; - break; - case SKU_ROW: - reg_domain = WlanRegDomainCode_row; - break; - case SKU_NONE: - reg_domain = WlanRegDomainCode_none; - break; - case SKU_DEBUG: - reg_domain = WlanRegDomainCode_debug; - break; - case SKU_SR9: - reg_domain = WlanRegDomainCode_sr9; - break; - case SKU_XR9: - reg_domain = WlanRegDomainCode_xr9; - break; - case SKU_GZ901: - reg_domain = WlanRegDomainCode_gz901; - break; - case 0: - reg_domain = WlanRegDomainCode_none; - break; - default: - syslog(LOG_ERR, "unknown regdomain (0x%x) ", which); - reg_domain = WlanRegDomainCode_none; - break; - } - - return (reg_domain); -} - -static int -wlan_snmp_to_regdomain(enum WlanRegDomainCode regdomain) -{ - int which; - - switch (regdomain) { - case WlanRegDomainCode_fcc: - which = SKU_FCC; - break; - case WlanRegDomainCode_ca: - which = SKU_CA; - break; - case WlanRegDomainCode_etsi: - which = SKU_ETSI; - break; - case WlanRegDomainCode_etsi2: - which = SKU_ETSI2; - break; - case WlanRegDomainCode_etsi3: - which = SKU_ETSI3; - break; - case WlanRegDomainCode_fcc3: - which = SKU_FCC3; - break; - case WlanRegDomainCode_japan: - which = SKU_JAPAN; - break; - case WlanRegDomainCode_korea: - which = SKU_KOREA; - break; - case WlanRegDomainCode_apac: - which = SKU_APAC; - break; - case WlanRegDomainCode_apac2: - which = SKU_APAC2; - break; - case WlanRegDomainCode_apac3: - which = SKU_APAC3; - break; - case WlanRegDomainCode_row: - which = SKU_ROW; - break; - case WlanRegDomainCode_none: - which = SKU_NONE; - break; - case WlanRegDomainCode_debug: - which = SKU_DEBUG; - break; - case WlanRegDomainCode_sr9: - which = SKU_SR9; - break; - case WlanRegDomainCode_xr9: - which = SKU_XR9; - break; - case WlanRegDomainCode_gz901: - which = SKU_GZ901; - break; - default: - syslog(LOG_ERR, "unknown snmp regdomain (0x%x) ", regdomain); - which = SKU_NONE; - break; - } - - return (which); -} - -static int -wlan_config_get_country(struct wlan_iface *wif) -{ - int val = 0; - size_t argsize; - struct ieee80211_regdomain regdomain; - - memset(®domain, 0, sizeof(regdomain)); - argsize = sizeof(regdomain); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, ®domain, - &argsize, 0) < 0) - return (-1); - - wif->reg_domain = wlan_regdomain_to_snmp(regdomain.regdomain); - wif->country_code[0] = regdomain.isocc[0]; - wif->country_code[1] = regdomain.isocc[1]; - wif->country_code[2] = regdomain.location; - - return (0); -} - -static int -wlan_config_set_country(struct wlan_iface *wif, char *ccode, int rdomain) -{ - int val = 0, txpowermax; - uint32_t i; - size_t argsize = 0; - struct ieee80211_regdomain_req *regdomain; - - if (wlan_get_channel_list(wif) < 0) - return (-1); - - if (wif->nchannels == 0) { - syslog(LOG_ERR, "iface %s - set regdomain failed", wif->wname); - return (-1); - } - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPOWMAX, &txpowermax, 0, - &argsize, 0) < 0) - return (-1); - - regdomain = malloc(IEEE80211_REGDOMAIN_SIZE(wif->nchannels)); - if (regdomain == NULL) - return (-1); - memset(regdomain, 0, IEEE80211_REGDOMAIN_SIZE(wif->nchannels)); - argsize = IEEE80211_REGDOMAIN_SIZE(wif->nchannels); - - /* XXX: recheck with how this is done by ifconfig(8) */ - regdomain->rd.regdomain = wlan_snmp_to_regdomain(rdomain); - regdomain->rd.isocc[0] = ccode[0]; - regdomain->rd.isocc[1] = ccode[1]; - regdomain->rd.location = ccode[2]; - - /* XXX: fill the channel list properly */ - regdomain->chaninfo.ic_nchans = wif->nchannels; - memcpy(regdomain->chaninfo.ic_chans, wif->chanlist, - wif->nchannels * sizeof(struct ieee80211_channel)); - for (i = 0; i < wif->nchannels; i++) - regdomain->chaninfo.ic_chans[i].ic_maxregpower = txpowermax; - - wif->state = wlanIfaceState_down; - if (wlan_config_state(wif, 1) < 0 || - wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, regdomain, - &argsize, 1) < 0) { - free(regdomain); - return (-1); - } - - wif->state = wlanIfaceState_up; - (void)wlan_config_state(wif, 1); - wif->reg_domain = wlan_regdomain_to_snmp(regdomain->rd.regdomain); - wif->country_code[0] = regdomain->rd.isocc[0]; - wif->country_code[1] = regdomain->rd.isocc[1]; - wif->country_code[2] = regdomain->rd.location; - free(regdomain); - - return (0); -} - -int -wlan_config_get_dssid(struct wlan_iface *wif) -{ - int val = -1; - size_t argsize = IEEE80211_NWID_LEN + 1; - char ssid[IEEE80211_NWID_LEN + 1]; - - memset(ssid, 0, IEEE80211_NWID_LEN + 1); - - if (wlan_ioctl(wif->wname, - (wif->mode == WlanIfaceOperatingModeType_meshPoint) ? - IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid, - &argsize, 0) < 0) - return (-1); - - if (argsize > IEEE80211_NWID_LEN) - argsize = IEEE80211_NWID_LEN; - memcpy(wif->desired_ssid, ssid, argsize); - wif->desired_ssid[argsize] = '\0'; - - return (0); -} - -int -wlan_config_set_dssid(struct wlan_iface *wif, char *ssid, int slen) -{ - int val = 0; - size_t argsize = slen; - - if (wlan_ioctl(wif->wname, - (wif->mode == WlanIfaceOperatingModeType_meshPoint) ? - IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid, - &argsize, 1) < 0) - return (-1); - - if (argsize > IEEE80211_NWID_LEN) - argsize = IEEE80211_NWID_LEN; - memcpy(wif->desired_ssid, ssid, argsize); - wif->desired_ssid[argsize] = '\0'; - - return (0); -} - -static int -wlan_config_get_dchannel(struct wlan_iface *wif) -{ - uint32_t i = 0; - int val = 0; - size_t argsize = sizeof(struct ieee80211_channel); - struct ieee80211_channel chan; - - if (wlan_get_channel_list(wif) < 0) - return (-1); - - memset(&chan, 0, sizeof(chan)); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan, - &argsize, 0) < 0) - return (-1); - - for (i = 0; i < wif->nchannels; i++) - if (chan.ic_ieee == wif->chanlist[i].ic_ieee && - chan.ic_flags == wif->chanlist[i].ic_flags) { - wif->desired_channel = i + 1; - break; - } - - return (0); -} - -static int -wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t dchannel) -{ - int val = 0; - size_t argsize = sizeof(struct ieee80211_channel); - struct ieee80211_channel chan; - - if (wlan_get_channel_list(wif) < 0) - return (-1); - - if (dchannel > wif->nchannels) - return (-1); - - memcpy(&chan, wif->chanlist + dchannel - 1, sizeof(chan)); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan, - &argsize, 1) < 0) - return (-1); - - wif->desired_channel = dchannel; - - return (0); -} - -static int -wlan_config_get_bssid(struct wlan_iface *wif) -{ - int val = 0; - size_t argsize = IEEE80211_ADDR_LEN; - char bssid[IEEE80211_ADDR_LEN]; - - memset(bssid, 0, IEEE80211_ADDR_LEN); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid, - &argsize, 0) < 0 || argsize != IEEE80211_ADDR_LEN) - return (-1); - - memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN); - - return (0); -} - -static int -wlan_config_set_bssid(struct wlan_iface *wif, uint8_t *bssid) -{ - int val = 0; - size_t argsize = IEEE80211_ADDR_LEN; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid, - &argsize, 1) < 0 || argsize != IEEE80211_ADDR_LEN) - return (-1); - - memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN); - - return (0); -} - -/* - * Convert the value returned by the kernel to the appropriate SNMP - * representation and set the corresponding interface member accordingly. - */ -static void -wlan_config_set_snmp_intval(struct wlan_iface *wif, int op, int val) -{ - switch (op) { - case IEEE80211_IOC_BURST: - if (val == 0) - wif->packet_burst = TruthValue_false; - else - wif->packet_burst = TruthValue_true; - break; - case IEEE80211_IOC_DFS: - if (val == 0) - wif->dyn_frequency = TruthValue_false; - else - wif->dyn_frequency = TruthValue_true; - break; - case IEEE80211_IOC_FF: - if (val == 0) - wif->fast_frames = TruthValue_false; - else - wif->fast_frames = TruthValue_true; - break; - case IEEE80211_IOC_TURBOP: - if (val == 0) - wif->dturbo = TruthValue_false; - else - wif->dturbo = TruthValue_true; - break; - case IEEE80211_IOC_TXPOWER: - wif->tx_power = val / 2; - break; - case IEEE80211_IOC_FRAGTHRESHOLD: - wif->frag_threshold = val; - break; - case IEEE80211_IOC_RTSTHRESHOLD: - wif->rts_threshold = val; - break; - case IEEE80211_IOC_WPS: - if (val == 0) - wif->priv_subscribe = TruthValue_false; - else - wif->priv_subscribe = TruthValue_true; - break; - case IEEE80211_IOC_BGSCAN: - if (val == 0) - wif->bg_scan = TruthValue_false; - else - wif->bg_scan = TruthValue_true; - break; - case IEEE80211_IOC_BGSCAN_IDLE: - wif->bg_scan_idle = val; - break; - case IEEE80211_IOC_BGSCAN_INTERVAL: - wif->bg_scan_interval = val; - break; - case IEEE80211_IOC_BMISSTHRESHOLD: - wif->beacons_missed = val; - break; - case IEEE80211_IOC_ROAMING: - switch (val) { - case IEEE80211_ROAMING_DEVICE: - wif->roam_mode = wlanIfaceRoamingMode_device; - break; - case IEEE80211_ROAMING_MANUAL: - wif->roam_mode = wlanIfaceRoamingMode_manual; - break; - case IEEE80211_ROAMING_AUTO: - /* FALTHROUGH */ - default: - wif->roam_mode = wlanIfaceRoamingMode_auto; - break; - } - break; - case IEEE80211_IOC_DOTD: - if (val == 0) - wif->dot11d = TruthValue_false; - else - wif->dot11d = TruthValue_true; - break; - case IEEE80211_IOC_DOTH: - if (val == 0) - wif->dot11h = TruthValue_false; - else - wif->dot11h = TruthValue_true; - break; - case IEEE80211_IOC_DWDS: - if (val == 0) - wif->dynamic_wds = TruthValue_false; - else - wif->dynamic_wds = TruthValue_true; - break; - case IEEE80211_IOC_POWERSAVE: - if (val == 0) - wif->power_save = TruthValue_false; - else - wif->power_save = TruthValue_true; - break; - case IEEE80211_IOC_APBRIDGE: - if (val == 0) - wif->ap_bridge = TruthValue_false; - else - wif->ap_bridge = TruthValue_true; - break; - case IEEE80211_IOC_BEACON_INTERVAL: - wif->beacon_interval = val; - break; - case IEEE80211_IOC_DTIM_PERIOD: - wif->dtim_period = val; - break; - case IEEE80211_IOC_HIDESSID: - if (val == 0) - wif->hide_ssid = TruthValue_false; - else - wif->hide_ssid = TruthValue_true; - break; - case IEEE80211_IOC_INACTIVITY: - if (val == 0) - wif->inact_process = TruthValue_false; - else - wif->inact_process = TruthValue_true; - break; - case IEEE80211_IOC_PROTMODE: - switch (val) { - case IEEE80211_PROTMODE_CTS: - wif->do11g_protect = wlanIfaceDot11gProtMode_cts; - break; - case IEEE80211_PROTMODE_RTSCTS: - wif->do11g_protect = wlanIfaceDot11gProtMode_rtscts; - break; - case IEEE80211_PROTMODE_OFF: - /* FALLTHROUGH */ - default: - wif->do11g_protect = wlanIfaceDot11gProtMode_off; - break; - } - break; - case IEEE80211_IOC_PUREG: - if (val == 0) - wif->dot11g_pure = TruthValue_false; - else - wif->dot11g_pure = TruthValue_true; - break; - case IEEE80211_IOC_PUREN: - if (val == 0) - wif->dot11n_pure = TruthValue_false; - else - wif->dot11n_pure = TruthValue_true; - break; - case IEEE80211_IOC_AMPDU: - switch (val) { - case 0: - wif->ampdu = WlanIfaceDot11nPduType_disabled; - break; - case 1: - wif->ampdu = WlanIfaceDot11nPduType_txOnly; - break; - case 2: - wif->ampdu = WlanIfaceDot11nPduType_rxOnly; - break; - case 3: - /* FALLTHROUGH */ - default: - wif->ampdu = WlanIfaceDot11nPduType_txAndRx; - break; - } - break; - case IEEE80211_IOC_AMPDU_DENSITY: - switch (val) { - case IEEE80211_HTCAP_MPDUDENSITY_025: - wif->ampdu_density = 25; - break; - case IEEE80211_HTCAP_MPDUDENSITY_05: - wif->ampdu_density = 50; - break; - case IEEE80211_HTCAP_MPDUDENSITY_1: - wif->ampdu_density = 100; - break; - case IEEE80211_HTCAP_MPDUDENSITY_2: - wif->ampdu_density = 200; - break; - case IEEE80211_HTCAP_MPDUDENSITY_4: - wif->ampdu_density = 400; - break; - case IEEE80211_HTCAP_MPDUDENSITY_8: - wif->ampdu_density = 800; - break; - case IEEE80211_HTCAP_MPDUDENSITY_16: - wif->ampdu_density = 1600; - break; - case IEEE80211_HTCAP_MPDUDENSITY_NA: - default: - wif->ampdu_density = 0; - break; - } - break; - case IEEE80211_IOC_AMPDU_LIMIT: - switch (val) { - case IEEE80211_HTCAP_MAXRXAMPDU_8K: - wif->ampdu_limit = 8192; - break; - case IEEE80211_HTCAP_MAXRXAMPDU_16K: - wif->ampdu_limit = 16384; - break; - case IEEE80211_HTCAP_MAXRXAMPDU_32K: - wif->ampdu_limit = 32768; - break; - case IEEE80211_HTCAP_MAXRXAMPDU_64K: - default: - wif->ampdu_limit = 65536; - break; - } - break; - case IEEE80211_IOC_AMSDU: - switch (val) { - case 0: - wif->amsdu = WlanIfaceDot11nPduType_disabled; - break; - case 1: - wif->amsdu = WlanIfaceDot11nPduType_txOnly; - break; - case 3: - wif->amsdu = WlanIfaceDot11nPduType_txAndRx; - break; - case 2: - default: - /* FALLTHROUGH */ - wif->amsdu = WlanIfaceDot11nPduType_rxOnly; - break; - } - break; - case IEEE80211_IOC_AMSDU_LIMIT: - wif->amsdu_limit = val; - break; - case IEEE80211_IOC_HTCONF: - if (val == 0) /* XXX */ - wif->ht_enabled = TruthValue_false; - else - wif->ht_enabled = TruthValue_true; - break; - case IEEE80211_IOC_HTCOMPAT: - if (val == 0) - wif->ht_compatible = TruthValue_false; - else - wif->ht_compatible = TruthValue_true; - break; - case IEEE80211_IOC_HTPROTMODE: - if (val == IEEE80211_PROTMODE_RTSCTS) - wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_rts; - else - wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_off; - break; - case IEEE80211_IOC_RIFS: - if (val == 0) - wif->rifs = TruthValue_false; - else - wif->rifs = TruthValue_true; - break; - case IEEE80211_IOC_SHORTGI: - if (val == 0) - wif->short_gi = TruthValue_false; - else - wif->short_gi = TruthValue_true; - break; - case IEEE80211_IOC_SMPS: - switch (val) { - case IEEE80211_HTCAP_SMPS_DYNAMIC: - wif->smps_mode = wlanIfaceDot11nSMPSMode_dynamic; - break; - case IEEE80211_HTCAP_SMPS_ENA: - wif->smps_mode = wlanIfaceDot11nSMPSMode_static; - break; - case IEEE80211_HTCAP_SMPS_OFF: - /* FALLTHROUGH */ - default: - wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled; - break; - } - break; - case IEEE80211_IOC_TDMA_SLOT: - wif->tdma_slot = val; - break; - case IEEE80211_IOC_TDMA_SLOTCNT: - wif->tdma_slot_count = val; - break; - case IEEE80211_IOC_TDMA_SLOTLEN: - wif->tdma_slot_length = val; - break; - case IEEE80211_IOC_TDMA_BINTERVAL: - wif->tdma_binterval = val; - break; - default: - break; - } -} - -/* - * Convert an SNMP value to the kernel equivalent and also do sanity check - * for each specific type. - */ -static int -wlan_config_snmp2value(int which, int sval, int *value) -{ - *value = 0; - - switch (which) { - case IEEE80211_IOC_BURST: - case IEEE80211_IOC_DFS: - case IEEE80211_IOC_FF: - case IEEE80211_IOC_TURBOP: - case IEEE80211_IOC_WPS: - case IEEE80211_IOC_BGSCAN: - case IEEE80211_IOC_DOTD: - case IEEE80211_IOC_DOTH: - case IEEE80211_IOC_DWDS: - case IEEE80211_IOC_POWERSAVE: - case IEEE80211_IOC_APBRIDGE: - case IEEE80211_IOC_HIDESSID: - case IEEE80211_IOC_INACTIVITY: - case IEEE80211_IOC_PUREG: - case IEEE80211_IOC_PUREN: - case IEEE80211_IOC_HTCONF: - case IEEE80211_IOC_HTCOMPAT: - case IEEE80211_IOC_RIFS: - if (sval == TruthValue_true) - *value = 1; - else if (sval != TruthValue_false) - return (SNMP_ERR_INCONS_VALUE); - break; - case IEEE80211_IOC_REGDOMAIN: - break; - case IEEE80211_IOC_SSID: - break; - case IEEE80211_IOC_CURCHAN: - break; - case IEEE80211_IOC_TXPOWER: - *value = sval * 2; - break; - case IEEE80211_IOC_FRAGTHRESHOLD: - if (sval < IEEE80211_FRAG_MIN || sval > IEEE80211_FRAG_MAX) - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_RTSTHRESHOLD: - if (sval < IEEE80211_RTS_MIN || sval > IEEE80211_RTS_MAX) - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_BGSCAN_IDLE: - if (sval < WLAN_BGSCAN_IDLE_MIN) - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_BGSCAN_INTERVAL: - if (sval < WLAN_SCAN_VALID_MIN) - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_BMISSTHRESHOLD: - if (sval < IEEE80211_HWBMISS_MIN || sval > IEEE80211_HWBMISS_MAX) - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_BSSID: - break; - case IEEE80211_IOC_ROAMING: - switch (sval) { - case wlanIfaceRoamingMode_device: - *value = IEEE80211_ROAMING_DEVICE; - break; - case wlanIfaceRoamingMode_manual: - *value = IEEE80211_ROAMING_MANUAL; - break; - case wlanIfaceRoamingMode_auto: - *value = IEEE80211_ROAMING_AUTO; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_BEACON_INTERVAL: - if (sval < IEEE80211_BINTVAL_MIN || sval > IEEE80211_BINTVAL_MAX) - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_DTIM_PERIOD: - if (sval < IEEE80211_DTIM_MIN || sval > IEEE80211_DTIM_MAX) - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_PROTMODE: - switch (sval) { - case wlanIfaceDot11gProtMode_cts: - *value = IEEE80211_PROTMODE_CTS; - break; - case wlanIfaceDot11gProtMode_rtscts: - *value = IEEE80211_PROTMODE_RTSCTS; - break; - case wlanIfaceDot11gProtMode_off: - *value = IEEE80211_PROTMODE_OFF; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_AMPDU: - switch (sval) { - case WlanIfaceDot11nPduType_disabled: - break; - case WlanIfaceDot11nPduType_txOnly: - *value = 1; - break; - case WlanIfaceDot11nPduType_rxOnly: - *value = 2; - break; - case WlanIfaceDot11nPduType_txAndRx: - *value = 3; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_AMPDU_DENSITY: - switch (sval) { - case 0: - *value = IEEE80211_HTCAP_MPDUDENSITY_NA; - break; - case 25: - *value = IEEE80211_HTCAP_MPDUDENSITY_025; - break; - case 50: - *value = IEEE80211_HTCAP_MPDUDENSITY_05; - break; - case 100: - *value = IEEE80211_HTCAP_MPDUDENSITY_1; - break; - case 200: - *value = IEEE80211_HTCAP_MPDUDENSITY_2; - break; - case 400: - *value = IEEE80211_HTCAP_MPDUDENSITY_4; - break; - case 800: - *value = IEEE80211_HTCAP_MPDUDENSITY_8; - break; - case 1600: - *value = IEEE80211_HTCAP_MPDUDENSITY_16; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_AMPDU_LIMIT: - switch (sval) { - case 8192: - *value = IEEE80211_HTCAP_MAXRXAMPDU_8K; - break; - case 16384: - *value = IEEE80211_HTCAP_MAXRXAMPDU_16K; - break; - case 32768: - *value = IEEE80211_HTCAP_MAXRXAMPDU_32K; - break; - case 65536: - *value = IEEE80211_HTCAP_MAXRXAMPDU_64K; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_AMSDU: - switch (sval) { - case WlanIfaceDot11nPduType_disabled: - break; - case WlanIfaceDot11nPduType_txOnly: - *value = 1; - break; - case WlanIfaceDot11nPduType_rxOnly: - *value = 2; - break; - case WlanIfaceDot11nPduType_txAndRx: - *value = 3; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_AMSDU_LIMIT: - if (sval == 3839 || sval == 0) - *value = IEEE80211_HTCAP_MAXAMSDU_3839; - else if (sval == 7935) - *value = IEEE80211_HTCAP_MAXAMSDU_7935; - else - return (SNMP_ERR_INCONS_VALUE); - break; - case IEEE80211_IOC_HTPROTMODE: - switch (sval) { - case wlanIfaceDot11nHTProtMode_rts: - *value = IEEE80211_PROTMODE_RTSCTS; - break; - case wlanIfaceDot11nHTProtMode_off: - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_SHORTGI: - if (sval == TruthValue_true) - *value = IEEE80211_HTCAP_SHORTGI20 | - IEEE80211_HTCAP_SHORTGI40; - else if (sval != TruthValue_false) - return (SNMP_ERR_INCONS_VALUE); - break; - case IEEE80211_IOC_SMPS: - switch (sval) { - case wlanIfaceDot11nSMPSMode_disabled: - *value = IEEE80211_HTCAP_SMPS_OFF; - break; - case wlanIfaceDot11nSMPSMode_static: - *value = IEEE80211_HTCAP_SMPS_ENA; - break; - case wlanIfaceDot11nSMPSMode_dynamic: - *value = IEEE80211_HTCAP_SMPS_DYNAMIC; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - break; - case IEEE80211_IOC_TDMA_SLOT: - if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */ - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_TDMA_SLOTCNT: - if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */ - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_TDMA_SLOTLEN: - if (sval < 2*100 || sval > 0xfffff) /* XXX */ - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - case IEEE80211_IOC_TDMA_BINTERVAL: - if (sval < 1) /* XXX */ - return (SNMP_ERR_INCONS_VALUE); - *value = sval; - break; - default: - return (SNMP_ERR_INCONS_VALUE); - } - - return (SNMP_ERR_NOERROR); -} - -/* - * Sanity checks for the wlanIfaceConfigTable. - */ -static int -wlan_config_check(struct wlan_iface *wif, int op) -{ - switch (op) { - case IEEE80211_IOC_BURST: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_burst)) == 0) { - wif->packet_burst = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_DFS: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_dfs)) == 0) { - wif->dyn_frequency = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_FF: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_athFastFrames)) - == 0) { - wif->fast_frames = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_TURBOP: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_athTurbo)) == 0) { - wif->dturbo = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_TXPOWER: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_txPmgt)) == 0) { - wif->tx_power = 0; - return (-1); - } - break; - case IEEE80211_IOC_FRAGTHRESHOLD: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_txFrag)) == 0) { - wif->frag_threshold = IEEE80211_FRAG_MAX; - return (-1); - } - break; - case IEEE80211_IOC_DWDS: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_wds)) == 0) { - wif->dynamic_wds = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_POWERSAVE: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_pmgt)) == 0) { - wif->power_save = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_BEACON_INTERVAL: - if (wif->mode != WlanIfaceOperatingModeType_hostAp && - wif->mode != WlanIfaceOperatingModeType_meshPoint && - wif->mode != WlanIfaceOperatingModeType_ibss) { - wif->beacon_interval = 100; /* XXX */ - return (-1); - } - break; - case IEEE80211_IOC_DTIM_PERIOD: - if (wif->mode != WlanIfaceOperatingModeType_hostAp && - wif->mode != WlanIfaceOperatingModeType_meshPoint && - wif->mode != WlanIfaceOperatingModeType_ibss) { - wif->dtim_period = 1; /* XXX */ - return (-1); - } - break; - case IEEE80211_IOC_PUREN: - if ((wif->htcaps & (0x1 << WlanHTCaps_htcHt)) == 0) { - wif->dot11n_pure = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_AMPDU: - if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmpdu)) == 0) { - wif->ampdu = WlanIfaceDot11nPduType_disabled; - return (-1); - } - break; - case IEEE80211_IOC_AMSDU: - if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmsdu)) == 0) { - wif->amsdu = WlanIfaceDot11nPduType_disabled; - return (-1); - } - break; - case IEEE80211_IOC_RIFS: - if ((wif->htcaps & (0x1 << WlanHTCaps_htcRifs)) == 0) { - wif->rifs = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_SHORTGI: - if ((wif->htcaps & (0x1 << WlanHTCaps_shortGi20 | - 0x1 << WlanHTCaps_shortGi40)) == 0) { - wif->short_gi = TruthValue_false; - return (-1); - } - break; - case IEEE80211_IOC_SMPS: - if ((wif->htcaps & (0x1 << WlanHTCaps_htcSmps)) == 0) { - wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled; - return (-1); - } - break; - case IEEE80211_IOC_TDMA_SLOT: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { - wif->tdma_slot = 0; - return (-1); - } - break; - case IEEE80211_IOC_TDMA_SLOTCNT: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { - wif->tdma_slot_count = 0; - return (-1); - } - break; - case IEEE80211_IOC_TDMA_SLOTLEN: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { - wif->tdma_slot_length = 0; - return (-1); - } - break; - case IEEE80211_IOC_TDMA_BINTERVAL: - if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { - wif->tdma_binterval = 0; - return (-1); - } - break; - default: - break; - } - - return (0); -} - -static int -wlan_config_get_intval(struct wlan_iface *wif, int op) -{ - int val = 0; - size_t argsize = 0; - - if (wlan_config_check(wif, op) < 0) - return (0); - if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0) - return (-1); - wlan_config_set_snmp_intval(wif, op, val); - - return (0); -} - -static int -wlan_config_set_intval(struct wlan_iface *wif, int op, int sval) -{ - size_t argsize = 0; - int val; - - if (wlan_config_check(wif, op) < 0) - return (-1); - if (wlan_config_snmp2value(op, sval, &val) != SNMP_ERR_NOERROR) - return (-1); - if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0) - return (-1); - wlan_config_set_snmp_intval(wif, op, val); - - return (0); -} - -int -wlan_config_get_ioctl(struct wlan_iface *wif, int which) -{ - int op; - - switch (which) { - case LEAF_wlanIfaceCountryCode: - /* FALLTHROUGH */ - case LEAF_wlanIfaceRegDomain: - return (wlan_config_get_country(wif)); - case LEAF_wlanIfaceDesiredSsid: - return (wlan_config_get_dssid(wif)); - case LEAF_wlanIfaceDesiredChannel: - return (wlan_config_get_dchannel(wif)); - case LEAF_wlanIfaceDesiredBssid: - return (wlan_config_get_bssid(wif)); - default: - op = wlan_config_snmp2ioctl(which); - return (wlan_config_get_intval(wif, op)); - } - - return (-1); -} - -int -wlan_config_set_ioctl(struct wlan_iface *wif, int which, int val, - char *strval, int len) -{ - int op; - - switch (which) { - case LEAF_wlanIfaceCountryCode: - return (wlan_config_set_country(wif, strval, - wif->reg_domain)); - case LEAF_wlanIfaceRegDomain: - return (wlan_config_set_country(wif, wif->country_code, - val)); - case LEAF_wlanIfaceDesiredSsid: - return (wlan_config_set_dssid(wif, strval, len)); - case LEAF_wlanIfaceDesiredChannel: - return (wlan_config_set_dchannel(wif, val)); - case LEAF_wlanIfaceDesiredBssid: - return (wlan_config_set_bssid(wif, strval)); - default: - op = wlan_config_snmp2ioctl(which); - return (wlan_config_set_intval(wif, op, val)); - } - - return (-1); -} - -static uint32_t -wlan_snmp_to_scan_flags(int flags) -{ - int sr_flags = 0; - - if ((flags & (0x1 << WlanScanFlagsType_noSelection)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_NOPICK; - if ((flags & (0x1 << WlanScanFlagsType_activeScan)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_ACTIVE; - if ((flags & (0x1 << WlanScanFlagsType_pickFirst)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_PICK1ST; - if ((flags & (0x1 << WlanScanFlagsType_backgroundScan)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_BGSCAN; - if ((flags & (0x1 << WlanScanFlagsType_once)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_ONCE; - if ((flags & (0x1 << WlanScanFlagsType_noBroadcast)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_NOBCAST; - if ((flags & (0x1 << WlanScanFlagsType_noAutoSequencing)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_NOJOIN; - if ((flags & (0x1 << WlanScanFlagsType_flushCashe)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_FLUSH; - if ((flags & (0x1 << WlanScanFlagsType_chechCashe)) != 0) - sr_flags |= IEEE80211_IOC_SCAN_CHECK; - - return (sr_flags); -} - -int -wlan_set_scan_config(struct wlan_iface *wif) -{ - int val = 0; - size_t argsize; - struct ieee80211_scan_req sr; - - - memset(&sr, 0, sizeof(sr)); - argsize = sizeof(struct ieee80211_scan_req); - sr.sr_flags = wlan_snmp_to_scan_flags(wif->scan_flags); - sr.sr_flags |= IEEE80211_IOC_SCAN_BGSCAN; - sr.sr_duration = wif->scan_duration; - sr.sr_mindwell = wif->scan_mindwell; - sr.sr_maxdwell = wif->scan_maxdwell; - sr.sr_nssid = 0; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_REQ, - &val, &sr, &argsize, 1) < 0) - return (-1); - - wif->scan_status = wlanScanConfigStatus_running; - return (0); -} - -static uint32_t -wlan_peercaps_to_snmp(uint32_t pcaps) -{ - uint32_t scaps = 0; - - if ((pcaps & IEEE80211_CAPINFO_ESS) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_ess); - if ((pcaps & IEEE80211_CAPINFO_IBSS) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_ibss); - if ((pcaps & IEEE80211_CAPINFO_CF_POLLABLE) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollable); - if ((pcaps & IEEE80211_CAPINFO_CF_POLLREQ) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollRequest); - if ((pcaps & IEEE80211_CAPINFO_PRIVACY) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_privacy); - if ((pcaps & IEEE80211_CAPINFO_SHORT_PREAMBLE) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_shortPreamble); - if ((pcaps & IEEE80211_CAPINFO_PBCC) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_pbcc); - if ((pcaps & IEEE80211_CAPINFO_CHNL_AGILITY) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_channelAgility); - if ((pcaps & IEEE80211_CAPINFO_SHORT_SLOTTIME) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_shortSlotTime); - if ((pcaps & IEEE80211_CAPINFO_RSN) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_rsn); - if ((pcaps & IEEE80211_CAPINFO_DSSSOFDM) != 0) - scaps |= (0x1 << WlanPeerCapabilityFlags_dsssofdm); - - return (scaps); -} - -static int -wlan_add_new_scan_result(struct wlan_iface *wif, - const struct ieee80211req_scan_result *isr, uint8_t *ssid) -{ - struct wlan_scan_result *sr; - - if ((sr = wlan_scan_new_result(ssid, isr->isr_bssid)) == NULL) - return (-1); - - sr->opchannel = wlan_channel_flags_to_snmp_phy(isr->isr_flags); - sr->rssi = isr->isr_rssi; - sr->frequency = isr->isr_freq; - sr->noise = isr->isr_noise; - sr->bintval = isr->isr_intval; - sr->capinfo = wlan_peercaps_to_snmp(isr->isr_capinfo); - - if (wlan_scan_add_result(wif, sr) < 0) { - wlan_scan_free_result(sr); - return (-1); - } - - return (0); -} - -int -wlan_get_scan_results(struct wlan_iface *wif) -{ - int ssidlen, val = 0; - uint8_t buf[24 * 1024]; - size_t argsize; - const uint8_t *cp, *idp; - uint8_t ssid[IEEE80211_NWID_LEN + 1]; - struct ieee80211req_scan_result isr; - - argsize = sizeof(buf); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_RESULTS, &val, &buf, - &argsize, 0) < 0) - return (-1); - - if (argsize < sizeof(struct ieee80211req_scan_result)) - return (0); - - cp = buf; - do { - memcpy(&isr, cp, sizeof(struct ieee80211req_scan_result)); - memset(ssid, 0, IEEE80211_NWID_LEN + 1); - - if (isr.isr_meshid_len) { - idp = cp + isr.isr_ie_off + isr.isr_ssid_len; - ssidlen = isr.isr_meshid_len; - } else { - idp = cp + isr.isr_ie_off; - ssidlen = isr.isr_ssid_len; - } - if (ssidlen > IEEE80211_NWID_LEN) - ssidlen = IEEE80211_NWID_LEN; - memcpy(ssid, idp, ssidlen); - ssid[IEEE80211_NWID_LEN] = '\0'; - (void)wlan_add_new_scan_result(wif, &isr, ssid); - cp += isr.isr_len; - argsize -= isr.isr_len; - } while (argsize >= sizeof(struct ieee80211req_scan_result)); - - return (0); -} - -int -wlan_get_stats(struct wlan_iface *wif) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(struct ifreq)); - strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ); - - ifr.ifr_data = (caddr_t) &wif->stats; - - if (ioctl(sock, SIOCG80211STATS, &ifr) < 0) { - syslog(LOG_ERR, "iface %s - ioctl(SIOCG80211STATS) failed: %s", - wif->wname, strerror(errno)); - return (-1); - } - - return (0); -} - -int -wlan_get_wepmode(struct wlan_iface *wif) -{ - int val = 0; - size_t argsize = 0; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL, - &argsize, 0) < 0 || val == IEEE80211_WEP_NOSUP) { - wif->wepsupported = 0; /* XXX */ - wif->wepmode = wlanWepMode_off; - wif->weptxkey = 0; - return (-1); - } - - wif->wepsupported = 1; - - switch (val) { - case IEEE80211_WEP_ON: - wif->wepmode = wlanWepMode_on; - break; - case IEEE80211_WEP_MIXED: - wif->wepmode = wlanWepMode_mixed; - break; - case IEEE80211_WEP_OFF: - /* FALLTHROUGH */ - default: - wif->wepmode = wlanWepMode_off; - break; - } - - return (0); -} - -int -wlan_set_wepmode(struct wlan_iface *wif) -{ - int val; - size_t argsize = 0; - - if (!wif->wepsupported) - return (-1); - - switch (wif->wepmode) { - case wlanWepMode_off: - val = IEEE80211_WEP_OFF; - break; - case wlanWepMode_on: - val = IEEE80211_WEP_ON; - break; - case wlanWepMode_mixed: - val = IEEE80211_WEP_MIXED; - break; - default: - return (-1); - } - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL, - &argsize, 1) < 0) - return (-1); - - return (0); -} - -int -wlan_get_weptxkey(struct wlan_iface *wif) -{ - int val; - size_t argsize = 0; - - if (!wif->wepsupported) - return (0); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL, - &argsize, 0) < 0) - return (-1); - - if (val == IEEE80211_KEYIX_NONE) - wif->weptxkey = 0; - else - wif->weptxkey = val + 1; - - return (0); -} - -int -wlan_set_weptxkey(struct wlan_iface *wif) -{ - int val; - size_t argsize = 0; - - if (!wif->wepsupported) - return (0); - - if (wif->weptxkey >= IEEE80211_WEP_NKID) - return (-1); - - if (wif->weptxkey == 0) - val = IEEE80211_KEYIX_NONE; - else - val = wif->weptxkey - 1; - if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL, - &argsize, 1) < 0) - return (-1); - - return (0); -} - -int -wlan_get_wepkeys(struct wlan_iface *wif __unused) -{ - /* XXX: should they be visible via SNMP */ - return (0); -} - -int -wlan_set_wepkeys(struct wlan_iface *wif __unused) -{ - /* XXX: should they be configurable via SNMP */ - return (0); -} - -int -wlan_get_mac_policy(struct wlan_iface *wif) -{ - int val = IEEE80211_MACCMD_POLICY; - size_t argsize = 0; - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(struct ieee80211req)); - strlcpy(ireq.i_name, wif->wname, IFNAMSIZ); - ireq.i_type = IEEE80211_IOC_MACCMD; - ireq.i_val = IEEE80211_MACCMD_POLICY; - - if (ioctl(sock, SIOCG80211, &ireq) < 0) { - if (errno != EINVAL) { - syslog(LOG_ERR, "iface %s - get param: ioctl(%d) " - "failed: %s", wif->wname, ireq.i_type, - strerror(errno)); - wif->macsupported = 0; - return (-1); - } else { - wif->macsupported = 1; - wif->mac_policy = wlanMACAccessControlPolicy_open; - return (0); - } - - } - - wif->macsupported = 1; - - switch (val) { - case IEEE80211_MACCMD_POLICY_ALLOW: - wif->mac_policy = wlanMACAccessControlPolicy_allow; - break; - case IEEE80211_MACCMD_POLICY_DENY: - wif->mac_policy = wlanMACAccessControlPolicy_deny; - break; - case IEEE80211_MACCMD_POLICY_RADIUS: - wif->mac_policy = wlanMACAccessControlPolicy_radius; - break; - case IEEE80211_MACCMD_POLICY_OPEN: - /* FALLTHROUGH */ - default: - wif->mac_policy = wlanMACAccessControlPolicy_open; - break; - } - - argsize = 0; - val = IEEE80211_MACCMD_LIST; - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, - &argsize, 0) < 0) - return (-1); - - wif->mac_nacls = argsize / sizeof(struct ieee80211req_maclist *); - return (0); -} - -int -wlan_set_mac_policy(struct wlan_iface *wif) -{ - int val; - size_t argsize = 0; - - if (!wif->macsupported) - return (-1); - - switch (wif->mac_policy) { - case wlanMACAccessControlPolicy_allow: - val = IEEE80211_MACCMD_POLICY_ALLOW; - break; - case wlanMACAccessControlPolicy_deny: - val = IEEE80211_MACCMD_POLICY_DENY; - break; - case wlanMACAccessControlPolicy_radius: - val = IEEE80211_MACCMD_POLICY_RADIUS; - break; - case wlanMACAccessControlPolicy_open: - val = IEEE80211_MACCMD_POLICY_OPEN; - break; - default: - return (-1); - } - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, - &argsize, 1) < 0) - return (-1); - - return (0); -} - -int -wlan_flush_mac_mac(struct wlan_iface *wif) -{ - int val = IEEE80211_MACCMD_FLUSH; - size_t argsize = 0; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, - &argsize, 1) < 0) - return (-1); - - return (0); -} - -static int -wlan_add_mac_macinfo(struct wlan_iface *wif, - const struct ieee80211req_maclist *ml) -{ - struct wlan_mac_mac *mmac; - - if ((mmac = wlan_mac_new_mac(ml->ml_macaddr)) == NULL) - return (-1); - - mmac->mac_status = RowStatus_active; - if (wlan_mac_add_mac(wif, mmac) < 0) { - wlan_mac_free_mac(mmac); - return (-1); - } - - return (0); -} - -int -wlan_get_mac_acl_macs(struct wlan_iface *wif) -{ - int i, nacls, val = IEEE80211_MACCMD_LIST; - size_t argsize = 0; - uint8_t *data; - struct ieee80211req ireq; - const struct ieee80211req_maclist *acllist; - - if (wif->mac_policy == wlanMACAccessControlPolicy_radius) { - wif->mac_nacls = 0; - return (0); - } - - memset(&ireq, 0, sizeof(struct ieee80211req)); - strlcpy(ireq.i_name, wif->wname, IFNAMSIZ); - ireq.i_type = IEEE80211_IOC_MACCMD; - ireq.i_val = IEEE80211_MACCMD_LIST; - - - if (ioctl(sock, SIOCG80211, &ireq) < 0) { - if (errno != EINVAL) { - syslog(LOG_ERR, "iface %s - get param: ioctl(%d) " - "failed: %s", wif->wname, ireq.i_type, - strerror(errno)); - wif->macsupported = 0; - return (-1); - } - } - - if (argsize == 0) { - wif->mac_nacls = 0; - return (0); - } - - if ((data = (uint8_t *)malloc(argsize)) == NULL) - return (-1); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, data, - &argsize, 0) < 0) - return (-1); - - nacls = argsize / sizeof(*acllist); - acllist = (struct ieee80211req_maclist *) data; - for (i = 0; i < nacls; i++) - (void)wlan_add_mac_macinfo(wif, acllist + i); - - wif->mac_nacls = nacls; - return (0); -} - -int -wlan_add_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac) -{ - int val = 0; - size_t argsize = IEEE80211_ADDR_LEN; - struct ieee80211req_mlme mlme; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_ADDMAC, &val, - mmac->mac, &argsize, 1) < 0) - return (-1); - - mmac->mac_status = RowStatus_active; - - /* If policy is deny, try to kick the station just in case. */ - if (wif->mac_policy != wlanMACAccessControlPolicy_deny) - return (0); - - memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_DEAUTH; - mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; - memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN); - argsize = sizeof(struct ieee80211req_mlme); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme, - &argsize, 1) < 0 && errno != ENOENT) - return (-1); - - return (0); -} - -int -wlan_del_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac) -{ - int val = 0; - size_t argsize = IEEE80211_ADDR_LEN; - struct ieee80211req_mlme mlme; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_DELMAC, &val, - mmac->mac, &argsize, 1) < 0) - return (-1); - - mmac->mac_status = RowStatus_active; - - /* If policy is allow, try to kick the station just in case. */ - if (wif->mac_policy != wlanMACAccessControlPolicy_allow) - return (0); - - memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_DEAUTH; - mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; - memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN); - argsize = sizeof(struct ieee80211req_mlme); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme, - &argsize, 1) < 0 && errno != ENOENT) - return (-1); - - return (0); -} - -int -wlan_peer_set_vlan(struct wlan_iface *wif, struct wlan_peer *wip, int vlan) -{ - int val = 0; - size_t argsize; - struct ieee80211req_sta_vlan vreq; - - memcpy(vreq.sv_macaddr, wip->pmac, IEEE80211_ADDR_LEN); - vreq.sv_vlan = vlan; - argsize = sizeof(struct ieee80211req_sta_vlan); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_VLAN, - &val, &vreq, &argsize, 1) < 0) - return (-1); - - wip->vlan = vlan; - - return (0); -} - -/* XXX */ -#ifndef IEEE80211_NODE_AUTH -#define IEEE80211_NODE_AUTH 0x000001 /* authorized for data */ -#define IEEE80211_NODE_QOS 0x000002 /* QoS enabled */ -#define IEEE80211_NODE_ERP 0x000004 /* ERP enabled */ -#define IEEE80211_NODE_PWR_MGT 0x000010 /* power save mode enabled */ -#define IEEE80211_NODE_AREF 0x000020 /* authentication ref held */ -#define IEEE80211_NODE_HT 0x000040 /* HT enabled */ -#define IEEE80211_NODE_HTCOMPAT 0x000080 /* HT setup w/ vendor OUI's */ -#define IEEE80211_NODE_WPS 0x000100 /* WPS association */ -#define IEEE80211_NODE_TSN 0x000200 /* TSN association */ -#define IEEE80211_NODE_AMPDU_RX 0x000400 /* AMPDU rx enabled */ -#define IEEE80211_NODE_AMPDU_TX 0x000800 /* AMPDU tx enabled */ -#define IEEE80211_NODE_MIMO_PS 0x001000 /* MIMO power save enabled */ -#define IEEE80211_NODE_MIMO_RTS 0x002000 /* send RTS in MIMO PS */ -#define IEEE80211_NODE_RIFS 0x004000 /* RIFS enabled */ -#define IEEE80211_NODE_SGI20 0x008000 /* Short GI in HT20 enabled */ -#define IEEE80211_NODE_SGI40 0x010000 /* Short GI in HT40 enabled */ -#define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ -#define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */ -#define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */ -#endif - -static uint32_t -wlan_peerstate_to_snmp(uint32_t pstate) -{ - uint32_t sstate = 0; - - if ((pstate & IEEE80211_NODE_AUTH) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_authorizedForData); - if ((pstate & IEEE80211_NODE_QOS) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_qosEnabled); - if ((pstate & IEEE80211_NODE_ERP) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_erpEnabled); - if ((pstate & IEEE80211_NODE_PWR_MGT) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_powerSaveMode); - if ((pstate & IEEE80211_NODE_AREF) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_authRefHeld); - if ((pstate & IEEE80211_NODE_HT) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_htEnabled); - if ((pstate & IEEE80211_NODE_HTCOMPAT) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_htCompat); - if ((pstate & IEEE80211_NODE_WPS) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_wpsAssoc); - if ((pstate & IEEE80211_NODE_TSN) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_tsnAssoc); - if ((pstate & IEEE80211_NODE_AMPDU_RX) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_ampduRx); - if ((pstate & IEEE80211_NODE_AMPDU_TX) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_ampduTx); - if ((pstate & IEEE80211_NODE_MIMO_PS) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_mimoPowerSave); - if ((pstate & IEEE80211_NODE_MIMO_RTS) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_sendRts); - if ((pstate & IEEE80211_NODE_RIFS) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_rifs); - if ((pstate & IEEE80211_NODE_SGI20) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT20); - if ((pstate & IEEE80211_NODE_SGI40) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT40); - if ((pstate & IEEE80211_NODE_AMSDU_RX) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_amsduRx); - if ((pstate & IEEE80211_NODE_AMSDU_TX) != 0) - sstate |= (0x1 << WlanIfacePeerFlagsType_amsduTx); - - return (sstate); -} - -static struct wlan_peer * -wlan_add_peerinfo(const struct ieee80211req_sta_info *si) -{ - struct wlan_peer *wip; - - if ((wip = wlan_new_peer(si->isi_macaddr))== NULL) - return (NULL); - - wip->associd = IEEE80211_AID(si->isi_associd); - wip->vlan = si->isi_vlan; - wip->frequency = si->isi_freq; - wip->fflags = si->isi_flags; - wip->txrate = si->isi_txrate; - wip->rssi = si->isi_rssi; - wip->idle = si->isi_inact; - wip->txseqs = si->isi_txseqs[0]; /* XXX */ - wip->rxseqs = si->isi_rxseqs[0]; /* XXX */ - wip->txpower = si->isi_txpower; - wip->capinfo = wlan_peercaps_to_snmp(si->isi_capinfo); - wip->state = wlan_peerstate_to_snmp(si->isi_state); - wip->local_id = si->isi_localid; - wip->peer_id = si->isi_peerid; - - return (wip); -} - -int -wlan_get_peerinfo(struct wlan_iface *wif) -{ - union { - struct ieee80211req_sta_req req; - uint8_t buf[24 * 1024]; - } u; - const uint8_t *cp; - int val = 0; - size_t len; - struct ieee80211req_sta_info si; - struct wlan_peer *wip; - - /* Get all stations - broadcast address */ - (void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN); - len = sizeof(u); - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_INFO, - & val, &u, &len, 0) < 0) - return (-1); - - if (len < sizeof(struct ieee80211req_sta_info)) - return (-1); - - cp = (const uint8_t *) u.req.info; - do { - memcpy(&si, cp, sizeof(struct ieee80211req_sta_info)); - if ((wip = wlan_add_peerinfo(&si)) != NULL && - wlan_add_peer(wif, wip) < 0) - wlan_free_peer(wip); - cp += si.isi_len, len -= si.isi_len; - } while (len >= sizeof(struct ieee80211req_sta_info)); - - return (0); -} - -/************************************************************************ - * Wireless MESH & HWMP sysctl config. - */ -const char wlan_sysctl_name[] = "net.wlan."; - -static const char *wlan_sysctl[] = { - "mesh.retrytimeout", - "mesh.holdingtimeout", - "mesh.confirmtimeout", - "mesh.maxretries", - "hwmp.targetonly", - "hwmp.replyforward", - "hwmp.pathlifetime", - "hwmp.roottimeout", - "hwmp.rootint", - "hwmp.rannint", - "hwmp.inact", -}; - -int32_t -wlan_do_sysctl(struct wlan_config *cfg, enum wlan_syscl which, int set) -{ - char mib_name[100]; - int val, sval; - size_t len, vlen; - - if (set) { - vlen = sizeof(sval); - switch (which) { - case WLAN_MESH_RETRY_TO: - sval = cfg->mesh_retryto; - break; - case WLAN_MESH_HOLDING_TO: - sval = cfg->mesh_holdingto; - break; - case WLAN_MESH_CONFIRM_TO: - sval = cfg->mesh_confirmto; - break; - case WLAN_MESH_MAX_RETRIES: - sval = cfg->mesh_maxretries; - break; - case WLAN_HWMP_TARGET_ONLY: - sval = cfg->hwmp_targetonly; - break; - case WLAN_HWMP_REPLY_FORWARD: - sval = cfg->hwmp_replyforward; - break; - case WLAN_HWMP_PATH_LIFETIME: - sval = cfg->hwmp_pathlifetime; - break; - case WLAN_HWMP_ROOT_TO: - sval = cfg->hwmp_roottimeout; - break; - case WLAN_HWMP_ROOT_INT: - sval = cfg->hwmp_rootint; - break; - case WLAN_HWMP_RANN_INT: - sval = cfg->hwmp_rannint; - break; - case WLAN_HWMP_INACTIVITY_TO: - sval = cfg->hwmp_inact; - break; - default: - return (-1); - } - } else { - if (which >= WLAN_SYSCTL_MAX) - return (-1); - vlen = 0; - } - - strlcpy(mib_name, wlan_sysctl_name, sizeof(mib_name)); - strlcat(mib_name, wlan_sysctl[which], sizeof(mib_name)); - len = sizeof (val); - - if (sysctlbyname(mib_name, &val, &len, (set? &sval : NULL), vlen) < 0) { - syslog(LOG_ERR, "sysctl(%s) failed - %s", mib_name, - strerror(errno)); - return (-1); - } - - switch (which) { - case WLAN_MESH_RETRY_TO: - cfg->mesh_retryto = val; - break; - case WLAN_MESH_HOLDING_TO: - cfg->mesh_holdingto = val; - break; - case WLAN_MESH_CONFIRM_TO: - cfg->mesh_confirmto = val; - break; - case WLAN_MESH_MAX_RETRIES: - cfg->mesh_maxretries = val; - break; - case WLAN_HWMP_TARGET_ONLY: - cfg->hwmp_targetonly = val; - break; - case WLAN_HWMP_REPLY_FORWARD: - cfg->hwmp_replyforward = val; - break; - case WLAN_HWMP_PATH_LIFETIME: - cfg->hwmp_pathlifetime = val; - break; - case WLAN_HWMP_ROOT_TO: - cfg->hwmp_roottimeout = val; - break; - case WLAN_HWMP_ROOT_INT: - cfg->hwmp_rootint = val; - break; - case WLAN_HWMP_RANN_INT: - cfg->hwmp_rannint = val; - break; - case WLAN_HWMP_INACTIVITY_TO: - cfg->hwmp_inact = val; - break; - default: - /* NOTREACHED */ - abort(); - } - - return (0); -} - -int -wlan_mesh_config_get(struct wlan_iface *wif, int which) -{ - int op, val = 0; - size_t argsize = 0; - uint8_t data[32], *pd = NULL; - - switch (which) { - case LEAF_wlanMeshTTL: - op = IEEE80211_IOC_MESH_TTL; - break; - case LEAF_wlanMeshPeeringEnabled: - op = IEEE80211_IOC_MESH_AP; - break; - case LEAF_wlanMeshForwardingEnabled: - op = IEEE80211_IOC_MESH_FWRD; - break; - case LEAF_wlanMeshMetric: - op = IEEE80211_IOC_MESH_PR_METRIC; - pd = data; - argsize = sizeof(data); - break; - case LEAF_wlanMeshPath: - op = IEEE80211_IOC_MESH_PR_PATH; - pd = data; - argsize = sizeof(data); - break; - case LEAF_wlanMeshRoutesFlush: - return (0); - default: - return (-1); - } - - if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 0) < 0) - return (-1); - - switch (which) { - case LEAF_wlanMeshTTL: - wif->mesh_ttl = val; - break; - case LEAF_wlanMeshPeeringEnabled: - if (val) - wif->mesh_peering = wlanMeshPeeringEnabled_true; - else - wif->mesh_peering = wlanMeshPeeringEnabled_false; - break; - case LEAF_wlanMeshForwardingEnabled: - if (val) - wif->mesh_forwarding = wlanMeshForwardingEnabled_true; - else - wif->mesh_forwarding = wlanMeshForwardingEnabled_false; - break; - case LEAF_wlanMeshMetric: - data[argsize] = '\0'; - if (strcmp(data, "AIRTIME") == 0) - wif->mesh_metric = wlanMeshMetric_airtime; - else - wif->mesh_metric = wlanMeshMetric_unknown; - break; - case LEAF_wlanMeshPath: - data[argsize] = '\0'; - if (strcmp(data, "HWMP") == 0) - wif->mesh_path = wlanMeshPath_hwmp; - else - wif->mesh_path = wlanMeshPath_unknown; - } - - return (0); -} - -int -wlan_mesh_config_set(struct wlan_iface *wif, int which) -{ - int op, val = 0; - size_t argsize = 0; - uint8_t data[32], *pd = NULL; - - switch (which) { - case LEAF_wlanMeshTTL: - op = IEEE80211_IOC_MESH_TTL; - val = wif->mesh_ttl; - break; - case LEAF_wlanMeshPeeringEnabled: - op = IEEE80211_IOC_MESH_AP; - if (wif->mesh_peering == wlanMeshPeeringEnabled_true) - val = 1; - break; - case LEAF_wlanMeshForwardingEnabled: - if (wif->mesh_forwarding == wlanMeshForwardingEnabled_true) - val = 1; - op = IEEE80211_IOC_MESH_FWRD; - break; - case LEAF_wlanMeshMetric: - op = IEEE80211_IOC_MESH_PR_METRIC; - if (wif->mesh_metric == wlanMeshMetric_airtime) - strcpy(data, "AIRTIME"); - else - return (-1); - pd = data; - argsize = sizeof(data); - break; - case LEAF_wlanMeshPath: - op = IEEE80211_IOC_MESH_PR_PATH; - if (wif->mesh_path == wlanMeshPath_hwmp) - strcpy(data, "HWMP"); - else - return (-1); - pd = data; - argsize = sizeof(data); - break; - default: - return (-1); - } - - if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 1) < 0) - return (-1); - - return(0); -} - -int -wlan_mesh_flush_routes(struct wlan_iface *wif) -{ - int val = IEEE80211_MESH_RTCMD_FLUSH; - size_t argsize = 0; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, NULL, - &argsize, 1) < 0) - return (-1); - - return (0); -} - -int -wlan_mesh_add_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr) -{ - int val = IEEE80211_MESH_RTCMD_ADD; - size_t argsize = IEEE80211_ADDR_LEN; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, - wmr->imroute.imr_dest, &argsize, 1) < 0) - return (-1); - - wmr->mroute_status = RowStatus_active; - - return (0); -} - -int -wlan_mesh_del_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr) -{ - int val = IEEE80211_MESH_RTCMD_DELETE; - size_t argsize = IEEE80211_ADDR_LEN; - - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, - wmr->imroute.imr_dest, &argsize, 1) < 0) - return (-1); - - wmr->mroute_status = RowStatus_destroy; - - return (0); -} - -int -wlan_mesh_get_routelist(struct wlan_iface *wif) -{ - int i, nroutes, val = IEEE80211_MESH_RTCMD_LIST; - size_t argsize; - struct ieee80211req_mesh_route routes[128]; - struct ieee80211req_mesh_route *rt; - struct wlan_mesh_route *wmr; - - argsize = sizeof(routes); - if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, routes, - &argsize, 0) < 0) /* XXX: ENOMEM? */ - return (-1); - - nroutes = argsize / sizeof(*rt); - for (i = 0; i < nroutes; i++) { - rt = routes + i; - if ((wmr = wlan_mesh_new_route(rt->imr_dest)) == NULL) - return (-1); - memcpy(&wmr->imroute, rt, sizeof(*rt)); - wmr->mroute_status = RowStatus_active; - if (wlan_mesh_add_rtentry(wif, wmr) < 0) - wlan_mesh_free_route(wmr); - } - - return (0); -} - -int -wlan_hwmp_config_get(struct wlan_iface *wif, int which) -{ - int op, val = 0; - size_t argsize = 0; - - switch (which) { - case LEAF_wlanHWMPRootMode: - op = IEEE80211_IOC_HWMP_ROOTMODE; - break; - case LEAF_wlanHWMPMaxHops: - op = IEEE80211_IOC_HWMP_MAXHOPS; - break; - default: - return (-1); - } - - if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0) - return (-1); - - switch (which) { - case LEAF_wlanHWMPRootMode: - switch (val) { - case IEEE80211_HWMP_ROOTMODE_NORMAL: - wif->hwmp_root_mode = wlanHWMPRootMode_normal; - break; - case IEEE80211_HWMP_ROOTMODE_PROACTIVE: - wif->hwmp_root_mode = wlanHWMPRootMode_proactive; - break; - case IEEE80211_HWMP_ROOTMODE_RANN: - wif->hwmp_root_mode = wlanHWMPRootMode_rann; - break; - case IEEE80211_HWMP_ROOTMODE_DISABLED: - default: - wif->hwmp_root_mode = wlanHWMPRootMode_disabled; - break; - } - break; - case LEAF_wlanHWMPMaxHops: - wif->hwmp_max_hops = val; - break; - } - - return (0); -} - -int -wlan_hwmp_config_set(struct wlan_iface *wif, int which) -{ - int op, val = 0; - size_t argsize = 0; - - switch (which) { - case LEAF_wlanHWMPRootMode: - op = IEEE80211_IOC_HWMP_ROOTMODE; - switch (wif->hwmp_root_mode) { - case wlanHWMPRootMode_disabled: - val = IEEE80211_HWMP_ROOTMODE_DISABLED; - break; - case wlanHWMPRootMode_normal: - val = IEEE80211_HWMP_ROOTMODE_NORMAL; - break; - case wlanHWMPRootMode_proactive: - val = IEEE80211_HWMP_ROOTMODE_PROACTIVE; - break; - case wlanHWMPRootMode_rann: - val = IEEE80211_HWMP_ROOTMODE_RANN; - break; - default: - return (-1); - } - break; - case LEAF_wlanHWMPMaxHops: - op = IEEE80211_IOC_HWMP_MAXHOPS; - val = wif->hwmp_max_hops; - break; - default: - return (-1); - } - - if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0) - return (-1); - - return (0); -} |