wlan_sys.c revision 310901
1210502Ssyrinx/*- 2210502Ssyrinx * Copyright (c) 2010 The FreeBSD Foundation 3210502Ssyrinx * All rights reserved. 4310901Sngie 5210502Ssyrinx * This software was developed by Shteryana Sotirova Shopova under 6210502Ssyrinx * sponsorship from the FreeBSD Foundation. 7210502Ssyrinx * 8210502Ssyrinx * Redistribution and use in source and binary forms, with or without 9210502Ssyrinx * modification, are permitted provided that the following conditions 10210502Ssyrinx * are met: 11210502Ssyrinx * 1. Redistributions of source code must retain the above copyright 12210502Ssyrinx * notice, this list of conditions and the following disclaimer. 13210502Ssyrinx * 2. Redistributions in binary form must reproduce the above copyright 14210502Ssyrinx * notice, this list of conditions and the following disclaimer in the 15210502Ssyrinx * documentation and/or other materials provided with the distribution. 16210502Ssyrinx * 17210502Ssyrinx * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18210502Ssyrinx * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19210502Ssyrinx * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20210502Ssyrinx * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21210502Ssyrinx * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22210502Ssyrinx * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23210502Ssyrinx * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24210502Ssyrinx * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25210502Ssyrinx * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26210502Ssyrinx * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27210502Ssyrinx * SUCH DAMAGE. 28210502Ssyrinx * 29210502Ssyrinx * $FreeBSD: stable/11/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_sys.c 310901 2016-12-31 10:32:49Z ngie $ 30210502Ssyrinx */ 31210502Ssyrinx 32210502Ssyrinx#include <sys/ioctl.h> 33210502Ssyrinx#include <sys/param.h> 34210502Ssyrinx#include <sys/module.h> 35210502Ssyrinx#include <sys/linker.h> 36210502Ssyrinx#include <sys/socket.h> 37210502Ssyrinx#include <sys/sysctl.h> 38210502Ssyrinx 39210502Ssyrinx#include <net/if.h> 40210502Ssyrinx#include <net/if_dl.h> 41210502Ssyrinx#include <net/if_media.h> 42210502Ssyrinx#include <net/if_mib.h> 43210502Ssyrinx#include <net/if_types.h> 44210502Ssyrinx#include <net80211/ieee80211.h> 45210502Ssyrinx#include <net80211/ieee80211_ioctl.h> 46210502Ssyrinx#include <net80211/ieee80211_regdomain.h> 47210502Ssyrinx 48210502Ssyrinx#include <errno.h> 49210502Ssyrinx#include <ifaddrs.h> 50210502Ssyrinx#include <stdarg.h> 51210502Ssyrinx#include <stdlib.h> 52210502Ssyrinx#include <stdio.h> 53210502Ssyrinx#include <string.h> 54210502Ssyrinx#include <syslog.h> 55210502Ssyrinx 56210502Ssyrinx#include <bsnmp/snmpmod.h> 57210502Ssyrinx#include <bsnmp/snmp_mibII.h> 58210502Ssyrinx 59210502Ssyrinx#include "wlan_tree.h" 60210502Ssyrinx#include "wlan_snmp.h" 61210502Ssyrinx 62210502Ssyrinxstatic int sock = -1; 63210502Ssyrinx 64210502Ssyrinxstatic int wlan_ioctl(char *, uint16_t, int *, void *, size_t *, int); 65210502Ssyrinxstatic int wlan_kmod_load(const char *); 66210502Ssyrinxstatic uint32_t wlan_drivercaps_to_snmp(uint32_t); 67210502Ssyrinxstatic uint32_t wlan_cryptocaps_to_snmp(uint32_t); 68210502Ssyrinxstatic uint32_t wlan_htcaps_to_snmp(uint32_t); 69210502Ssyrinxstatic uint32_t wlan_peerstate_to_snmp(uint32_t); 70210502Ssyrinxstatic uint32_t wlan_peercaps_to_snmp(uint32_t ); 71210502Ssyrinxstatic uint32_t wlan_channel_flags_to_snmp_phy(uint32_t); 72210502Ssyrinxstatic uint32_t wlan_regdomain_to_snmp(int); 73210502Ssyrinxstatic uint32_t wlan_snmp_to_scan_flags(int); 74210502Ssyrinxstatic int wlan_config_snmp2ioctl(int); 75210502Ssyrinxstatic int wlan_snmp_to_regdomain(enum WlanRegDomainCode); 76210502Ssyrinxstatic int wlan_config_get_country(struct wlan_iface *); 77210502Ssyrinxstatic int wlan_config_set_country(struct wlan_iface *, char *, int); 78210502Ssyrinxstatic int wlan_config_get_dchannel(struct wlan_iface *wif); 79210502Ssyrinxstatic int wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t); 80210502Ssyrinxstatic int wlan_config_get_bssid(struct wlan_iface *); 81210502Ssyrinxstatic int wlan_config_set_bssid(struct wlan_iface *, uint8_t *); 82210502Ssyrinxstatic void wlan_config_set_snmp_intval(struct wlan_iface *, int, int); 83210502Ssyrinxstatic int wlan_config_snmp2value(int, int, int *); 84210502Ssyrinxstatic int wlan_config_check(struct wlan_iface *, int); 85210502Ssyrinxstatic int wlan_config_get_intval(struct wlan_iface *, int); 86210502Ssyrinxstatic int wlan_config_set_intval(struct wlan_iface *, int, int); 87210502Ssyrinxstatic int wlan_add_new_scan_result(struct wlan_iface *, 88210502Ssyrinx const struct ieee80211req_scan_result *, uint8_t *); 89210502Ssyrinxstatic int wlan_add_mac_macinfo(struct wlan_iface *, 90210502Ssyrinx const struct ieee80211req_maclist *); 91210502Ssyrinxstatic struct wlan_peer *wlan_add_peerinfo(const struct ieee80211req_sta_info *); 92210502Ssyrinx 93210502Ssyrinxint 94210502Ssyrinxwlan_ioctl_init(void) 95210502Ssyrinx{ 96210502Ssyrinx if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 97210502Ssyrinx syslog(LOG_ERR, "cannot open socket : %s", strerror(errno)); 98210502Ssyrinx return (-1); 99210502Ssyrinx } 100210502Ssyrinx 101210502Ssyrinx return (0); 102210502Ssyrinx} 103210502Ssyrinx/* 104210502Ssyrinx * Load the needed modules in kernel if not already there. 105210502Ssyrinx */ 106210502Ssyrinxenum wlan_kmodules { 107210502Ssyrinx WLAN_KMOD = 0, 108210502Ssyrinx WLAN_KMOD_ACL, 109210502Ssyrinx WLAN_KMOD_WEP, 110210502Ssyrinx WLAN_KMODS_MAX 111210502Ssyrinx}; 112210502Ssyrinx 113210502Ssyrinxstatic const char *wmod_names[] = { 114210502Ssyrinx "wlan", 115210502Ssyrinx "wlan_wlan_acl", 116210502Ssyrinx "wlan_wep", 117210502Ssyrinx NULL 118210502Ssyrinx}; 119210502Ssyrinx 120210502Ssyrinxstatic int 121210502Ssyrinxwlan_kmod_load(const char *modname) 122210502Ssyrinx{ 123210502Ssyrinx int fileid, modid; 124210502Ssyrinx struct module_stat mstat; 125210502Ssyrinx 126210502Ssyrinx mstat.version = sizeof(struct module_stat); 127210502Ssyrinx for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { 128210502Ssyrinx for (modid = kldfirstmod(fileid); modid > 0; 129210502Ssyrinx modid = modfnext(modid)) { 130210502Ssyrinx if (modstat(modid, &mstat) < 0) 131210502Ssyrinx continue; 132210502Ssyrinx if (strcmp(modname, mstat.name) == 0) 133210502Ssyrinx return (0); 134210502Ssyrinx } 135210502Ssyrinx } 136210502Ssyrinx 137210502Ssyrinx /* Not present - load it. */ 138210502Ssyrinx if (kldload(modname) < 0) { 139210502Ssyrinx syslog(LOG_ERR, "failed to load %s kernel module - %s", modname, 140210502Ssyrinx strerror(errno)); 141210502Ssyrinx return (-1); 142210502Ssyrinx } 143210502Ssyrinx 144210502Ssyrinx return (1); 145210502Ssyrinx} 146210502Ssyrinx 147210502Ssyrinxint 148210502Ssyrinxwlan_kmodules_load(void) 149210502Ssyrinx{ 150210502Ssyrinx if (wlan_kmod_load(wmod_names[WLAN_KMOD]) < 0) 151210502Ssyrinx return (-1); 152210502Ssyrinx 153210502Ssyrinx if (wlan_kmod_load(wmod_names[WLAN_KMOD_ACL]) > 0) 154210502Ssyrinx syslog(LOG_NOTICE, "SNMP wlan loaded %s module", 155210502Ssyrinx wmod_names[WLAN_KMOD_ACL]); 156210502Ssyrinx 157210502Ssyrinx if (wlan_kmod_load(wmod_names[WLAN_KMOD_WEP]) > 0) 158210502Ssyrinx syslog(LOG_NOTICE, "SNMP wlan loaded %s module", 159210502Ssyrinx wmod_names[WLAN_KMOD_WEP]); 160210502Ssyrinx 161310901Sngie return (0); 162210502Ssyrinx} 163210502Ssyrinx 164210502Ssyrinx/* XXX: FIXME */ 165210502Ssyrinxstatic int 166210502Ssyrinxwlan_ioctl(char *wif_name, uint16_t req_type, int *val, void *arg, 167210502Ssyrinx size_t *argsize, int set) 168210502Ssyrinx{ 169210502Ssyrinx struct ieee80211req ireq; 170210502Ssyrinx 171210502Ssyrinx memset(&ireq, 0, sizeof(struct ieee80211req)); 172210502Ssyrinx strlcpy(ireq.i_name, wif_name, IFNAMSIZ); 173210502Ssyrinx 174210502Ssyrinx ireq.i_type = req_type; 175210502Ssyrinx ireq.i_val = *val; 176210502Ssyrinx ireq.i_len = *argsize; 177210502Ssyrinx ireq.i_data = arg; 178210502Ssyrinx 179210502Ssyrinx if (ioctl(sock, set ? SIOCS80211 : SIOCG80211, &ireq) < 0) { 180210502Ssyrinx syslog(LOG_ERR, "iface %s - %s param: ioctl(%d) " 181210502Ssyrinx "failed: %s", wif_name, set ? "set" : "get", 182210502Ssyrinx req_type, strerror(errno)); 183210502Ssyrinx return (-1); 184210502Ssyrinx } 185210502Ssyrinx 186210502Ssyrinx *argsize = ireq.i_len; 187210502Ssyrinx *val = ireq.i_val; 188210502Ssyrinx 189210502Ssyrinx return (0); 190210502Ssyrinx} 191210502Ssyrinx 192210502Ssyrinxint 193210502Ssyrinxwlan_check_media(char *ifname) 194210502Ssyrinx{ 195210502Ssyrinx struct ifmediareq ifmr; 196210502Ssyrinx 197210502Ssyrinx memset(&ifmr, 0, sizeof(struct ifmediareq)); 198210502Ssyrinx strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); 199210502Ssyrinx 200210502Ssyrinx if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0 || ifmr.ifm_count == 0) 201210502Ssyrinx return (0); /* Interface doesn't support SIOCGIFMEDIA. */ 202210502Ssyrinx 203210502Ssyrinx if ((ifmr.ifm_status & IFM_AVALID) == 0) 204210502Ssyrinx return (0); 205210502Ssyrinx 206210502Ssyrinx return (IFM_TYPE(ifmr.ifm_active)); 207210502Ssyrinx} 208210502Ssyrinx 209210502Ssyrinxint 210210502Ssyrinxwlan_get_opmode(struct wlan_iface *wif) 211210502Ssyrinx{ 212210502Ssyrinx struct ifmediareq ifmr; 213210502Ssyrinx 214210502Ssyrinx memset(&ifmr, 0, sizeof(struct ifmediareq)); 215210502Ssyrinx strlcpy(ifmr.ifm_name, wif->wname, sizeof(ifmr.ifm_name)); 216210502Ssyrinx 217210502Ssyrinx if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0) { 218210502Ssyrinx if (errno == ENXIO) 219210502Ssyrinx return (-1); 220210502Ssyrinx wif->mode = WlanIfaceOperatingModeType_station; 221210502Ssyrinx return (0); 222210502Ssyrinx } 223210502Ssyrinx 224210502Ssyrinx if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) { 225210502Ssyrinx if (ifmr.ifm_current & IFM_FLAG0) 226210502Ssyrinx wif->mode = WlanIfaceOperatingModeType_adhocDemo; 227210502Ssyrinx else 228210502Ssyrinx wif->mode = WlanIfaceOperatingModeType_ibss; 229210502Ssyrinx } else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 230210502Ssyrinx wif->mode = WlanIfaceOperatingModeType_hostAp; 231210502Ssyrinx else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 232210502Ssyrinx wif->mode = WlanIfaceOperatingModeType_monitor; 233210502Ssyrinx else if (ifmr.ifm_current & IFM_IEEE80211_MBSS) 234210502Ssyrinx wif->mode = WlanIfaceOperatingModeType_meshPoint; 235210502Ssyrinx else if (ifmr.ifm_current & IFM_IEEE80211_WDS) 236210502Ssyrinx wif->mode = WlanIfaceOperatingModeType_wds; 237210502Ssyrinx 238210502Ssyrinx return (0); 239210502Ssyrinx} 240210502Ssyrinx 241210502Ssyrinxint 242210502Ssyrinxwlan_config_state(struct wlan_iface *wif, uint8_t set) 243210502Ssyrinx{ 244210502Ssyrinx int flags; 245210502Ssyrinx struct ifreq ifr; 246210502Ssyrinx 247210502Ssyrinx memset(&ifr, 0, sizeof(ifr)); 248210502Ssyrinx strcpy(ifr.ifr_name, wif->wname); 249210502Ssyrinx 250210502Ssyrinx if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { 251210502Ssyrinx syslog(LOG_ERR, "set %s status: ioctl(SIOCGIFFLAGS) " 252210502Ssyrinx "failed: %s", wif->wname, strerror(errno)); 253210502Ssyrinx return (-1); 254210502Ssyrinx } 255210502Ssyrinx 256210502Ssyrinx if (set == 0) { 257210502Ssyrinx if ((ifr.ifr_flags & IFF_UP) != 0) 258210502Ssyrinx wif->state = wlanIfaceState_up; 259210502Ssyrinx else 260210502Ssyrinx wif->state = wlanIfaceState_down; 261210502Ssyrinx return (0); 262210502Ssyrinx } 263210502Ssyrinx 264210502Ssyrinx flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); 265210502Ssyrinx 266210502Ssyrinx if (wif->state == wlanIfaceState_up) 267210502Ssyrinx flags |= IFF_UP; 268210502Ssyrinx else 269210502Ssyrinx flags &= ~IFF_UP; 270210502Ssyrinx 271210502Ssyrinx ifr.ifr_flags = flags & 0xffff; 272210502Ssyrinx ifr.ifr_flagshigh = flags >> 16; 273210502Ssyrinx if (ioctl(sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { 274210502Ssyrinx syslog(LOG_ERR, "set %s %s: ioctl(SIOCSIFFLAGS) failed: %s", 275210502Ssyrinx wif->wname, wif->state == wlanIfaceState_up?"up":"down", 276210502Ssyrinx strerror(errno)); 277210502Ssyrinx return (-1); 278210502Ssyrinx } 279210502Ssyrinx 280210502Ssyrinx return (0); 281210502Ssyrinx} 282210502Ssyrinx 283210502Ssyrinxint 284210502Ssyrinxwlan_get_local_addr(struct wlan_iface *wif) 285210502Ssyrinx{ 286210502Ssyrinx int len; 287210502Ssyrinx char ifname[IFNAMSIZ]; 288210502Ssyrinx struct ifaddrs *ifap, *ifa; 289210502Ssyrinx struct sockaddr_dl sdl; 290210502Ssyrinx 291210502Ssyrinx if (getifaddrs(&ifap) != 0) { 292210502Ssyrinx syslog(LOG_ERR, "wlan get mac: getifaddrs() failed - %s", 293210502Ssyrinx strerror(errno)); 294210502Ssyrinx return (-1); 295210502Ssyrinx } 296210502Ssyrinx 297210502Ssyrinx for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 298210502Ssyrinx if (ifa->ifa_addr->sa_family != AF_LINK) 299210502Ssyrinx continue; 300210502Ssyrinx memcpy(&sdl, ifa->ifa_addr, sizeof(struct sockaddr_dl)); 301210502Ssyrinx if (sdl.sdl_alen > IEEE80211_ADDR_LEN) 302210502Ssyrinx continue; 303210502Ssyrinx if ((len = sdl.sdl_nlen) >= IFNAMSIZ) 304210502Ssyrinx len = IFNAMSIZ - 1; 305210502Ssyrinx memcpy(ifname, sdl.sdl_data, len); 306210502Ssyrinx ifname[len] = '\0'; 307210502Ssyrinx if (strcmp(wif->wname, ifname) == 0) 308210502Ssyrinx break; 309210502Ssyrinx } 310210502Ssyrinx 311210502Ssyrinx freeifaddrs(ifap); 312210502Ssyrinx return (0); 313210502Ssyrinx} 314210502Ssyrinx 315210502Ssyrinxint 316210502Ssyrinxwlan_get_parent(struct wlan_iface *wif __unused) 317210502Ssyrinx{ 318210502Ssyrinx /* XXX: There's no way to fetch this from the kernel. */ 319210502Ssyrinx return (0); 320210502Ssyrinx} 321210502Ssyrinx 322210502Ssyrinx/* XXX */ 323210502Ssyrinx#define IEEE80211_C_STA 0x00000001 /* CAPABILITY: STA available */ 324210502Ssyrinx#define IEEE80211_C_8023ENCAP 0x00000002 /* CAPABILITY: 802.3 encap */ 325210502Ssyrinx#define IEEE80211_C_FF 0x00000040 /* CAPABILITY: ATH FF avail */ 326210502Ssyrinx#define IEEE80211_C_TURBOP 0x00000080 /* CAPABILITY: ATH Turbo avail*/ 327210502Ssyrinx#define IEEE80211_C_IBSS 0x00000100 /* CAPABILITY: IBSS available */ 328210502Ssyrinx#define IEEE80211_C_PMGT 0x00000200 /* CAPABILITY: Power mgmt */ 329210502Ssyrinx#define IEEE80211_C_HOSTAP 0x00000400 /* CAPABILITY: HOSTAP avail */ 330210502Ssyrinx#define IEEE80211_C_AHDEMO 0x00000800 /* CAPABILITY: Old Adhoc Demo */ 331210502Ssyrinx#define IEEE80211_C_SWRETRY 0x00001000 /* CAPABILITY: sw tx retry */ 332210502Ssyrinx#define IEEE80211_C_TXPMGT 0x00002000 /* CAPABILITY: tx power mgmt */ 333210502Ssyrinx#define IEEE80211_C_SHSLOT 0x00004000 /* CAPABILITY: short slottime */ 334210502Ssyrinx#define IEEE80211_C_SHPREAMBLE 0x00008000 /* CAPABILITY: short preamble */ 335210502Ssyrinx#define IEEE80211_C_MONITOR 0x00010000 /* CAPABILITY: monitor mode */ 336210502Ssyrinx#define IEEE80211_C_DFS 0x00020000 /* CAPABILITY: DFS/radar avail*/ 337210502Ssyrinx#define IEEE80211_C_MBSS 0x00040000 /* CAPABILITY: MBSS available */ 338210502Ssyrinx/* 0x7c0000 available */ 339210502Ssyrinx#define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */ 340210502Ssyrinx#define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */ 341210502Ssyrinx#define IEEE80211_C_WPA 0x01800000 /* CAPABILITY: WPA1+WPA2 avail*/ 342210502Ssyrinx#define IEEE80211_C_BURST 0x02000000 /* CAPABILITY: frame bursting */ 343210502Ssyrinx#define IEEE80211_C_WME 0x04000000 /* CAPABILITY: WME avail */ 344210502Ssyrinx#define IEEE80211_C_WDS 0x08000000 /* CAPABILITY: 4-addr support */ 345210502Ssyrinx/* 0x10000000 reserved */ 346210502Ssyrinx#define IEEE80211_C_BGSCAN 0x20000000 /* CAPABILITY: bg scanning */ 347210502Ssyrinx#define IEEE80211_C_TXFRAG 0x40000000 /* CAPABILITY: tx fragments */ 348210502Ssyrinx#define IEEE80211_C_TDMA 0x80000000 /* CAPABILITY: TDMA avail */ 349210502Ssyrinx 350210502Ssyrinxstatic uint32_t 351210502Ssyrinxwlan_drivercaps_to_snmp(uint32_t dcaps) 352210502Ssyrinx{ 353210502Ssyrinx uint32_t scaps = 0; 354210502Ssyrinx 355210502Ssyrinx if ((dcaps & IEEE80211_C_STA) != 0) 356210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_station); 357210502Ssyrinx if ((dcaps & IEEE80211_C_8023ENCAP) != 0) 358210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_ieee8023encap); 359210502Ssyrinx if ((dcaps & IEEE80211_C_FF) != 0) 360210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_athFastFrames); 361210502Ssyrinx if ((dcaps & IEEE80211_C_TURBOP) != 0) 362210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_athTurbo); 363210502Ssyrinx if ((dcaps & IEEE80211_C_IBSS) != 0) 364210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_ibss); 365210502Ssyrinx if ((dcaps & IEEE80211_C_PMGT) != 0) 366210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_pmgt); 367210502Ssyrinx if ((dcaps & IEEE80211_C_HOSTAP) != 0) 368210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_hostAp); 369210502Ssyrinx if ((dcaps & IEEE80211_C_AHDEMO) != 0) 370210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_ahDemo); 371210502Ssyrinx if ((dcaps & IEEE80211_C_SWRETRY) != 0) 372210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_swRetry); 373210502Ssyrinx if ((dcaps & IEEE80211_C_TXPMGT) != 0) 374210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_txPmgt); 375210502Ssyrinx if ((dcaps & IEEE80211_C_SHSLOT) != 0) 376210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_shortSlot); 377210502Ssyrinx if ((dcaps & IEEE80211_C_SHPREAMBLE) != 0) 378210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_shortPreamble); 379210502Ssyrinx if ((dcaps & IEEE80211_C_MONITOR) != 0) 380210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_monitor); 381210502Ssyrinx if ((dcaps & IEEE80211_C_DFS) != 0) 382210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_dfs); 383210502Ssyrinx if ((dcaps & IEEE80211_C_MBSS) != 0) 384210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_mbss); 385210502Ssyrinx if ((dcaps & IEEE80211_C_WPA1) != 0) 386210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_wpa1); 387210502Ssyrinx if ((dcaps & IEEE80211_C_WPA2) != 0) 388210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_wpa2); 389210502Ssyrinx if ((dcaps & IEEE80211_C_BURST) != 0) 390210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_burst); 391210502Ssyrinx if ((dcaps & IEEE80211_C_WME) != 0) 392210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_wme); 393210502Ssyrinx if ((dcaps & IEEE80211_C_WDS) != 0) 394210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_wds); 395210502Ssyrinx if ((dcaps & IEEE80211_C_BGSCAN) != 0) 396210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_bgScan); 397210502Ssyrinx if ((dcaps & IEEE80211_C_TXFRAG) != 0) 398210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_txFrag); 399210502Ssyrinx if ((dcaps & IEEE80211_C_TDMA) != 0) 400210502Ssyrinx scaps |= (0x1 << WlanDriverCaps_tdma); 401210502Ssyrinx 402210502Ssyrinx return (scaps); 403210502Ssyrinx} 404210502Ssyrinx 405210502Ssyrinxstatic uint32_t 406210502Ssyrinxwlan_cryptocaps_to_snmp(uint32_t ccaps) 407210502Ssyrinx{ 408210502Ssyrinx uint32_t scaps = 0; 409210502Ssyrinx 410210502Ssyrinx#if NOT_YET 411210502Ssyrinx if ((ccaps & IEEE80211_CRYPTO_WEP) != 0) 412210502Ssyrinx scaps |= (0x1 << wlanCryptoCaps_wep); 413210502Ssyrinx if ((ccaps & IEEE80211_CRYPTO_TKIP) != 0) 414210502Ssyrinx scaps |= (0x1 << wlanCryptoCaps_tkip); 415210502Ssyrinx if ((ccaps & IEEE80211_CRYPTO_AES_OCB) != 0) 416210502Ssyrinx scaps |= (0x1 << wlanCryptoCaps_aes); 417210502Ssyrinx if ((ccaps & IEEE80211_CRYPTO_AES_CCM) != 0) 418210502Ssyrinx scaps |= (0x1 << wlanCryptoCaps_aesCcm); 419210502Ssyrinx if ((ccaps & IEEE80211_CRYPTO_TKIPMIC) != 0) 420210502Ssyrinx scaps |= (0x1 << wlanCryptoCaps_tkipMic); 421210502Ssyrinx if ((ccaps & IEEE80211_CRYPTO_CKIP) != 0) 422210502Ssyrinx scaps |= (0x1 << wlanCryptoCaps_ckip); 423210502Ssyrinx#else /* !NOT_YET */ 424210502Ssyrinx scaps = ccaps; 425210502Ssyrinx#endif 426210502Ssyrinx return (scaps); 427210502Ssyrinx} 428210502Ssyrinx 429210502Ssyrinx#define IEEE80211_HTC_AMPDU 0x00010000 /* CAPABILITY: A-MPDU tx */ 430210502Ssyrinx#define IEEE80211_HTC_AMSDU 0x00020000 /* CAPABILITY: A-MSDU tx */ 431210502Ssyrinx/* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */ 432210502Ssyrinx#define IEEE80211_HTC_HT 0x00040000 /* CAPABILITY: HT operation */ 433210502Ssyrinx#define IEEE80211_HTC_SMPS 0x00080000 /* CAPABILITY: MIMO power save*/ 434210502Ssyrinx#define IEEE80211_HTC_RIFS 0x00100000 /* CAPABILITY: RIFS support */ 435210502Ssyrinx 436210502Ssyrinxstatic uint32_t 437210502Ssyrinxwlan_htcaps_to_snmp(uint32_t hcaps) 438210502Ssyrinx{ 439210502Ssyrinx uint32_t scaps = 0; 440210502Ssyrinx 441210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_LDPC) != 0) 442210502Ssyrinx scaps |= (0x1 << WlanHTCaps_ldpc); 443210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_CHWIDTH40) != 0) 444210502Ssyrinx scaps |= (0x1 << WlanHTCaps_chwidth40); 445210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_GREENFIELD) != 0) 446210502Ssyrinx scaps |= (0x1 << WlanHTCaps_greenField); 447210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_SHORTGI20) != 0) 448210502Ssyrinx scaps |= (0x1 << WlanHTCaps_shortGi20); 449210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_SHORTGI40) != 0) 450210502Ssyrinx scaps |= (0x1 << WlanHTCaps_shortGi40); 451210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_TXSTBC) != 0) 452210502Ssyrinx scaps |= (0x1 << WlanHTCaps_txStbc); 453210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_DELBA) != 0) 454210502Ssyrinx scaps |= (0x1 << WlanHTCaps_delba); 455210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_MAXAMSDU_7935) != 0) 456210502Ssyrinx scaps |= (0x1 << WlanHTCaps_amsdu7935); 457210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_DSSSCCK40) != 0) 458210502Ssyrinx scaps |= (0x1 << WlanHTCaps_dssscck40); 459210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_PSMP) != 0) 460210502Ssyrinx scaps |= (0x1 << WlanHTCaps_psmp); 461210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_40INTOLERANT) != 0) 462210502Ssyrinx scaps |= (0x1 << WlanHTCaps_fortyMHzIntolerant); 463210502Ssyrinx if ((hcaps & IEEE80211_HTCAP_LSIGTXOPPROT) != 0) 464210502Ssyrinx scaps |= (0x1 << WlanHTCaps_lsigTxOpProt); 465210502Ssyrinx if ((hcaps & IEEE80211_HTC_AMPDU) != 0) 466210502Ssyrinx scaps |= (0x1 << WlanHTCaps_htcAmpdu); 467210502Ssyrinx if ((hcaps & IEEE80211_HTC_AMSDU) != 0) 468210502Ssyrinx scaps |= (0x1 << WlanHTCaps_htcAmsdu); 469210502Ssyrinx if ((hcaps & IEEE80211_HTC_HT) != 0) 470210502Ssyrinx scaps |= (0x1 << WlanHTCaps_htcHt); 471210502Ssyrinx if ((hcaps & IEEE80211_HTC_SMPS) != 0) 472210502Ssyrinx scaps |= (0x1 << WlanHTCaps_htcSmps); 473210502Ssyrinx if ((hcaps & IEEE80211_HTC_RIFS) != 0) 474210502Ssyrinx scaps |= (0x1 << WlanHTCaps_htcRifs); 475210502Ssyrinx 476210502Ssyrinx return (scaps); 477210502Ssyrinx} 478210502Ssyrinx 479210502Ssyrinx/* XXX: Not here? */ 480210502Ssyrinx#define WLAN_SET_TDMA_OPMODE(w) do { \ 481210502Ssyrinx if ((w)->mode == WlanIfaceOperatingModeType_adhocDemo && \ 482210502Ssyrinx ((w)->drivercaps & WlanDriverCaps_tdma) != 0) \ 483210502Ssyrinx (w)->mode = WlanIfaceOperatingModeType_tdma; \ 484210502Ssyrinx} while (0) 485210502Ssyrinxint 486210502Ssyrinxwlan_get_driver_caps(struct wlan_iface *wif) 487210502Ssyrinx{ 488210502Ssyrinx int val = 0; 489210502Ssyrinx size_t argsize; 490210502Ssyrinx struct ieee80211_devcaps_req dc; 491210502Ssyrinx 492210502Ssyrinx memset(&dc, 0, sizeof(struct ieee80211_devcaps_req)); 493210502Ssyrinx argsize = sizeof(struct ieee80211_devcaps_req); 494210502Ssyrinx 495210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_DEVCAPS, &val, &dc, 496210502Ssyrinx &argsize, 0) < 0) 497210502Ssyrinx return (-1); 498210502Ssyrinx 499210502Ssyrinx wif->drivercaps = wlan_drivercaps_to_snmp(dc.dc_drivercaps); 500210502Ssyrinx wif->cryptocaps = wlan_cryptocaps_to_snmp(dc.dc_cryptocaps); 501210502Ssyrinx wif->htcaps = wlan_htcaps_to_snmp(dc.dc_htcaps); 502210502Ssyrinx 503210502Ssyrinx WLAN_SET_TDMA_OPMODE(wif); 504210502Ssyrinx 505210502Ssyrinx argsize = dc.dc_chaninfo.ic_nchans * sizeof(struct ieee80211_channel); 506210502Ssyrinx wif->chanlist = (struct ieee80211_channel *)malloc(argsize); 507210502Ssyrinx if (wif->chanlist == NULL) 508210502Ssyrinx return (0); 509210502Ssyrinx 510210502Ssyrinx memcpy(wif->chanlist, dc.dc_chaninfo.ic_chans, argsize); 511210502Ssyrinx wif->nchannels = dc.dc_chaninfo.ic_nchans; 512210502Ssyrinx 513210502Ssyrinx return (0); 514210502Ssyrinx} 515210502Ssyrinx 516210502Ssyrinxuint8_t 517210502Ssyrinxwlan_channel_state_to_snmp(uint8_t cstate) 518210502Ssyrinx{ 519210502Ssyrinx uint8_t cs = 0; 520210502Ssyrinx 521210502Ssyrinx if ((cstate & IEEE80211_CHANSTATE_RADAR) != 0) 522210502Ssyrinx cs |= (0x1 << WlanIfaceChannelStateType_radar); 523210502Ssyrinx if ((cstate & IEEE80211_CHANSTATE_CACDONE) != 0) 524210502Ssyrinx cs |= (0x1 << WlanIfaceChannelStateType_cacDone); 525210502Ssyrinx if ((cstate & IEEE80211_CHANSTATE_CWINT) != 0) 526210502Ssyrinx cs |= (0x1 << WlanIfaceChannelStateType_interferenceDetected); 527210502Ssyrinx if ((cstate & IEEE80211_CHANSTATE_NORADAR) != 0) 528210502Ssyrinx cs |= (0x1 << WlanIfaceChannelStateType_radarClear); 529210502Ssyrinx 530210502Ssyrinx return (cs); 531210502Ssyrinx} 532210502Ssyrinx 533210502Ssyrinxuint32_t 534210502Ssyrinxwlan_channel_flags_to_snmp(uint32_t cflags) 535210502Ssyrinx{ 536210502Ssyrinx uint32_t cf = 0; 537210502Ssyrinx 538210502Ssyrinx if ((cflags & IEEE80211_CHAN_TURBO) != 0) 539210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_turbo); 540210502Ssyrinx if ((cflags & IEEE80211_CHAN_CCK) != 0) 541210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_cck); 542210502Ssyrinx if ((cflags & IEEE80211_CHAN_OFDM) != 0) 543210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_ofdm); 544210502Ssyrinx if ((cflags & IEEE80211_CHAN_2GHZ) != 0) 545210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum2Ghz); 546210502Ssyrinx if ((cflags & IEEE80211_CHAN_5GHZ) != 0) 547210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum5Ghz); 548210502Ssyrinx if ((cflags & IEEE80211_CHAN_PASSIVE) != 0) 549210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_passiveScan); 550210502Ssyrinx if ((cflags & IEEE80211_CHAN_DYN) != 0) 551210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_dynamicCckOfdm); 552210502Ssyrinx if ((cflags & IEEE80211_CHAN_GFSK) != 0) 553210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_gfsk); 554210502Ssyrinx if ((cflags & IEEE80211_CHAN_GSM) != 0) 555210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum900Mhz); 556210502Ssyrinx if ((cflags & IEEE80211_CHAN_STURBO) != 0) 557210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_dot11aStaticTurbo); 558210502Ssyrinx if ((cflags & IEEE80211_CHAN_HALF) != 0) 559210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_halfRate); 560210502Ssyrinx if ((cflags & IEEE80211_CHAN_QUARTER) != 0) 561210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_quarterRate); 562210502Ssyrinx if ((cflags & IEEE80211_CHAN_HT20) != 0) 563210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_ht20); 564210502Ssyrinx if ((cflags & IEEE80211_CHAN_HT40U) != 0) 565210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_ht40u); 566210502Ssyrinx if ((cflags & IEEE80211_CHAN_HT40D) != 0) 567210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_ht40d); 568210502Ssyrinx if ((cflags & IEEE80211_CHAN_DFS) != 0) 569210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_dfs); 570210502Ssyrinx if ((cflags & IEEE80211_CHAN_4MSXMIT) != 0) 571210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_xmit4ms); 572210502Ssyrinx if ((cflags & IEEE80211_CHAN_NOADHOC) != 0) 573210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_noAdhoc); 574210502Ssyrinx if ((cflags & IEEE80211_CHAN_NOHOSTAP) != 0) 575210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_noHostAp); 576210502Ssyrinx if ((cflags & IEEE80211_CHAN_11D) != 0) 577210502Ssyrinx cf |= (0x1 << WlanIfaceChannelFlagsType_dot11d); 578210502Ssyrinx 579210502Ssyrinx return (cf); 580210502Ssyrinx} 581210502Ssyrinx 582210502Ssyrinx/* XXX: */ 583210502Ssyrinx#define WLAN_SNMP_MAX_CHANS 256 584210502Ssyrinxint 585210502Ssyrinxwlan_get_channel_list(struct wlan_iface *wif) 586210502Ssyrinx{ 587210502Ssyrinx int val = 0; 588210502Ssyrinx uint32_t i, nchans; 589210502Ssyrinx size_t argsize; 590210502Ssyrinx struct ieee80211req_chaninfo *chaninfo; 591210502Ssyrinx struct ieee80211req_chanlist active; 592210502Ssyrinx const struct ieee80211_channel *c; 593210502Ssyrinx 594210502Ssyrinx argsize = sizeof(struct ieee80211req_chaninfo) + 595210502Ssyrinx sizeof(struct ieee80211_channel) * WLAN_SNMP_MAX_CHANS; 596210502Ssyrinx chaninfo = (struct ieee80211req_chaninfo *)malloc(argsize); 597210502Ssyrinx if (chaninfo == NULL) 598210502Ssyrinx return (-1); 599210502Ssyrinx 600210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANINFO, &val, chaninfo, 601210502Ssyrinx &argsize, 0) < 0) 602210502Ssyrinx return (-1); 603210502Ssyrinx 604210502Ssyrinx argsize = sizeof(active); 605210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANLIST, &val, &active, 606210502Ssyrinx &argsize, 0) < 0) 607210502Ssyrinx goto error; 608210502Ssyrinx 609210502Ssyrinx for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) { 610210502Ssyrinx c = &chaninfo->ic_chans[i]; 611210502Ssyrinx if (!isset(active.ic_channels, c->ic_ieee)) 612210502Ssyrinx continue; 613210502Ssyrinx nchans++; 614210502Ssyrinx } 615210502Ssyrinx wif->chanlist = (struct ieee80211_channel *)reallocf(wif->chanlist, 616210502Ssyrinx nchans * sizeof(*c)); 617210502Ssyrinx if (wif->chanlist == NULL) 618210502Ssyrinx goto error; 619210502Ssyrinx wif->nchannels = nchans; 620210502Ssyrinx for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) { 621210502Ssyrinx c = &chaninfo->ic_chans[i]; 622210502Ssyrinx if (!isset(active.ic_channels, c->ic_ieee)) 623210502Ssyrinx continue; 624210502Ssyrinx memcpy(wif->chanlist + nchans, c, sizeof (*c)); 625210502Ssyrinx nchans++; 626210502Ssyrinx } 627210502Ssyrinx 628210502Ssyrinx free(chaninfo); 629210502Ssyrinx return (0); 630210502Ssyrinxerror: 631210502Ssyrinx wif->nchannels = 0; 632210502Ssyrinx free(chaninfo); 633210502Ssyrinx return (-1); 634210502Ssyrinx} 635210502Ssyrinx 636210502Ssyrinxstatic enum WlanIfPhyMode 637210502Ssyrinxwlan_channel_flags_to_snmp_phy(uint32_t cflags) 638210502Ssyrinx{ 639210502Ssyrinx /* XXX: recheck */ 640210502Ssyrinx if ((cflags & IEEE80211_CHAN_A) != 0) 641210502Ssyrinx return (WlanIfPhyMode_dot11a); 642210502Ssyrinx if ((cflags & IEEE80211_CHAN_B) != 0) 643210502Ssyrinx return (WlanIfPhyMode_dot11b); 644210502Ssyrinx if ((cflags & IEEE80211_CHAN_G) != 0 || 645210502Ssyrinx (cflags & IEEE80211_CHAN_PUREG) != 0) 646210502Ssyrinx return (WlanIfPhyMode_dot11g); 647210502Ssyrinx if ((cflags & IEEE80211_CHAN_FHSS) != 0) 648210502Ssyrinx return (WlanIfPhyMode_fh); 649210502Ssyrinx if ((cflags & IEEE80211_CHAN_TURBO) != 0 && 650210502Ssyrinx (cflags & IEEE80211_CHAN_A) != 0) 651210502Ssyrinx return (WlanIfPhyMode_turboA); 652210502Ssyrinx if ((cflags & IEEE80211_CHAN_TURBO) != 0 && 653210502Ssyrinx (cflags & IEEE80211_CHAN_G) != 0) 654210502Ssyrinx return (WlanIfPhyMode_turboG); 655210502Ssyrinx if ((cflags & IEEE80211_CHAN_STURBO) != 0) 656210502Ssyrinx return (WlanIfPhyMode_sturboA); 657210502Ssyrinx if ((cflags & IEEE80211_CHAN_HALF) != 0) 658210502Ssyrinx return (WlanIfPhyMode_ofdmHalf); 659210502Ssyrinx if ((cflags & IEEE80211_CHAN_QUARTER) != 0) 660210502Ssyrinx return (WlanIfPhyMode_ofdmQuarter); 661210502Ssyrinx 662210502Ssyrinx return (WlanIfPhyMode_auto); 663210502Ssyrinx} 664210502Ssyrinx 665210502Ssyrinxint 666210502Ssyrinxwlan_get_roam_params(struct wlan_iface *wif) 667210502Ssyrinx{ 668210502Ssyrinx int val = 0; 669210502Ssyrinx size_t argsize; 670210502Ssyrinx 671210502Ssyrinx argsize = sizeof(struct ieee80211_roamparams_req); 672210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_ROAM, &val, 673210502Ssyrinx &wif->roamparams, &argsize, 0) < 0) 674210502Ssyrinx return (-1); 675210502Ssyrinx 676210502Ssyrinx return (0); 677210502Ssyrinx} 678210502Ssyrinx 679210502Ssyrinxint 680210502Ssyrinxwlan_get_tx_params(struct wlan_iface *wif) 681210502Ssyrinx{ 682210502Ssyrinx int val = 0; 683210502Ssyrinx size_t argsize; 684210502Ssyrinx 685210502Ssyrinx /* 686210502Ssyrinx * XXX: Reset IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA 687210502Ssyrinx * and IEEE80211_MODE_11NG modes. 688210502Ssyrinx */ 689210502Ssyrinx argsize = sizeof(struct ieee80211_txparams_req); 690210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val, 691210502Ssyrinx &wif->txparams, &argsize, 0) < 0) 692210502Ssyrinx return (-1); 693210502Ssyrinx 694210502Ssyrinx return (0); 695210502Ssyrinx} 696210502Ssyrinx 697210502Ssyrinxint 698210502Ssyrinxwlan_set_tx_params(struct wlan_iface *wif, int32_t pmode __unused) 699210502Ssyrinx{ 700210502Ssyrinx int val = 0; 701210502Ssyrinx size_t argsize; 702210502Ssyrinx 703210502Ssyrinx /* 704210502Ssyrinx * XXX: Set IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA 705210502Ssyrinx * and IEEE80211_MODE_11NG modes. 706210502Ssyrinx */ 707210502Ssyrinx argsize = sizeof(struct ieee80211_txparams_req); 708210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val, 709210502Ssyrinx &wif->txparams, &argsize, 1) < 0) 710210502Ssyrinx return (-1); 711210502Ssyrinx 712210502Ssyrinx return (0); 713210502Ssyrinx} 714210502Ssyrinx 715210502Ssyrinxint 716210502Ssyrinxwlan_clone_create(struct wlan_iface *wif) 717210502Ssyrinx{ 718210502Ssyrinx struct ifreq ifr; 719210502Ssyrinx struct ieee80211_clone_params wcp; 720210502Ssyrinx static const uint8_t zerobssid[IEEE80211_ADDR_LEN]; 721210502Ssyrinx 722210502Ssyrinx memset(&wcp, 0, sizeof(wcp)); 723210502Ssyrinx memset(&ifr, 0, sizeof(ifr)); 724210502Ssyrinx 725210502Ssyrinx /* Sanity checks. */ 726210502Ssyrinx if (wif == NULL || wif->pname[0] == '\0' || wif->mode > WLAN_IFMODE_MAX) 727210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 728210502Ssyrinx 729210502Ssyrinx if (wif->mode == WlanIfaceOperatingModeType_wds && 730210502Ssyrinx memcmp(wif->dbssid, zerobssid, IEEE80211_ADDR_LEN) == 0) 731210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 732210502Ssyrinx 733210502Ssyrinx strlcpy(wcp.icp_parent, wif->pname, IFNAMSIZ); 734210502Ssyrinx if ((wif->flags & WlanIfaceFlagsType_uniqueBssid) != 0) 735210502Ssyrinx wcp.icp_flags |= IEEE80211_CLONE_BSSID; 736210502Ssyrinx if ((wif->flags & WlanIfaceFlagsType_noBeacons) != 0) 737210502Ssyrinx wcp.icp_flags |= IEEE80211_CLONE_NOBEACONS; 738210502Ssyrinx if (wif->mode == WlanIfaceOperatingModeType_wds && 739210502Ssyrinx (wif->flags & WlanIfaceFlagsType_wdsLegacy) != 0) 740210502Ssyrinx wcp.icp_flags |= IEEE80211_CLONE_WDSLEGACY; 741210502Ssyrinx 742210502Ssyrinx switch (wif->mode) { 743210502Ssyrinx case WlanIfaceOperatingModeType_ibss: 744210502Ssyrinx wcp.icp_opmode = IEEE80211_M_IBSS; 745210502Ssyrinx break; 746210502Ssyrinx case WlanIfaceOperatingModeType_station: 747210502Ssyrinx wcp.icp_opmode = IEEE80211_M_STA; 748210502Ssyrinx break; 749210502Ssyrinx case WlanIfaceOperatingModeType_wds: 750210502Ssyrinx wcp.icp_opmode = IEEE80211_M_WDS; 751210502Ssyrinx break; 752210502Ssyrinx case WlanIfaceOperatingModeType_adhocDemo: 753210502Ssyrinx wcp.icp_opmode = IEEE80211_M_AHDEMO; 754210502Ssyrinx break; 755210502Ssyrinx case WlanIfaceOperatingModeType_hostAp: 756210502Ssyrinx wcp.icp_opmode = IEEE80211_M_HOSTAP; 757210502Ssyrinx break; 758210502Ssyrinx case WlanIfaceOperatingModeType_monitor: 759210502Ssyrinx wcp.icp_opmode = IEEE80211_M_MONITOR; 760210502Ssyrinx break; 761210502Ssyrinx case WlanIfaceOperatingModeType_meshPoint: 762210502Ssyrinx wcp.icp_opmode = IEEE80211_M_MBSS; 763210502Ssyrinx break; 764210502Ssyrinx case WlanIfaceOperatingModeType_tdma: 765210502Ssyrinx wcp.icp_opmode = IEEE80211_M_AHDEMO; 766210502Ssyrinx wcp.icp_flags |= IEEE80211_CLONE_TDMA; 767210502Ssyrinx break; 768210502Ssyrinx } 769210502Ssyrinx 770210502Ssyrinx memcpy(wcp.icp_bssid, wif->dbssid, IEEE80211_ADDR_LEN); 771210502Ssyrinx if (memcmp(wif->dlmac, zerobssid, IEEE80211_ADDR_LEN) != 0) { 772210502Ssyrinx memcpy(wcp.icp_macaddr, wif->dlmac, IEEE80211_ADDR_LEN); 773210502Ssyrinx wcp.icp_flags |= IEEE80211_CLONE_MACADDR; 774210502Ssyrinx } 775210502Ssyrinx 776210502Ssyrinx strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ); 777210502Ssyrinx ifr.ifr_data = (caddr_t) &wcp; 778210502Ssyrinx 779210502Ssyrinx if (ioctl(sock, SIOCIFCREATE2, (caddr_t) &ifr) < 0) { 780210502Ssyrinx syslog(LOG_ERR, "wlan clone create: ioctl(SIOCIFCREATE2) " 781210502Ssyrinx "failed: %s", strerror(errno)); 782210502Ssyrinx return (SNMP_ERR_GENERR); 783210502Ssyrinx } 784210502Ssyrinx 785210502Ssyrinx return (SNMP_ERR_NOERROR); 786210502Ssyrinx} 787210502Ssyrinx 788210502Ssyrinxint 789210502Ssyrinxwlan_clone_destroy(struct wlan_iface *wif) 790210502Ssyrinx{ 791210502Ssyrinx struct ifreq ifr; 792210502Ssyrinx 793210502Ssyrinx if (wif == NULL) 794210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 795210502Ssyrinx 796210502Ssyrinx memset(&ifr, 0, sizeof(ifr)); 797210502Ssyrinx strcpy(ifr.ifr_name, wif->wname); 798210502Ssyrinx 799210502Ssyrinx if (ioctl(sock, SIOCIFDESTROY, &ifr) < 0) { 800210502Ssyrinx syslog(LOG_ERR, "wlan clone destroy: ioctl(SIOCIFDESTROY) " 801210502Ssyrinx "failed: %s", strerror(errno)); 802210502Ssyrinx return (SNMP_ERR_GENERR); 803210502Ssyrinx } 804210502Ssyrinx 805210502Ssyrinx return (SNMP_ERR_NOERROR); 806210502Ssyrinx} 807210502Ssyrinx 808210502Ssyrinxstatic int 809210502Ssyrinxwlan_config_snmp2ioctl(int which) 810210502Ssyrinx{ 811210502Ssyrinx int op; 812210502Ssyrinx 813210502Ssyrinx switch (which) { 814210502Ssyrinx case LEAF_wlanIfacePacketBurst: 815210502Ssyrinx op = IEEE80211_IOC_BURST; 816210502Ssyrinx break; 817210502Ssyrinx case LEAF_wlanIfaceCountryCode: 818210502Ssyrinx op = IEEE80211_IOC_REGDOMAIN; 819210502Ssyrinx break; 820210502Ssyrinx case LEAF_wlanIfaceRegDomain: 821210502Ssyrinx op = IEEE80211_IOC_REGDOMAIN; 822210502Ssyrinx break; 823210502Ssyrinx case LEAF_wlanIfaceDesiredSsid: 824210502Ssyrinx op = IEEE80211_IOC_SSID; 825210502Ssyrinx break; 826210502Ssyrinx case LEAF_wlanIfaceDesiredChannel: 827210502Ssyrinx op = IEEE80211_IOC_CURCHAN; 828210502Ssyrinx break; 829210502Ssyrinx case LEAF_wlanIfaceDynamicFreqSelection: 830210502Ssyrinx op = IEEE80211_IOC_DFS; 831210502Ssyrinx break; 832210502Ssyrinx case LEAF_wlanIfaceFastFrames: 833210502Ssyrinx op = IEEE80211_IOC_FF; 834210502Ssyrinx break; 835210502Ssyrinx case LEAF_wlanIfaceDturbo: 836210502Ssyrinx op = IEEE80211_IOC_TURBOP; 837210502Ssyrinx break; 838210502Ssyrinx case LEAF_wlanIfaceTxPower: 839210502Ssyrinx op = IEEE80211_IOC_TXPOWER; 840210502Ssyrinx break; 841210502Ssyrinx case LEAF_wlanIfaceFragmentThreshold: 842210502Ssyrinx op = IEEE80211_IOC_FRAGTHRESHOLD; 843210502Ssyrinx break; 844210502Ssyrinx case LEAF_wlanIfaceRTSThreshold: 845210502Ssyrinx op = IEEE80211_IOC_RTSTHRESHOLD; 846210502Ssyrinx break; 847210502Ssyrinx case LEAF_wlanIfaceWlanPrivacySubscribe: 848210502Ssyrinx op = IEEE80211_IOC_WPS; 849210502Ssyrinx break; 850210502Ssyrinx case LEAF_wlanIfaceBgScan: 851210502Ssyrinx op = IEEE80211_IOC_BGSCAN; 852210502Ssyrinx break; 853210502Ssyrinx case LEAF_wlanIfaceBgScanIdle: 854210502Ssyrinx op = IEEE80211_IOC_BGSCAN_IDLE; 855210502Ssyrinx break; 856210502Ssyrinx case LEAF_wlanIfaceBgScanInterval: 857210502Ssyrinx op = IEEE80211_IOC_BGSCAN_INTERVAL; 858210502Ssyrinx break; 859210502Ssyrinx case LEAF_wlanIfaceBeaconMissedThreshold: 860210502Ssyrinx op = IEEE80211_IOC_BMISSTHRESHOLD; 861210502Ssyrinx break; 862210502Ssyrinx case LEAF_wlanIfaceDesiredBssid: 863210502Ssyrinx op = IEEE80211_IOC_BSSID; 864210502Ssyrinx break; 865210502Ssyrinx case LEAF_wlanIfaceRoamingMode: 866210502Ssyrinx op = IEEE80211_IOC_ROAMING; 867210502Ssyrinx break; 868210502Ssyrinx case LEAF_wlanIfaceDot11d: 869210502Ssyrinx op = IEEE80211_IOC_DOTD; 870210502Ssyrinx break; 871210502Ssyrinx case LEAF_wlanIfaceDot11h: 872210502Ssyrinx op = IEEE80211_IOC_DOTH; 873210502Ssyrinx break; 874210502Ssyrinx case LEAF_wlanIfaceDynamicWds: 875210502Ssyrinx op = IEEE80211_IOC_DWDS; 876210502Ssyrinx break; 877210502Ssyrinx case LEAF_wlanIfacePowerSave: 878210502Ssyrinx op = IEEE80211_IOC_POWERSAVE; 879210502Ssyrinx break; 880210502Ssyrinx case LEAF_wlanIfaceApBridge: 881210502Ssyrinx op = IEEE80211_IOC_APBRIDGE; 882210502Ssyrinx break; 883210502Ssyrinx case LEAF_wlanIfaceBeaconInterval: 884210502Ssyrinx op = IEEE80211_IOC_BEACON_INTERVAL; 885210502Ssyrinx break; 886210502Ssyrinx case LEAF_wlanIfaceDtimPeriod: 887210502Ssyrinx op = IEEE80211_IOC_DTIM_PERIOD; 888210502Ssyrinx break; 889210502Ssyrinx case LEAF_wlanIfaceHideSsid: 890210502Ssyrinx op = IEEE80211_IOC_HIDESSID; 891210502Ssyrinx break; 892210502Ssyrinx case LEAF_wlanIfaceInactivityProccess: 893210502Ssyrinx op = IEEE80211_IOC_INACTIVITY; 894210502Ssyrinx break; 895210502Ssyrinx case LEAF_wlanIfaceDot11gProtMode: 896210502Ssyrinx op = IEEE80211_IOC_PROTMODE; 897210502Ssyrinx break; 898210502Ssyrinx case LEAF_wlanIfaceDot11gPureMode: 899210502Ssyrinx op = IEEE80211_IOC_PUREG; 900210502Ssyrinx break; 901210502Ssyrinx case LEAF_wlanIfaceDot11nPureMode: 902210502Ssyrinx op = IEEE80211_IOC_PUREN; 903210502Ssyrinx break; 904210502Ssyrinx case LEAF_wlanIfaceDot11nAmpdu: 905210502Ssyrinx op = IEEE80211_IOC_AMPDU; 906210502Ssyrinx break; 907210502Ssyrinx case LEAF_wlanIfaceDot11nAmpduDensity: 908210502Ssyrinx op = IEEE80211_IOC_AMPDU_DENSITY; 909210502Ssyrinx break; 910210502Ssyrinx case LEAF_wlanIfaceDot11nAmpduLimit: 911210502Ssyrinx op = IEEE80211_IOC_AMPDU_LIMIT; 912210502Ssyrinx break; 913210502Ssyrinx case LEAF_wlanIfaceDot11nAmsdu: 914210502Ssyrinx op = IEEE80211_IOC_AMSDU; 915210502Ssyrinx break; 916210502Ssyrinx case LEAF_wlanIfaceDot11nAmsduLimit: 917210502Ssyrinx op = IEEE80211_IOC_AMSDU_LIMIT; 918210502Ssyrinx break; 919210502Ssyrinx case LEAF_wlanIfaceDot11nHighThroughput: 920210502Ssyrinx op = IEEE80211_IOC_HTCONF; 921210502Ssyrinx break; 922210502Ssyrinx case LEAF_wlanIfaceDot11nHTCompatible: 923210502Ssyrinx op = IEEE80211_IOC_HTCOMPAT; 924210502Ssyrinx break; 925210502Ssyrinx case LEAF_wlanIfaceDot11nHTProtMode: 926210502Ssyrinx op = IEEE80211_IOC_HTPROTMODE; 927210502Ssyrinx break; 928210502Ssyrinx case LEAF_wlanIfaceDot11nRIFS: 929210502Ssyrinx op = IEEE80211_IOC_RIFS; 930210502Ssyrinx break; 931210502Ssyrinx case LEAF_wlanIfaceDot11nShortGI: 932210502Ssyrinx op = IEEE80211_IOC_SHORTGI; 933210502Ssyrinx break; 934210502Ssyrinx case LEAF_wlanIfaceDot11nSMPSMode: 935210502Ssyrinx op = IEEE80211_IOC_SMPS; 936210502Ssyrinx break; 937210502Ssyrinx case LEAF_wlanIfaceTdmaSlot: 938210502Ssyrinx op = IEEE80211_IOC_TDMA_SLOT; 939210502Ssyrinx break; 940210502Ssyrinx case LEAF_wlanIfaceTdmaSlotCount: 941210502Ssyrinx op = IEEE80211_IOC_TDMA_SLOTCNT; 942210502Ssyrinx break; 943210502Ssyrinx case LEAF_wlanIfaceTdmaSlotLength: 944210502Ssyrinx op = IEEE80211_IOC_TDMA_SLOTLEN; 945210502Ssyrinx break; 946210502Ssyrinx case LEAF_wlanIfaceTdmaBeaconInterval: 947210502Ssyrinx op = IEEE80211_IOC_TDMA_BINTERVAL; 948210502Ssyrinx break; 949210502Ssyrinx default: 950210502Ssyrinx op = -1; 951210502Ssyrinx } 952210502Ssyrinx 953210502Ssyrinx return (op); 954210502Ssyrinx} 955210502Ssyrinx 956210502Ssyrinxstatic enum WlanRegDomainCode 957210502Ssyrinxwlan_regdomain_to_snmp(int which) 958210502Ssyrinx{ 959210502Ssyrinx enum WlanRegDomainCode reg_domain; 960210502Ssyrinx 961210502Ssyrinx switch (which) { 962210502Ssyrinx case SKU_FCC: 963210502Ssyrinx reg_domain = WlanRegDomainCode_fcc; 964210502Ssyrinx break; 965210502Ssyrinx case SKU_CA: 966210502Ssyrinx reg_domain = WlanRegDomainCode_ca; 967210502Ssyrinx break; 968210502Ssyrinx case SKU_ETSI: 969210502Ssyrinx reg_domain = WlanRegDomainCode_etsi; 970210502Ssyrinx break; 971210502Ssyrinx case SKU_ETSI2: 972210502Ssyrinx reg_domain = WlanRegDomainCode_etsi2; 973210502Ssyrinx break; 974210502Ssyrinx case SKU_ETSI3: 975210502Ssyrinx reg_domain = WlanRegDomainCode_etsi3; 976210502Ssyrinx break; 977210502Ssyrinx case SKU_FCC3: 978210502Ssyrinx reg_domain = WlanRegDomainCode_fcc3; 979210502Ssyrinx break; 980210502Ssyrinx case SKU_JAPAN: 981210502Ssyrinx reg_domain = WlanRegDomainCode_japan; 982210502Ssyrinx break; 983210502Ssyrinx case SKU_KOREA: 984210502Ssyrinx reg_domain = WlanRegDomainCode_korea; 985210502Ssyrinx break; 986210502Ssyrinx case SKU_APAC: 987210502Ssyrinx reg_domain = WlanRegDomainCode_apac; 988210502Ssyrinx break; 989210502Ssyrinx case SKU_APAC2: 990210502Ssyrinx reg_domain = WlanRegDomainCode_apac2; 991210502Ssyrinx break; 992210502Ssyrinx case SKU_APAC3: 993210502Ssyrinx reg_domain = WlanRegDomainCode_apac3; 994210502Ssyrinx break; 995210502Ssyrinx case SKU_ROW: 996210502Ssyrinx reg_domain = WlanRegDomainCode_row; 997210502Ssyrinx break; 998210502Ssyrinx case SKU_NONE: 999210502Ssyrinx reg_domain = WlanRegDomainCode_none; 1000210502Ssyrinx break; 1001210502Ssyrinx case SKU_DEBUG: 1002210502Ssyrinx reg_domain = WlanRegDomainCode_debug; 1003210502Ssyrinx break; 1004210502Ssyrinx case SKU_SR9: 1005210502Ssyrinx reg_domain = WlanRegDomainCode_sr9; 1006210502Ssyrinx break; 1007210502Ssyrinx case SKU_XR9: 1008210502Ssyrinx reg_domain = WlanRegDomainCode_xr9; 1009210502Ssyrinx break; 1010210502Ssyrinx case SKU_GZ901: 1011210502Ssyrinx reg_domain = WlanRegDomainCode_gz901; 1012210502Ssyrinx break; 1013210502Ssyrinx case 0: 1014210502Ssyrinx reg_domain = WlanRegDomainCode_none; 1015210502Ssyrinx break; 1016210502Ssyrinx default: 1017210502Ssyrinx syslog(LOG_ERR, "unknown regdomain (0x%x) ", which); 1018210502Ssyrinx reg_domain = WlanRegDomainCode_none; 1019210502Ssyrinx break; 1020210502Ssyrinx } 1021210502Ssyrinx 1022210502Ssyrinx return (reg_domain); 1023210502Ssyrinx} 1024210502Ssyrinx 1025210502Ssyrinxstatic int 1026210502Ssyrinxwlan_snmp_to_regdomain(enum WlanRegDomainCode regdomain) 1027210502Ssyrinx{ 1028210502Ssyrinx int which; 1029210502Ssyrinx 1030210502Ssyrinx switch (regdomain) { 1031210502Ssyrinx case WlanRegDomainCode_fcc: 1032210502Ssyrinx which = SKU_FCC; 1033210502Ssyrinx break; 1034210502Ssyrinx case WlanRegDomainCode_ca: 1035210502Ssyrinx which = SKU_CA; 1036210502Ssyrinx break; 1037210502Ssyrinx case WlanRegDomainCode_etsi: 1038210502Ssyrinx which = SKU_ETSI; 1039210502Ssyrinx break; 1040210502Ssyrinx case WlanRegDomainCode_etsi2: 1041210502Ssyrinx which = SKU_ETSI2; 1042210502Ssyrinx break; 1043210502Ssyrinx case WlanRegDomainCode_etsi3: 1044210502Ssyrinx which = SKU_ETSI3; 1045210502Ssyrinx break; 1046210502Ssyrinx case WlanRegDomainCode_fcc3: 1047210502Ssyrinx which = SKU_FCC3; 1048210502Ssyrinx break; 1049210502Ssyrinx case WlanRegDomainCode_japan: 1050210502Ssyrinx which = SKU_JAPAN; 1051210502Ssyrinx break; 1052210502Ssyrinx case WlanRegDomainCode_korea: 1053210502Ssyrinx which = SKU_KOREA; 1054210502Ssyrinx break; 1055210502Ssyrinx case WlanRegDomainCode_apac: 1056210502Ssyrinx which = SKU_APAC; 1057210502Ssyrinx break; 1058210502Ssyrinx case WlanRegDomainCode_apac2: 1059210502Ssyrinx which = SKU_APAC2; 1060210502Ssyrinx break; 1061210502Ssyrinx case WlanRegDomainCode_apac3: 1062210502Ssyrinx which = SKU_APAC3; 1063210502Ssyrinx break; 1064210502Ssyrinx case WlanRegDomainCode_row: 1065210502Ssyrinx which = SKU_ROW; 1066210502Ssyrinx break; 1067210502Ssyrinx case WlanRegDomainCode_none: 1068210502Ssyrinx which = SKU_NONE; 1069210502Ssyrinx break; 1070210502Ssyrinx case WlanRegDomainCode_debug: 1071210502Ssyrinx which = SKU_DEBUG; 1072210502Ssyrinx break; 1073210502Ssyrinx case WlanRegDomainCode_sr9: 1074210502Ssyrinx which = SKU_SR9; 1075210502Ssyrinx break; 1076210502Ssyrinx case WlanRegDomainCode_xr9: 1077210502Ssyrinx which = SKU_XR9; 1078210502Ssyrinx break; 1079210502Ssyrinx case WlanRegDomainCode_gz901: 1080210502Ssyrinx which = SKU_GZ901; 1081210502Ssyrinx break; 1082210502Ssyrinx default: 1083210502Ssyrinx syslog(LOG_ERR, "unknown snmp regdomain (0x%x) ", regdomain); 1084210502Ssyrinx which = SKU_NONE; 1085210502Ssyrinx break; 1086210502Ssyrinx } 1087210502Ssyrinx 1088210502Ssyrinx return (which); 1089210502Ssyrinx} 1090210502Ssyrinx 1091210502Ssyrinxstatic int 1092210502Ssyrinxwlan_config_get_country(struct wlan_iface *wif) 1093210502Ssyrinx{ 1094210502Ssyrinx int val = 0; 1095210502Ssyrinx size_t argsize; 1096210502Ssyrinx struct ieee80211_regdomain regdomain; 1097210502Ssyrinx 1098210502Ssyrinx memset(®domain, 0, sizeof(regdomain)); 1099210502Ssyrinx argsize = sizeof(regdomain); 1100210502Ssyrinx 1101210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, ®domain, 1102210502Ssyrinx &argsize, 0) < 0) 1103210502Ssyrinx return (-1); 1104210502Ssyrinx 1105210502Ssyrinx wif->reg_domain = wlan_regdomain_to_snmp(regdomain.regdomain); 1106210502Ssyrinx wif->country_code[0] = regdomain.isocc[0]; 1107210502Ssyrinx wif->country_code[1] = regdomain.isocc[1]; 1108210502Ssyrinx wif->country_code[2] = regdomain.location; 1109210502Ssyrinx 1110210502Ssyrinx return (0); 1111210502Ssyrinx} 1112210502Ssyrinx 1113210502Ssyrinxstatic int 1114210502Ssyrinxwlan_config_set_country(struct wlan_iface *wif, char *ccode, int rdomain) 1115210502Ssyrinx{ 1116210502Ssyrinx int val = 0, txpowermax; 1117210502Ssyrinx uint32_t i; 1118210502Ssyrinx size_t argsize = 0; 1119210502Ssyrinx struct ieee80211_regdomain_req *regdomain; 1120210502Ssyrinx 1121210502Ssyrinx if (wlan_get_channel_list(wif) < 0) 1122210502Ssyrinx return (-1); 1123210502Ssyrinx 1124210502Ssyrinx if (wif->nchannels == 0) { 1125210502Ssyrinx syslog(LOG_ERR, "iface %s - set regdomain failed", wif->wname); 1126210502Ssyrinx return (-1); 1127210502Ssyrinx } 1128210502Ssyrinx 1129210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPOWMAX, &txpowermax, 0, 1130210502Ssyrinx &argsize, 0) < 0) 1131210502Ssyrinx return (-1); 1132210502Ssyrinx 1133210502Ssyrinx regdomain = malloc(IEEE80211_REGDOMAIN_SIZE(wif->nchannels)); 1134210502Ssyrinx if (regdomain == NULL) 1135210502Ssyrinx return (-1); 1136210502Ssyrinx memset(regdomain, 0, IEEE80211_REGDOMAIN_SIZE(wif->nchannels)); 1137210502Ssyrinx argsize = IEEE80211_REGDOMAIN_SIZE(wif->nchannels); 1138210502Ssyrinx 1139210502Ssyrinx /* XXX: recheck with how this is done by ifconfig(8) */ 1140210502Ssyrinx regdomain->rd.regdomain = wlan_snmp_to_regdomain(rdomain); 1141210502Ssyrinx regdomain->rd.isocc[0] = ccode[0]; 1142210502Ssyrinx regdomain->rd.isocc[1] = ccode[1]; 1143210502Ssyrinx regdomain->rd.location = ccode[2]; 1144210502Ssyrinx 1145210502Ssyrinx /* XXX: fill the channel list properly */ 1146210502Ssyrinx regdomain->chaninfo.ic_nchans = wif->nchannels; 1147210502Ssyrinx memcpy(regdomain->chaninfo.ic_chans, wif->chanlist, 1148210502Ssyrinx wif->nchannels * sizeof(struct ieee80211_channel)); 1149210502Ssyrinx for (i = 0; i < wif->nchannels; i++) 1150210502Ssyrinx regdomain->chaninfo.ic_chans[i].ic_maxregpower = txpowermax; 1151210502Ssyrinx 1152210502Ssyrinx wif->state = wlanIfaceState_down; 1153210502Ssyrinx if (wlan_config_state(wif, 1) < 0 || 1154210502Ssyrinx wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, regdomain, 1155210502Ssyrinx &argsize, 1) < 0) { 1156210502Ssyrinx free(regdomain); 1157210502Ssyrinx return (-1); 1158210502Ssyrinx } 1159210502Ssyrinx 1160210502Ssyrinx wif->state = wlanIfaceState_up; 1161210502Ssyrinx (void)wlan_config_state(wif, 1); 1162210502Ssyrinx wif->reg_domain = wlan_regdomain_to_snmp(regdomain->rd.regdomain); 1163210502Ssyrinx wif->country_code[0] = regdomain->rd.isocc[0]; 1164210502Ssyrinx wif->country_code[1] = regdomain->rd.isocc[1]; 1165210502Ssyrinx wif->country_code[2] = regdomain->rd.location; 1166210502Ssyrinx free(regdomain); 1167210502Ssyrinx 1168210502Ssyrinx return (0); 1169210502Ssyrinx} 1170210502Ssyrinx 1171210502Ssyrinxint 1172210502Ssyrinxwlan_config_get_dssid(struct wlan_iface *wif) 1173210502Ssyrinx{ 1174210502Ssyrinx int val = -1; 1175210502Ssyrinx size_t argsize = IEEE80211_NWID_LEN + 1; 1176210502Ssyrinx char ssid[IEEE80211_NWID_LEN + 1]; 1177210502Ssyrinx 1178210502Ssyrinx memset(ssid, 0, IEEE80211_NWID_LEN + 1); 1179210502Ssyrinx 1180210502Ssyrinx if (wlan_ioctl(wif->wname, 1181210502Ssyrinx (wif->mode == WlanIfaceOperatingModeType_meshPoint) ? 1182210502Ssyrinx IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid, 1183210502Ssyrinx &argsize, 0) < 0) 1184210502Ssyrinx return (-1); 1185210502Ssyrinx 1186210502Ssyrinx if (argsize > IEEE80211_NWID_LEN) 1187210502Ssyrinx argsize = IEEE80211_NWID_LEN; 1188210502Ssyrinx memcpy(wif->desired_ssid, ssid, argsize); 1189210502Ssyrinx wif->desired_ssid[argsize] = '\0'; 1190210502Ssyrinx 1191210502Ssyrinx return (0); 1192210502Ssyrinx} 1193210502Ssyrinx 1194210502Ssyrinxint 1195210502Ssyrinxwlan_config_set_dssid(struct wlan_iface *wif, char *ssid, int slen) 1196210502Ssyrinx{ 1197210502Ssyrinx int val = 0; 1198210502Ssyrinx size_t argsize = slen; 1199210502Ssyrinx 1200210502Ssyrinx if (wlan_ioctl(wif->wname, 1201210502Ssyrinx (wif->mode == WlanIfaceOperatingModeType_meshPoint) ? 1202210502Ssyrinx IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid, 1203210502Ssyrinx &argsize, 1) < 0) 1204210502Ssyrinx return (-1); 1205210502Ssyrinx 1206210502Ssyrinx if (argsize > IEEE80211_NWID_LEN) 1207210502Ssyrinx argsize = IEEE80211_NWID_LEN; 1208210502Ssyrinx memcpy(wif->desired_ssid, ssid, argsize); 1209210502Ssyrinx wif->desired_ssid[argsize] = '\0'; 1210210502Ssyrinx 1211210502Ssyrinx return (0); 1212210502Ssyrinx} 1213210502Ssyrinx 1214210502Ssyrinxstatic int 1215210502Ssyrinxwlan_config_get_dchannel(struct wlan_iface *wif) 1216210502Ssyrinx{ 1217210502Ssyrinx uint32_t i = 0; 1218210502Ssyrinx int val = 0; 1219210502Ssyrinx size_t argsize = sizeof(struct ieee80211_channel); 1220210502Ssyrinx struct ieee80211_channel chan; 1221210502Ssyrinx 1222210502Ssyrinx if (wlan_get_channel_list(wif) < 0) 1223210502Ssyrinx return (-1); 1224210502Ssyrinx 1225210502Ssyrinx memset(&chan, 0, sizeof(chan)); 1226210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan, 1227210502Ssyrinx &argsize, 0) < 0) 1228210502Ssyrinx return (-1); 1229210502Ssyrinx 1230210502Ssyrinx for (i = 0; i < wif->nchannels; i++) 1231210502Ssyrinx if (chan.ic_ieee == wif->chanlist[i].ic_ieee && 1232210502Ssyrinx chan.ic_flags == wif->chanlist[i].ic_flags) { 1233210502Ssyrinx wif->desired_channel = i + 1; 1234210502Ssyrinx break; 1235210502Ssyrinx } 1236210502Ssyrinx 1237210502Ssyrinx return (0); 1238210502Ssyrinx} 1239210502Ssyrinx 1240210502Ssyrinxstatic int 1241210502Ssyrinxwlan_config_set_dchannel(struct wlan_iface *wif, uint32_t dchannel) 1242210502Ssyrinx{ 1243210502Ssyrinx int val = 0; 1244210502Ssyrinx size_t argsize = sizeof(struct ieee80211_channel); 1245210502Ssyrinx struct ieee80211_channel chan; 1246210502Ssyrinx 1247210502Ssyrinx if (wlan_get_channel_list(wif) < 0) 1248210502Ssyrinx return (-1); 1249210502Ssyrinx 1250210502Ssyrinx if (dchannel > wif->nchannels) 1251210502Ssyrinx return (-1); 1252210502Ssyrinx 1253210502Ssyrinx memcpy(&chan, wif->chanlist + dchannel - 1, sizeof(chan)); 1254210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan, 1255210502Ssyrinx &argsize, 1) < 0) 1256210502Ssyrinx return (-1); 1257210502Ssyrinx 1258210502Ssyrinx wif->desired_channel = dchannel; 1259210502Ssyrinx 1260210502Ssyrinx return (0); 1261210502Ssyrinx} 1262210502Ssyrinx 1263210502Ssyrinxstatic int 1264210502Ssyrinxwlan_config_get_bssid(struct wlan_iface *wif) 1265210502Ssyrinx{ 1266210502Ssyrinx int val = 0; 1267210502Ssyrinx size_t argsize = IEEE80211_ADDR_LEN; 1268210502Ssyrinx char bssid[IEEE80211_ADDR_LEN]; 1269210502Ssyrinx 1270210502Ssyrinx memset(bssid, 0, IEEE80211_ADDR_LEN); 1271210502Ssyrinx 1272210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid, 1273210502Ssyrinx &argsize, 0) < 0 || argsize != IEEE80211_ADDR_LEN) 1274210502Ssyrinx return (-1); 1275210502Ssyrinx 1276210502Ssyrinx memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN); 1277210502Ssyrinx 1278210502Ssyrinx return (0); 1279210502Ssyrinx} 1280210502Ssyrinx 1281210502Ssyrinxstatic int 1282210502Ssyrinxwlan_config_set_bssid(struct wlan_iface *wif, uint8_t *bssid) 1283210502Ssyrinx{ 1284210502Ssyrinx int val = 0; 1285210502Ssyrinx size_t argsize = IEEE80211_ADDR_LEN; 1286210502Ssyrinx 1287210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid, 1288210502Ssyrinx &argsize, 1) < 0 || argsize != IEEE80211_ADDR_LEN) 1289210502Ssyrinx return (-1); 1290210502Ssyrinx 1291210502Ssyrinx memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN); 1292210502Ssyrinx 1293210502Ssyrinx return (0); 1294210502Ssyrinx} 1295210502Ssyrinx 1296210502Ssyrinx/* 1297210502Ssyrinx * Convert the value returned by the kernel to the appropriate SNMP 1298210502Ssyrinx * representation and set the corresponding interface member accordingly. 1299210502Ssyrinx */ 1300210502Ssyrinxstatic void 1301210502Ssyrinxwlan_config_set_snmp_intval(struct wlan_iface *wif, int op, int val) 1302210502Ssyrinx{ 1303210502Ssyrinx switch (op) { 1304210502Ssyrinx case IEEE80211_IOC_BURST: 1305210502Ssyrinx if (val == 0) 1306210502Ssyrinx wif->packet_burst = TruthValue_false; 1307210502Ssyrinx else 1308210502Ssyrinx wif->packet_burst = TruthValue_true; 1309210502Ssyrinx break; 1310210502Ssyrinx case IEEE80211_IOC_DFS: 1311210502Ssyrinx if (val == 0) 1312210502Ssyrinx wif->dyn_frequency = TruthValue_false; 1313210502Ssyrinx else 1314210502Ssyrinx wif->dyn_frequency = TruthValue_true; 1315210502Ssyrinx break; 1316210502Ssyrinx case IEEE80211_IOC_FF: 1317210502Ssyrinx if (val == 0) 1318210502Ssyrinx wif->fast_frames = TruthValue_false; 1319210502Ssyrinx else 1320210502Ssyrinx wif->fast_frames = TruthValue_true; 1321210502Ssyrinx break; 1322210502Ssyrinx case IEEE80211_IOC_TURBOP: 1323210502Ssyrinx if (val == 0) 1324210502Ssyrinx wif->dturbo = TruthValue_false; 1325210502Ssyrinx else 1326210502Ssyrinx wif->dturbo = TruthValue_true; 1327210502Ssyrinx break; 1328210502Ssyrinx case IEEE80211_IOC_TXPOWER: 1329210502Ssyrinx wif->tx_power = val / 2; 1330210502Ssyrinx break; 1331210502Ssyrinx case IEEE80211_IOC_FRAGTHRESHOLD: 1332210502Ssyrinx wif->frag_threshold = val; 1333210502Ssyrinx break; 1334210502Ssyrinx case IEEE80211_IOC_RTSTHRESHOLD: 1335210502Ssyrinx wif->rts_threshold = val; 1336210502Ssyrinx break; 1337210502Ssyrinx case IEEE80211_IOC_WPS: 1338210502Ssyrinx if (val == 0) 1339210502Ssyrinx wif->priv_subscribe = TruthValue_false; 1340210502Ssyrinx else 1341210502Ssyrinx wif->priv_subscribe = TruthValue_true; 1342210502Ssyrinx break; 1343210502Ssyrinx case IEEE80211_IOC_BGSCAN: 1344210502Ssyrinx if (val == 0) 1345210502Ssyrinx wif->bg_scan = TruthValue_false; 1346210502Ssyrinx else 1347210502Ssyrinx wif->bg_scan = TruthValue_true; 1348210502Ssyrinx break; 1349210502Ssyrinx case IEEE80211_IOC_BGSCAN_IDLE: 1350210502Ssyrinx wif->bg_scan_idle = val; 1351210502Ssyrinx break; 1352210502Ssyrinx case IEEE80211_IOC_BGSCAN_INTERVAL: 1353210502Ssyrinx wif->bg_scan_interval = val; 1354210502Ssyrinx break; 1355210502Ssyrinx case IEEE80211_IOC_BMISSTHRESHOLD: 1356210502Ssyrinx wif->beacons_missed = val; 1357210502Ssyrinx break; 1358210502Ssyrinx case IEEE80211_IOC_ROAMING: 1359210502Ssyrinx switch (val) { 1360210502Ssyrinx case IEEE80211_ROAMING_DEVICE: 1361210502Ssyrinx wif->roam_mode = wlanIfaceRoamingMode_device; 1362210502Ssyrinx break; 1363210502Ssyrinx case IEEE80211_ROAMING_MANUAL: 1364210502Ssyrinx wif->roam_mode = wlanIfaceRoamingMode_manual; 1365210502Ssyrinx break; 1366210502Ssyrinx case IEEE80211_ROAMING_AUTO: 1367210502Ssyrinx /* FALTHROUGH */ 1368210502Ssyrinx default: 1369210502Ssyrinx wif->roam_mode = wlanIfaceRoamingMode_auto; 1370210502Ssyrinx break; 1371210502Ssyrinx } 1372210502Ssyrinx break; 1373210502Ssyrinx case IEEE80211_IOC_DOTD: 1374210502Ssyrinx if (val == 0) 1375210502Ssyrinx wif->dot11d = TruthValue_false; 1376210502Ssyrinx else 1377210502Ssyrinx wif->dot11d = TruthValue_true; 1378210502Ssyrinx break; 1379210502Ssyrinx case IEEE80211_IOC_DOTH: 1380210502Ssyrinx if (val == 0) 1381210502Ssyrinx wif->dot11h = TruthValue_false; 1382210502Ssyrinx else 1383210502Ssyrinx wif->dot11h = TruthValue_true; 1384210502Ssyrinx break; 1385210502Ssyrinx case IEEE80211_IOC_DWDS: 1386210502Ssyrinx if (val == 0) 1387210502Ssyrinx wif->dynamic_wds = TruthValue_false; 1388210502Ssyrinx else 1389210502Ssyrinx wif->dynamic_wds = TruthValue_true; 1390210502Ssyrinx break; 1391210502Ssyrinx case IEEE80211_IOC_POWERSAVE: 1392210502Ssyrinx if (val == 0) 1393210502Ssyrinx wif->power_save = TruthValue_false; 1394210502Ssyrinx else 1395210502Ssyrinx wif->power_save = TruthValue_true; 1396210502Ssyrinx break; 1397210502Ssyrinx case IEEE80211_IOC_APBRIDGE: 1398210502Ssyrinx if (val == 0) 1399210502Ssyrinx wif->ap_bridge = TruthValue_false; 1400210502Ssyrinx else 1401210502Ssyrinx wif->ap_bridge = TruthValue_true; 1402210502Ssyrinx break; 1403210502Ssyrinx case IEEE80211_IOC_BEACON_INTERVAL: 1404210502Ssyrinx wif->beacon_interval = val; 1405210502Ssyrinx break; 1406210502Ssyrinx case IEEE80211_IOC_DTIM_PERIOD: 1407210502Ssyrinx wif->dtim_period = val; 1408210502Ssyrinx break; 1409210502Ssyrinx case IEEE80211_IOC_HIDESSID: 1410210502Ssyrinx if (val == 0) 1411210502Ssyrinx wif->hide_ssid = TruthValue_false; 1412210502Ssyrinx else 1413210502Ssyrinx wif->hide_ssid = TruthValue_true; 1414210502Ssyrinx break; 1415210502Ssyrinx case IEEE80211_IOC_INACTIVITY: 1416210502Ssyrinx if (val == 0) 1417210502Ssyrinx wif->inact_process = TruthValue_false; 1418210502Ssyrinx else 1419210502Ssyrinx wif->inact_process = TruthValue_true; 1420210502Ssyrinx break; 1421210502Ssyrinx case IEEE80211_IOC_PROTMODE: 1422210502Ssyrinx switch (val) { 1423210502Ssyrinx case IEEE80211_PROTMODE_CTS: 1424210502Ssyrinx wif->do11g_protect = wlanIfaceDot11gProtMode_cts; 1425210502Ssyrinx break; 1426210502Ssyrinx case IEEE80211_PROTMODE_RTSCTS: 1427210502Ssyrinx wif->do11g_protect = wlanIfaceDot11gProtMode_rtscts; 1428210502Ssyrinx break; 1429210502Ssyrinx case IEEE80211_PROTMODE_OFF: 1430210502Ssyrinx /* FALLTHROUGH */ 1431210502Ssyrinx default: 1432210502Ssyrinx wif->do11g_protect = wlanIfaceDot11gProtMode_off; 1433210502Ssyrinx break; 1434210502Ssyrinx } 1435210502Ssyrinx break; 1436210502Ssyrinx case IEEE80211_IOC_PUREG: 1437210502Ssyrinx if (val == 0) 1438210502Ssyrinx wif->dot11g_pure = TruthValue_false; 1439210502Ssyrinx else 1440210502Ssyrinx wif->dot11g_pure = TruthValue_true; 1441210502Ssyrinx break; 1442210502Ssyrinx case IEEE80211_IOC_PUREN: 1443210502Ssyrinx if (val == 0) 1444210502Ssyrinx wif->dot11n_pure = TruthValue_false; 1445210502Ssyrinx else 1446210502Ssyrinx wif->dot11n_pure = TruthValue_true; 1447210502Ssyrinx break; 1448210502Ssyrinx case IEEE80211_IOC_AMPDU: 1449210502Ssyrinx switch (val) { 1450210502Ssyrinx case 0: 1451210502Ssyrinx wif->ampdu = WlanIfaceDot11nPduType_disabled; 1452210502Ssyrinx break; 1453210502Ssyrinx case 1: 1454210502Ssyrinx wif->ampdu = WlanIfaceDot11nPduType_txOnly; 1455210502Ssyrinx break; 1456210502Ssyrinx case 2: 1457210502Ssyrinx wif->ampdu = WlanIfaceDot11nPduType_rxOnly; 1458210502Ssyrinx break; 1459210502Ssyrinx case 3: 1460210502Ssyrinx /* FALLTHROUGH */ 1461210502Ssyrinx default: 1462210502Ssyrinx wif->ampdu = WlanIfaceDot11nPduType_txAndRx; 1463210502Ssyrinx break; 1464210502Ssyrinx } 1465210502Ssyrinx break; 1466210502Ssyrinx case IEEE80211_IOC_AMPDU_DENSITY: 1467210502Ssyrinx switch (val) { 1468210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_025: 1469210502Ssyrinx wif->ampdu_density = 25; 1470210502Ssyrinx break; 1471210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_05: 1472210502Ssyrinx wif->ampdu_density = 50; 1473210502Ssyrinx break; 1474210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_1: 1475210502Ssyrinx wif->ampdu_density = 100; 1476210502Ssyrinx break; 1477210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_2: 1478210502Ssyrinx wif->ampdu_density = 200; 1479210502Ssyrinx break; 1480210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_4: 1481210502Ssyrinx wif->ampdu_density = 400; 1482210502Ssyrinx break; 1483210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_8: 1484210502Ssyrinx wif->ampdu_density = 800; 1485210502Ssyrinx break; 1486210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_16: 1487210502Ssyrinx wif->ampdu_density = 1600; 1488210502Ssyrinx break; 1489210502Ssyrinx case IEEE80211_HTCAP_MPDUDENSITY_NA: 1490210502Ssyrinx default: 1491210502Ssyrinx wif->ampdu_density = 0; 1492210502Ssyrinx break; 1493210502Ssyrinx } 1494210502Ssyrinx break; 1495210502Ssyrinx case IEEE80211_IOC_AMPDU_LIMIT: 1496210502Ssyrinx switch (val) { 1497210502Ssyrinx case IEEE80211_HTCAP_MAXRXAMPDU_8K: 1498210502Ssyrinx wif->ampdu_limit = 8192; 1499210502Ssyrinx break; 1500210502Ssyrinx case IEEE80211_HTCAP_MAXRXAMPDU_16K: 1501210502Ssyrinx wif->ampdu_limit = 16384; 1502210502Ssyrinx break; 1503210502Ssyrinx case IEEE80211_HTCAP_MAXRXAMPDU_32K: 1504210502Ssyrinx wif->ampdu_limit = 32768; 1505210502Ssyrinx break; 1506210502Ssyrinx case IEEE80211_HTCAP_MAXRXAMPDU_64K: 1507210502Ssyrinx default: 1508210502Ssyrinx wif->ampdu_limit = 65536; 1509210502Ssyrinx break; 1510210502Ssyrinx } 1511210502Ssyrinx break; 1512210502Ssyrinx case IEEE80211_IOC_AMSDU: 1513210502Ssyrinx switch (val) { 1514210502Ssyrinx case 0: 1515210502Ssyrinx wif->amsdu = WlanIfaceDot11nPduType_disabled; 1516210502Ssyrinx break; 1517210502Ssyrinx case 1: 1518210502Ssyrinx wif->amsdu = WlanIfaceDot11nPduType_txOnly; 1519210502Ssyrinx break; 1520210502Ssyrinx case 3: 1521210502Ssyrinx wif->amsdu = WlanIfaceDot11nPduType_txAndRx; 1522210502Ssyrinx break; 1523210502Ssyrinx case 2: 1524210502Ssyrinx default: 1525210502Ssyrinx /* FALLTHROUGH */ 1526210502Ssyrinx wif->amsdu = WlanIfaceDot11nPduType_rxOnly; 1527210502Ssyrinx break; 1528210502Ssyrinx } 1529210502Ssyrinx break; 1530210502Ssyrinx case IEEE80211_IOC_AMSDU_LIMIT: 1531210502Ssyrinx wif->amsdu_limit = val; 1532210502Ssyrinx break; 1533210502Ssyrinx case IEEE80211_IOC_HTCONF: 1534210502Ssyrinx if (val == 0) /* XXX */ 1535210502Ssyrinx wif->ht_enabled = TruthValue_false; 1536210502Ssyrinx else 1537210502Ssyrinx wif->ht_enabled = TruthValue_true; 1538210502Ssyrinx break; 1539210502Ssyrinx case IEEE80211_IOC_HTCOMPAT: 1540210502Ssyrinx if (val == 0) 1541210502Ssyrinx wif->ht_compatible = TruthValue_false; 1542210502Ssyrinx else 1543210502Ssyrinx wif->ht_compatible = TruthValue_true; 1544210502Ssyrinx break; 1545210502Ssyrinx case IEEE80211_IOC_HTPROTMODE: 1546210502Ssyrinx if (val == IEEE80211_PROTMODE_RTSCTS) 1547210502Ssyrinx wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_rts; 1548210502Ssyrinx else 1549210502Ssyrinx wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_off; 1550210502Ssyrinx break; 1551210502Ssyrinx case IEEE80211_IOC_RIFS: 1552210502Ssyrinx if (val == 0) 1553210502Ssyrinx wif->rifs = TruthValue_false; 1554210502Ssyrinx else 1555210502Ssyrinx wif->rifs = TruthValue_true; 1556210502Ssyrinx break; 1557210502Ssyrinx case IEEE80211_IOC_SHORTGI: 1558210502Ssyrinx if (val == 0) 1559210502Ssyrinx wif->short_gi = TruthValue_false; 1560210502Ssyrinx else 1561210502Ssyrinx wif->short_gi = TruthValue_true; 1562210502Ssyrinx break; 1563210502Ssyrinx case IEEE80211_IOC_SMPS: 1564210502Ssyrinx switch (val) { 1565210502Ssyrinx case IEEE80211_HTCAP_SMPS_DYNAMIC: 1566210502Ssyrinx wif->smps_mode = wlanIfaceDot11nSMPSMode_dynamic; 1567210502Ssyrinx break; 1568210502Ssyrinx case IEEE80211_HTCAP_SMPS_ENA: 1569210502Ssyrinx wif->smps_mode = wlanIfaceDot11nSMPSMode_static; 1570210502Ssyrinx break; 1571210502Ssyrinx case IEEE80211_HTCAP_SMPS_OFF: 1572210502Ssyrinx /* FALLTHROUGH */ 1573210502Ssyrinx default: 1574210502Ssyrinx wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled; 1575210502Ssyrinx break; 1576210502Ssyrinx } 1577210502Ssyrinx break; 1578210502Ssyrinx case IEEE80211_IOC_TDMA_SLOT: 1579210502Ssyrinx wif->tdma_slot = val; 1580210502Ssyrinx break; 1581210502Ssyrinx case IEEE80211_IOC_TDMA_SLOTCNT: 1582210502Ssyrinx wif->tdma_slot_count = val; 1583210502Ssyrinx break; 1584210502Ssyrinx case IEEE80211_IOC_TDMA_SLOTLEN: 1585210502Ssyrinx wif->tdma_slot_length = val; 1586210502Ssyrinx break; 1587210502Ssyrinx case IEEE80211_IOC_TDMA_BINTERVAL: 1588210502Ssyrinx wif->tdma_binterval = val; 1589210502Ssyrinx break; 1590210502Ssyrinx default: 1591210502Ssyrinx break; 1592210502Ssyrinx } 1593210502Ssyrinx} 1594210502Ssyrinx 1595210502Ssyrinx/* 1596210502Ssyrinx * Convert an SNMP value to the kernel equivalent and also do sanity check 1597210502Ssyrinx * for each specific type. 1598210502Ssyrinx */ 1599210502Ssyrinxstatic int 1600210502Ssyrinxwlan_config_snmp2value(int which, int sval, int *value) 1601210502Ssyrinx{ 1602210502Ssyrinx *value = 0; 1603210502Ssyrinx 1604210502Ssyrinx switch (which) { 1605210502Ssyrinx case IEEE80211_IOC_BURST: 1606210502Ssyrinx case IEEE80211_IOC_DFS: 1607210502Ssyrinx case IEEE80211_IOC_FF: 1608210502Ssyrinx case IEEE80211_IOC_TURBOP: 1609210502Ssyrinx case IEEE80211_IOC_WPS: 1610210502Ssyrinx case IEEE80211_IOC_BGSCAN: 1611210502Ssyrinx case IEEE80211_IOC_DOTD: 1612210502Ssyrinx case IEEE80211_IOC_DOTH: 1613210502Ssyrinx case IEEE80211_IOC_DWDS: 1614210502Ssyrinx case IEEE80211_IOC_POWERSAVE: 1615210502Ssyrinx case IEEE80211_IOC_APBRIDGE: 1616210502Ssyrinx case IEEE80211_IOC_HIDESSID: 1617210502Ssyrinx case IEEE80211_IOC_INACTIVITY: 1618210502Ssyrinx case IEEE80211_IOC_PUREG: 1619210502Ssyrinx case IEEE80211_IOC_PUREN: 1620210502Ssyrinx case IEEE80211_IOC_HTCONF: 1621210502Ssyrinx case IEEE80211_IOC_HTCOMPAT: 1622210502Ssyrinx case IEEE80211_IOC_RIFS: 1623210502Ssyrinx if (sval == TruthValue_true) 1624210502Ssyrinx *value = 1; 1625210502Ssyrinx else if (sval != TruthValue_false) 1626210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1627210502Ssyrinx break; 1628210502Ssyrinx case IEEE80211_IOC_REGDOMAIN: 1629210502Ssyrinx break; 1630210502Ssyrinx case IEEE80211_IOC_SSID: 1631210502Ssyrinx break; 1632210502Ssyrinx case IEEE80211_IOC_CURCHAN: 1633210502Ssyrinx break; 1634210502Ssyrinx case IEEE80211_IOC_TXPOWER: 1635210502Ssyrinx *value = sval * 2; 1636210502Ssyrinx break; 1637210502Ssyrinx case IEEE80211_IOC_FRAGTHRESHOLD: 1638210502Ssyrinx if (sval < IEEE80211_FRAG_MIN || sval > IEEE80211_FRAG_MAX) 1639210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1640210502Ssyrinx *value = sval; 1641210502Ssyrinx break; 1642210502Ssyrinx case IEEE80211_IOC_RTSTHRESHOLD: 1643210502Ssyrinx if (sval < IEEE80211_RTS_MIN || sval > IEEE80211_RTS_MAX) 1644210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1645210502Ssyrinx *value = sval; 1646210502Ssyrinx break; 1647210502Ssyrinx case IEEE80211_IOC_BGSCAN_IDLE: 1648210502Ssyrinx if (sval < WLAN_BGSCAN_IDLE_MIN) 1649210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1650210502Ssyrinx *value = sval; 1651210502Ssyrinx break; 1652210502Ssyrinx case IEEE80211_IOC_BGSCAN_INTERVAL: 1653210502Ssyrinx if (sval < WLAN_SCAN_VALID_MIN) 1654210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1655210502Ssyrinx *value = sval; 1656210502Ssyrinx break; 1657210502Ssyrinx case IEEE80211_IOC_BMISSTHRESHOLD: 1658210502Ssyrinx if (sval < IEEE80211_HWBMISS_MIN || sval > IEEE80211_HWBMISS_MAX) 1659210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1660210502Ssyrinx *value = sval; 1661210502Ssyrinx break; 1662210502Ssyrinx case IEEE80211_IOC_BSSID: 1663210502Ssyrinx break; 1664210502Ssyrinx case IEEE80211_IOC_ROAMING: 1665210502Ssyrinx switch (sval) { 1666210502Ssyrinx case wlanIfaceRoamingMode_device: 1667210502Ssyrinx *value = IEEE80211_ROAMING_DEVICE; 1668210502Ssyrinx break; 1669210502Ssyrinx case wlanIfaceRoamingMode_manual: 1670210502Ssyrinx *value = IEEE80211_ROAMING_MANUAL; 1671210502Ssyrinx break; 1672210502Ssyrinx case wlanIfaceRoamingMode_auto: 1673210502Ssyrinx *value = IEEE80211_ROAMING_AUTO; 1674210502Ssyrinx break; 1675210502Ssyrinx default: 1676210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1677210502Ssyrinx } 1678210502Ssyrinx break; 1679210502Ssyrinx case IEEE80211_IOC_BEACON_INTERVAL: 1680210502Ssyrinx if (sval < IEEE80211_BINTVAL_MIN || sval > IEEE80211_BINTVAL_MAX) 1681210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1682210502Ssyrinx *value = sval; 1683210502Ssyrinx break; 1684210502Ssyrinx case IEEE80211_IOC_DTIM_PERIOD: 1685210502Ssyrinx if (sval < IEEE80211_DTIM_MIN || sval > IEEE80211_DTIM_MAX) 1686210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1687210502Ssyrinx *value = sval; 1688210502Ssyrinx break; 1689210502Ssyrinx case IEEE80211_IOC_PROTMODE: 1690210502Ssyrinx switch (sval) { 1691210502Ssyrinx case wlanIfaceDot11gProtMode_cts: 1692210502Ssyrinx *value = IEEE80211_PROTMODE_CTS; 1693210502Ssyrinx break; 1694210502Ssyrinx case wlanIfaceDot11gProtMode_rtscts: 1695210502Ssyrinx *value = IEEE80211_PROTMODE_RTSCTS; 1696210502Ssyrinx break; 1697210502Ssyrinx case wlanIfaceDot11gProtMode_off: 1698210502Ssyrinx *value = IEEE80211_PROTMODE_OFF; 1699210502Ssyrinx break; 1700210502Ssyrinx default: 1701210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1702210502Ssyrinx } 1703210502Ssyrinx break; 1704210502Ssyrinx case IEEE80211_IOC_AMPDU: 1705210502Ssyrinx switch (sval) { 1706210502Ssyrinx case WlanIfaceDot11nPduType_disabled: 1707210502Ssyrinx break; 1708210502Ssyrinx case WlanIfaceDot11nPduType_txOnly: 1709210502Ssyrinx *value = 1; 1710210502Ssyrinx break; 1711210502Ssyrinx case WlanIfaceDot11nPduType_rxOnly: 1712210502Ssyrinx *value = 2; 1713210502Ssyrinx break; 1714210502Ssyrinx case WlanIfaceDot11nPduType_txAndRx: 1715210502Ssyrinx *value = 3; 1716210502Ssyrinx break; 1717210502Ssyrinx default: 1718210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1719210502Ssyrinx } 1720210502Ssyrinx break; 1721210502Ssyrinx case IEEE80211_IOC_AMPDU_DENSITY: 1722210502Ssyrinx switch (sval) { 1723210502Ssyrinx case 0: 1724210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_NA; 1725210502Ssyrinx break; 1726210502Ssyrinx case 25: 1727210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_025; 1728210502Ssyrinx break; 1729210502Ssyrinx case 50: 1730210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_05; 1731210502Ssyrinx break; 1732210502Ssyrinx case 100: 1733210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_1; 1734210502Ssyrinx break; 1735210502Ssyrinx case 200: 1736210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_2; 1737210502Ssyrinx break; 1738210502Ssyrinx case 400: 1739210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_4; 1740210502Ssyrinx break; 1741210502Ssyrinx case 800: 1742210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_8; 1743210502Ssyrinx break; 1744210502Ssyrinx case 1600: 1745210502Ssyrinx *value = IEEE80211_HTCAP_MPDUDENSITY_16; 1746210502Ssyrinx break; 1747210502Ssyrinx default: 1748210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1749210502Ssyrinx } 1750210502Ssyrinx break; 1751210502Ssyrinx case IEEE80211_IOC_AMPDU_LIMIT: 1752210502Ssyrinx switch (sval) { 1753210502Ssyrinx case 8192: 1754210502Ssyrinx *value = IEEE80211_HTCAP_MAXRXAMPDU_8K; 1755210502Ssyrinx break; 1756210502Ssyrinx case 16384: 1757210502Ssyrinx *value = IEEE80211_HTCAP_MAXRXAMPDU_16K; 1758210502Ssyrinx break; 1759210502Ssyrinx case 32768: 1760210502Ssyrinx *value = IEEE80211_HTCAP_MAXRXAMPDU_32K; 1761210502Ssyrinx break; 1762210502Ssyrinx case 65536: 1763210502Ssyrinx *value = IEEE80211_HTCAP_MAXRXAMPDU_64K; 1764210502Ssyrinx break; 1765210502Ssyrinx default: 1766210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1767210502Ssyrinx } 1768210502Ssyrinx break; 1769210502Ssyrinx case IEEE80211_IOC_AMSDU: 1770210502Ssyrinx switch (sval) { 1771210502Ssyrinx case WlanIfaceDot11nPduType_disabled: 1772210502Ssyrinx break; 1773210502Ssyrinx case WlanIfaceDot11nPduType_txOnly: 1774210502Ssyrinx *value = 1; 1775210502Ssyrinx break; 1776210502Ssyrinx case WlanIfaceDot11nPduType_rxOnly: 1777210502Ssyrinx *value = 2; 1778210502Ssyrinx break; 1779210502Ssyrinx case WlanIfaceDot11nPduType_txAndRx: 1780210502Ssyrinx *value = 3; 1781210502Ssyrinx break; 1782210502Ssyrinx default: 1783210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1784210502Ssyrinx } 1785210502Ssyrinx break; 1786210502Ssyrinx case IEEE80211_IOC_AMSDU_LIMIT: 1787210502Ssyrinx if (sval == 3839 || sval == 0) 1788210502Ssyrinx *value = IEEE80211_HTCAP_MAXAMSDU_3839; 1789210502Ssyrinx else if (sval == 7935) 1790210502Ssyrinx *value = IEEE80211_HTCAP_MAXAMSDU_7935; 1791210502Ssyrinx else 1792210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1793210502Ssyrinx break; 1794210502Ssyrinx case IEEE80211_IOC_HTPROTMODE: 1795210502Ssyrinx switch (sval) { 1796210502Ssyrinx case wlanIfaceDot11nHTProtMode_rts: 1797210502Ssyrinx *value = IEEE80211_PROTMODE_RTSCTS; 1798210502Ssyrinx break; 1799210502Ssyrinx case wlanIfaceDot11nHTProtMode_off: 1800210502Ssyrinx break; 1801210502Ssyrinx default: 1802210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1803210502Ssyrinx } 1804210502Ssyrinx break; 1805210502Ssyrinx case IEEE80211_IOC_SHORTGI: 1806210502Ssyrinx if (sval == TruthValue_true) 1807210502Ssyrinx *value = IEEE80211_HTCAP_SHORTGI20 | 1808210502Ssyrinx IEEE80211_HTCAP_SHORTGI40; 1809210502Ssyrinx else if (sval != TruthValue_false) 1810210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1811210502Ssyrinx break; 1812210502Ssyrinx case IEEE80211_IOC_SMPS: 1813210502Ssyrinx switch (sval) { 1814210502Ssyrinx case wlanIfaceDot11nSMPSMode_disabled: 1815210502Ssyrinx *value = IEEE80211_HTCAP_SMPS_OFF; 1816210502Ssyrinx break; 1817210502Ssyrinx case wlanIfaceDot11nSMPSMode_static: 1818210502Ssyrinx *value = IEEE80211_HTCAP_SMPS_ENA; 1819210502Ssyrinx break; 1820210502Ssyrinx case wlanIfaceDot11nSMPSMode_dynamic: 1821210502Ssyrinx *value = IEEE80211_HTCAP_SMPS_DYNAMIC; 1822210502Ssyrinx break; 1823210502Ssyrinx default: 1824210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1825210502Ssyrinx } 1826210502Ssyrinx break; 1827210502Ssyrinx case IEEE80211_IOC_TDMA_SLOT: 1828210502Ssyrinx if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */ 1829210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1830210502Ssyrinx *value = sval; 1831210502Ssyrinx break; 1832210502Ssyrinx case IEEE80211_IOC_TDMA_SLOTCNT: 1833210502Ssyrinx if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */ 1834210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1835210502Ssyrinx *value = sval; 1836210502Ssyrinx break; 1837210502Ssyrinx case IEEE80211_IOC_TDMA_SLOTLEN: 1838210502Ssyrinx if (sval < 2*100 || sval > 0xfffff) /* XXX */ 1839210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1840210502Ssyrinx *value = sval; 1841210502Ssyrinx break; 1842210502Ssyrinx case IEEE80211_IOC_TDMA_BINTERVAL: 1843210502Ssyrinx if (sval < 1) /* XXX */ 1844210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1845210502Ssyrinx *value = sval; 1846210502Ssyrinx break; 1847210502Ssyrinx default: 1848210502Ssyrinx return (SNMP_ERR_INCONS_VALUE); 1849210502Ssyrinx } 1850210502Ssyrinx 1851210502Ssyrinx return (SNMP_ERR_NOERROR); 1852210502Ssyrinx} 1853210502Ssyrinx 1854210502Ssyrinx/* 1855210502Ssyrinx * Sanity checks for the wlanIfaceConfigTable. 1856210502Ssyrinx */ 1857210502Ssyrinxstatic int 1858210502Ssyrinxwlan_config_check(struct wlan_iface *wif, int op) 1859210502Ssyrinx{ 1860210502Ssyrinx switch (op) { 1861210502Ssyrinx case IEEE80211_IOC_BURST: 1862210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_burst)) == 0) { 1863210502Ssyrinx wif->packet_burst = TruthValue_false; 1864210502Ssyrinx return (-1); 1865210502Ssyrinx } 1866210502Ssyrinx break; 1867210502Ssyrinx case IEEE80211_IOC_DFS: 1868210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_dfs)) == 0) { 1869210502Ssyrinx wif->dyn_frequency = TruthValue_false; 1870210502Ssyrinx return (-1); 1871210502Ssyrinx } 1872210502Ssyrinx break; 1873210502Ssyrinx case IEEE80211_IOC_FF: 1874210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_athFastFrames)) 1875210502Ssyrinx == 0) { 1876210502Ssyrinx wif->fast_frames = TruthValue_false; 1877210502Ssyrinx return (-1); 1878210502Ssyrinx } 1879210502Ssyrinx break; 1880210502Ssyrinx case IEEE80211_IOC_TURBOP: 1881210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_athTurbo)) == 0) { 1882210502Ssyrinx wif->dturbo = TruthValue_false; 1883210502Ssyrinx return (-1); 1884210502Ssyrinx } 1885210502Ssyrinx break; 1886210502Ssyrinx case IEEE80211_IOC_TXPOWER: 1887210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_txPmgt)) == 0) { 1888210502Ssyrinx wif->tx_power = 0; 1889210502Ssyrinx return (-1); 1890210502Ssyrinx } 1891210502Ssyrinx break; 1892210502Ssyrinx case IEEE80211_IOC_FRAGTHRESHOLD: 1893210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_txFrag)) == 0) { 1894210502Ssyrinx wif->frag_threshold = IEEE80211_FRAG_MAX; 1895210502Ssyrinx return (-1); 1896210502Ssyrinx } 1897210502Ssyrinx break; 1898210502Ssyrinx case IEEE80211_IOC_DWDS: 1899210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_wds)) == 0) { 1900210502Ssyrinx wif->dynamic_wds = TruthValue_false; 1901210502Ssyrinx return (-1); 1902210502Ssyrinx } 1903210502Ssyrinx break; 1904210502Ssyrinx case IEEE80211_IOC_POWERSAVE: 1905210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_pmgt)) == 0) { 1906210502Ssyrinx wif->power_save = TruthValue_false; 1907210502Ssyrinx return (-1); 1908210502Ssyrinx } 1909210502Ssyrinx break; 1910210502Ssyrinx case IEEE80211_IOC_BEACON_INTERVAL: 1911210502Ssyrinx if (wif->mode != WlanIfaceOperatingModeType_hostAp && 1912210502Ssyrinx wif->mode != WlanIfaceOperatingModeType_meshPoint && 1913210502Ssyrinx wif->mode != WlanIfaceOperatingModeType_ibss) { 1914210502Ssyrinx wif->beacon_interval = 100; /* XXX */ 1915210502Ssyrinx return (-1); 1916210502Ssyrinx } 1917210502Ssyrinx break; 1918210502Ssyrinx case IEEE80211_IOC_DTIM_PERIOD: 1919210502Ssyrinx if (wif->mode != WlanIfaceOperatingModeType_hostAp && 1920210502Ssyrinx wif->mode != WlanIfaceOperatingModeType_meshPoint && 1921210502Ssyrinx wif->mode != WlanIfaceOperatingModeType_ibss) { 1922210502Ssyrinx wif->dtim_period = 1; /* XXX */ 1923210502Ssyrinx return (-1); 1924210502Ssyrinx } 1925210502Ssyrinx break; 1926210502Ssyrinx case IEEE80211_IOC_PUREN: 1927210502Ssyrinx if ((wif->htcaps & (0x1 << WlanHTCaps_htcHt)) == 0) { 1928210502Ssyrinx wif->dot11n_pure = TruthValue_false; 1929210502Ssyrinx return (-1); 1930210502Ssyrinx } 1931210502Ssyrinx break; 1932210502Ssyrinx case IEEE80211_IOC_AMPDU: 1933210502Ssyrinx if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmpdu)) == 0) { 1934210502Ssyrinx wif->ampdu = WlanIfaceDot11nPduType_disabled; 1935210502Ssyrinx return (-1); 1936210502Ssyrinx } 1937210502Ssyrinx break; 1938210502Ssyrinx case IEEE80211_IOC_AMSDU: 1939210502Ssyrinx if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmsdu)) == 0) { 1940210502Ssyrinx wif->amsdu = WlanIfaceDot11nPduType_disabled; 1941210502Ssyrinx return (-1); 1942210502Ssyrinx } 1943210502Ssyrinx break; 1944210502Ssyrinx case IEEE80211_IOC_RIFS: 1945210502Ssyrinx if ((wif->htcaps & (0x1 << WlanHTCaps_htcRifs)) == 0) { 1946210502Ssyrinx wif->rifs = TruthValue_false; 1947210502Ssyrinx return (-1); 1948210502Ssyrinx } 1949210502Ssyrinx break; 1950210502Ssyrinx case IEEE80211_IOC_SHORTGI: 1951210502Ssyrinx if ((wif->htcaps & (0x1 << WlanHTCaps_shortGi20 | 1952210502Ssyrinx 0x1 << WlanHTCaps_shortGi40)) == 0) { 1953210502Ssyrinx wif->short_gi = TruthValue_false; 1954210502Ssyrinx return (-1); 1955210502Ssyrinx } 1956210502Ssyrinx break; 1957210502Ssyrinx case IEEE80211_IOC_SMPS: 1958210502Ssyrinx if ((wif->htcaps & (0x1 << WlanHTCaps_htcSmps)) == 0) { 1959210502Ssyrinx wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled; 1960210502Ssyrinx return (-1); 1961210502Ssyrinx } 1962210502Ssyrinx break; 1963210502Ssyrinx case IEEE80211_IOC_TDMA_SLOT: 1964210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1965210502Ssyrinx wif->tdma_slot = 0; 1966210502Ssyrinx return (-1); 1967210502Ssyrinx } 1968210502Ssyrinx break; 1969210502Ssyrinx case IEEE80211_IOC_TDMA_SLOTCNT: 1970210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1971210502Ssyrinx wif->tdma_slot_count = 0; 1972210502Ssyrinx return (-1); 1973210502Ssyrinx } 1974210502Ssyrinx break; 1975210502Ssyrinx case IEEE80211_IOC_TDMA_SLOTLEN: 1976210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1977210502Ssyrinx wif->tdma_slot_length = 0; 1978210502Ssyrinx return (-1); 1979210502Ssyrinx } 1980210502Ssyrinx break; 1981210502Ssyrinx case IEEE80211_IOC_TDMA_BINTERVAL: 1982210502Ssyrinx if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1983210502Ssyrinx wif->tdma_binterval = 0; 1984210502Ssyrinx return (-1); 1985210502Ssyrinx } 1986210502Ssyrinx break; 1987210502Ssyrinx default: 1988210502Ssyrinx break; 1989210502Ssyrinx } 1990210502Ssyrinx 1991210502Ssyrinx return (0); 1992210502Ssyrinx} 1993210502Ssyrinx 1994210502Ssyrinxstatic int 1995210502Ssyrinxwlan_config_get_intval(struct wlan_iface *wif, int op) 1996210502Ssyrinx{ 1997210502Ssyrinx int val = 0; 1998210502Ssyrinx size_t argsize = 0; 1999210502Ssyrinx 2000210502Ssyrinx if (wlan_config_check(wif, op) < 0) 2001210502Ssyrinx return (0); 2002210502Ssyrinx if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0) 2003210502Ssyrinx return (-1); 2004210502Ssyrinx wlan_config_set_snmp_intval(wif, op, val); 2005210502Ssyrinx 2006210502Ssyrinx return (0); 2007210502Ssyrinx} 2008210502Ssyrinx 2009210502Ssyrinxstatic int 2010210502Ssyrinxwlan_config_set_intval(struct wlan_iface *wif, int op, int sval) 2011210502Ssyrinx{ 2012210502Ssyrinx size_t argsize = 0; 2013210502Ssyrinx int val; 2014210502Ssyrinx 2015210502Ssyrinx if (wlan_config_check(wif, op) < 0) 2016210502Ssyrinx return (-1); 2017210502Ssyrinx if (wlan_config_snmp2value(op, sval, &val) != SNMP_ERR_NOERROR) 2018210502Ssyrinx return (-1); 2019210502Ssyrinx if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0) 2020210502Ssyrinx return (-1); 2021210502Ssyrinx wlan_config_set_snmp_intval(wif, op, val); 2022210502Ssyrinx 2023210502Ssyrinx return (0); 2024210502Ssyrinx} 2025210502Ssyrinx 2026210502Ssyrinxint 2027210502Ssyrinxwlan_config_get_ioctl(struct wlan_iface *wif, int which) 2028210502Ssyrinx{ 2029210502Ssyrinx int op; 2030210502Ssyrinx 2031210502Ssyrinx switch (which) { 2032210502Ssyrinx case LEAF_wlanIfaceCountryCode: 2033210502Ssyrinx /* FALLTHROUGH */ 2034210502Ssyrinx case LEAF_wlanIfaceRegDomain: 2035210502Ssyrinx return (wlan_config_get_country(wif)); 2036210502Ssyrinx case LEAF_wlanIfaceDesiredSsid: 2037210502Ssyrinx return (wlan_config_get_dssid(wif)); 2038210502Ssyrinx case LEAF_wlanIfaceDesiredChannel: 2039210502Ssyrinx return (wlan_config_get_dchannel(wif)); 2040210502Ssyrinx case LEAF_wlanIfaceDesiredBssid: 2041210502Ssyrinx return (wlan_config_get_bssid(wif)); 2042210502Ssyrinx default: 2043210502Ssyrinx op = wlan_config_snmp2ioctl(which); 2044210502Ssyrinx return (wlan_config_get_intval(wif, op)); 2045210502Ssyrinx } 2046210502Ssyrinx 2047210502Ssyrinx return (-1); 2048210502Ssyrinx} 2049210502Ssyrinx 2050210502Ssyrinxint 2051210502Ssyrinxwlan_config_set_ioctl(struct wlan_iface *wif, int which, int val, 2052210502Ssyrinx char *strval, int len) 2053210502Ssyrinx{ 2054210502Ssyrinx int op; 2055210502Ssyrinx 2056210502Ssyrinx switch (which) { 2057210502Ssyrinx case LEAF_wlanIfaceCountryCode: 2058210502Ssyrinx return (wlan_config_set_country(wif, strval, 2059210502Ssyrinx wif->reg_domain)); 2060210502Ssyrinx case LEAF_wlanIfaceRegDomain: 2061210502Ssyrinx return (wlan_config_set_country(wif, wif->country_code, 2062210502Ssyrinx val)); 2063210502Ssyrinx case LEAF_wlanIfaceDesiredSsid: 2064210502Ssyrinx return (wlan_config_set_dssid(wif, strval, len)); 2065210502Ssyrinx case LEAF_wlanIfaceDesiredChannel: 2066210502Ssyrinx return (wlan_config_set_dchannel(wif, val)); 2067210502Ssyrinx case LEAF_wlanIfaceDesiredBssid: 2068210502Ssyrinx return (wlan_config_set_bssid(wif, strval)); 2069210502Ssyrinx default: 2070210502Ssyrinx op = wlan_config_snmp2ioctl(which); 2071210502Ssyrinx return (wlan_config_set_intval(wif, op, val)); 2072210502Ssyrinx } 2073210502Ssyrinx 2074210502Ssyrinx return (-1); 2075210502Ssyrinx} 2076210502Ssyrinx 2077210502Ssyrinxstatic uint32_t 2078210502Ssyrinxwlan_snmp_to_scan_flags(int flags) 2079210502Ssyrinx{ 2080210502Ssyrinx int sr_flags = 0; 2081210502Ssyrinx 2082210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_noSelection)) != 0) 2083210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_NOPICK; 2084210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_activeScan)) != 0) 2085210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_ACTIVE; 2086210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_pickFirst)) != 0) 2087210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_PICK1ST; 2088210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_backgroundScan)) != 0) 2089210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_BGSCAN; 2090210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_once)) != 0) 2091210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_ONCE; 2092210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_noBroadcast)) != 0) 2093210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_NOBCAST; 2094210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_noAutoSequencing)) != 0) 2095210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_NOJOIN; 2096210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_flushCashe)) != 0) 2097210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_FLUSH; 2098210502Ssyrinx if ((flags & (0x1 << WlanScanFlagsType_chechCashe)) != 0) 2099210502Ssyrinx sr_flags |= IEEE80211_IOC_SCAN_CHECK; 2100210502Ssyrinx 2101210502Ssyrinx return (sr_flags); 2102210502Ssyrinx} 2103210502Ssyrinx 2104210502Ssyrinxint 2105210502Ssyrinxwlan_set_scan_config(struct wlan_iface *wif) 2106210502Ssyrinx{ 2107210502Ssyrinx int val = 0; 2108210502Ssyrinx size_t argsize; 2109210502Ssyrinx struct ieee80211_scan_req sr; 2110210502Ssyrinx 2111210502Ssyrinx 2112210502Ssyrinx memset(&sr, 0, sizeof(sr)); 2113210502Ssyrinx argsize = sizeof(struct ieee80211_scan_req); 2114210502Ssyrinx sr.sr_flags = wlan_snmp_to_scan_flags(wif->scan_flags); 2115210502Ssyrinx sr.sr_flags |= IEEE80211_IOC_SCAN_BGSCAN; 2116210502Ssyrinx sr.sr_duration = wif->scan_duration; 2117210502Ssyrinx sr.sr_mindwell = wif->scan_mindwell; 2118210502Ssyrinx sr.sr_maxdwell = wif->scan_maxdwell; 2119210502Ssyrinx sr.sr_nssid = 0; 2120210502Ssyrinx 2121210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_REQ, 2122210502Ssyrinx &val, &sr, &argsize, 1) < 0) 2123210502Ssyrinx return (-1); 2124210502Ssyrinx 2125210502Ssyrinx wif->scan_status = wlanScanConfigStatus_running; 2126210502Ssyrinx return (0); 2127210502Ssyrinx} 2128210502Ssyrinx 2129210502Ssyrinxstatic uint32_t 2130210502Ssyrinxwlan_peercaps_to_snmp(uint32_t pcaps) 2131210502Ssyrinx{ 2132210502Ssyrinx uint32_t scaps = 0; 2133210502Ssyrinx 2134210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_ESS) != 0) 2135210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_ess); 2136210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_IBSS) != 0) 2137210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_ibss); 2138210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_CF_POLLABLE) != 0) 2139210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollable); 2140210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_CF_POLLREQ) != 0) 2141210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollRequest); 2142210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_PRIVACY) != 0) 2143210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_privacy); 2144210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_SHORT_PREAMBLE) != 0) 2145210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_shortPreamble); 2146210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_PBCC) != 0) 2147210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_pbcc); 2148210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_CHNL_AGILITY) != 0) 2149210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_channelAgility); 2150210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_SHORT_SLOTTIME) != 0) 2151210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_shortSlotTime); 2152210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_RSN) != 0) 2153210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_rsn); 2154210502Ssyrinx if ((pcaps & IEEE80211_CAPINFO_DSSSOFDM) != 0) 2155210502Ssyrinx scaps |= (0x1 << WlanPeerCapabilityFlags_dsssofdm); 2156210502Ssyrinx 2157210502Ssyrinx return (scaps); 2158210502Ssyrinx} 2159210502Ssyrinx 2160210502Ssyrinxstatic int 2161210502Ssyrinxwlan_add_new_scan_result(struct wlan_iface *wif, 2162210502Ssyrinx const struct ieee80211req_scan_result *isr, uint8_t *ssid) 2163210502Ssyrinx{ 2164210502Ssyrinx struct wlan_scan_result *sr; 2165210502Ssyrinx 2166210502Ssyrinx if ((sr = wlan_scan_new_result(ssid, isr->isr_bssid)) == NULL) 2167210502Ssyrinx return (-1); 2168210502Ssyrinx 2169210502Ssyrinx sr->opchannel = wlan_channel_flags_to_snmp_phy(isr->isr_flags); 2170210502Ssyrinx sr->rssi = isr->isr_rssi; 2171210502Ssyrinx sr->frequency = isr->isr_freq; 2172210502Ssyrinx sr->noise = isr->isr_noise; 2173210502Ssyrinx sr->bintval = isr->isr_intval; 2174210502Ssyrinx sr->capinfo = wlan_peercaps_to_snmp(isr->isr_capinfo); 2175210502Ssyrinx 2176210502Ssyrinx if (wlan_scan_add_result(wif, sr) < 0) { 2177210502Ssyrinx wlan_scan_free_result(sr); 2178210502Ssyrinx return (-1); 2179210502Ssyrinx } 2180210502Ssyrinx 2181210502Ssyrinx return (0); 2182210502Ssyrinx} 2183210502Ssyrinx 2184210502Ssyrinxint 2185210502Ssyrinxwlan_get_scan_results(struct wlan_iface *wif) 2186210502Ssyrinx{ 2187210502Ssyrinx int ssidlen, val = 0; 2188210502Ssyrinx uint8_t buf[24 * 1024]; 2189210502Ssyrinx size_t argsize; 2190210502Ssyrinx const uint8_t *cp, *idp; 2191210502Ssyrinx uint8_t ssid[IEEE80211_NWID_LEN + 1]; 2192210502Ssyrinx struct ieee80211req_scan_result isr; 2193210502Ssyrinx 2194210502Ssyrinx argsize = sizeof(buf); 2195210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_RESULTS, &val, &buf, 2196210502Ssyrinx &argsize, 0) < 0) 2197210502Ssyrinx return (-1); 2198210502Ssyrinx 2199210502Ssyrinx if (argsize < sizeof(struct ieee80211req_scan_result)) 2200210502Ssyrinx return (0); 2201210502Ssyrinx 2202210502Ssyrinx cp = buf; 2203210502Ssyrinx do { 2204210502Ssyrinx memcpy(&isr, cp, sizeof(struct ieee80211req_scan_result)); 2205210502Ssyrinx memset(ssid, 0, IEEE80211_NWID_LEN + 1); 2206210502Ssyrinx 2207210502Ssyrinx if (isr.isr_meshid_len) { 2208210502Ssyrinx idp = cp + isr.isr_ie_off + isr.isr_ssid_len; 2209210502Ssyrinx ssidlen = isr.isr_meshid_len; 2210210502Ssyrinx } else { 2211210502Ssyrinx idp = cp + isr.isr_ie_off; 2212210502Ssyrinx ssidlen = isr.isr_ssid_len; 2213210502Ssyrinx } 2214210502Ssyrinx if (ssidlen > IEEE80211_NWID_LEN) 2215210502Ssyrinx ssidlen = IEEE80211_NWID_LEN; 2216210502Ssyrinx memcpy(ssid, idp, ssidlen); 2217210502Ssyrinx ssid[IEEE80211_NWID_LEN] = '\0'; 2218210502Ssyrinx (void)wlan_add_new_scan_result(wif, &isr, ssid); 2219210502Ssyrinx cp += isr.isr_len; 2220210502Ssyrinx argsize -= isr.isr_len; 2221210502Ssyrinx } while (argsize >= sizeof(struct ieee80211req_scan_result)); 2222210502Ssyrinx 2223210502Ssyrinx return (0); 2224210502Ssyrinx} 2225210502Ssyrinx 2226210502Ssyrinxint 2227210502Ssyrinxwlan_get_stats(struct wlan_iface *wif) 2228210502Ssyrinx{ 2229210502Ssyrinx struct ifreq ifr; 2230210502Ssyrinx 2231210502Ssyrinx memset(&ifr, 0, sizeof(struct ifreq)); 2232210502Ssyrinx strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ); 2233210502Ssyrinx 2234210502Ssyrinx ifr.ifr_data = (caddr_t) &wif->stats; 2235210502Ssyrinx 2236210502Ssyrinx if (ioctl(sock, SIOCG80211STATS, &ifr) < 0) { 2237210502Ssyrinx syslog(LOG_ERR, "iface %s - ioctl(SIOCG80211STATS) failed: %s", 2238210502Ssyrinx wif->wname, strerror(errno)); 2239210502Ssyrinx return (-1); 2240210502Ssyrinx } 2241210502Ssyrinx 2242210502Ssyrinx return (0); 2243210502Ssyrinx} 2244210502Ssyrinx 2245210502Ssyrinxint 2246210502Ssyrinxwlan_get_wepmode(struct wlan_iface *wif) 2247210502Ssyrinx{ 2248210502Ssyrinx int val = 0; 2249210502Ssyrinx size_t argsize = 0; 2250210502Ssyrinx 2251210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL, 2252210502Ssyrinx &argsize, 0) < 0 || val == IEEE80211_WEP_NOSUP) { 2253210502Ssyrinx wif->wepsupported = 0; /* XXX */ 2254210502Ssyrinx wif->wepmode = wlanWepMode_off; 2255210502Ssyrinx wif->weptxkey = 0; 2256210502Ssyrinx return (-1); 2257210502Ssyrinx } 2258210502Ssyrinx 2259210502Ssyrinx wif->wepsupported = 1; 2260210502Ssyrinx 2261210502Ssyrinx switch (val) { 2262210502Ssyrinx case IEEE80211_WEP_ON: 2263210502Ssyrinx wif->wepmode = wlanWepMode_on; 2264210502Ssyrinx break; 2265210502Ssyrinx case IEEE80211_WEP_MIXED: 2266210502Ssyrinx wif->wepmode = wlanWepMode_mixed; 2267210502Ssyrinx break; 2268210502Ssyrinx case IEEE80211_WEP_OFF: 2269210502Ssyrinx /* FALLTHROUGH */ 2270210502Ssyrinx default: 2271210502Ssyrinx wif->wepmode = wlanWepMode_off; 2272210502Ssyrinx break; 2273210502Ssyrinx } 2274210502Ssyrinx 2275210502Ssyrinx return (0); 2276210502Ssyrinx} 2277210502Ssyrinx 2278210502Ssyrinxint 2279210502Ssyrinxwlan_set_wepmode(struct wlan_iface *wif) 2280210502Ssyrinx{ 2281210502Ssyrinx int val; 2282210502Ssyrinx size_t argsize = 0; 2283210502Ssyrinx 2284210502Ssyrinx if (!wif->wepsupported) 2285210502Ssyrinx return (-1); 2286210502Ssyrinx 2287210502Ssyrinx switch (wif->wepmode) { 2288210502Ssyrinx case wlanWepMode_off: 2289210502Ssyrinx val = IEEE80211_WEP_OFF; 2290210502Ssyrinx break; 2291210502Ssyrinx case wlanWepMode_on: 2292210502Ssyrinx val = IEEE80211_WEP_ON; 2293210502Ssyrinx break; 2294210502Ssyrinx case wlanWepMode_mixed: 2295210502Ssyrinx val = IEEE80211_WEP_MIXED; 2296210502Ssyrinx break; 2297210502Ssyrinx default: 2298210502Ssyrinx return (-1); 2299210502Ssyrinx } 2300210502Ssyrinx 2301210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL, 2302210502Ssyrinx &argsize, 1) < 0) 2303210502Ssyrinx return (-1); 2304210502Ssyrinx 2305210502Ssyrinx return (0); 2306210502Ssyrinx} 2307210502Ssyrinx 2308210502Ssyrinxint 2309210502Ssyrinxwlan_get_weptxkey(struct wlan_iface *wif) 2310210502Ssyrinx{ 2311210502Ssyrinx int val; 2312210502Ssyrinx size_t argsize = 0; 2313210502Ssyrinx 2314210502Ssyrinx if (!wif->wepsupported) 2315210502Ssyrinx return (0); 2316210502Ssyrinx 2317210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL, 2318210502Ssyrinx &argsize, 0) < 0) 2319210502Ssyrinx return (-1); 2320210502Ssyrinx 2321210502Ssyrinx if (val == IEEE80211_KEYIX_NONE) 2322210502Ssyrinx wif->weptxkey = 0; 2323210502Ssyrinx else 2324210502Ssyrinx wif->weptxkey = val + 1; 2325210502Ssyrinx 2326210502Ssyrinx return (0); 2327210502Ssyrinx} 2328210502Ssyrinx 2329210502Ssyrinxint 2330210502Ssyrinxwlan_set_weptxkey(struct wlan_iface *wif) 2331210502Ssyrinx{ 2332210502Ssyrinx int val; 2333210502Ssyrinx size_t argsize = 0; 2334210502Ssyrinx 2335210502Ssyrinx if (!wif->wepsupported) 2336210502Ssyrinx return (0); 2337210502Ssyrinx 2338210502Ssyrinx if (wif->weptxkey >= IEEE80211_WEP_NKID) 2339210502Ssyrinx return (-1); 2340210502Ssyrinx 2341210502Ssyrinx if (wif->weptxkey == 0) 2342210502Ssyrinx val = IEEE80211_KEYIX_NONE; 2343210502Ssyrinx else 2344210502Ssyrinx val = wif->weptxkey - 1; 2345210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL, 2346210502Ssyrinx &argsize, 1) < 0) 2347210502Ssyrinx return (-1); 2348210502Ssyrinx 2349210502Ssyrinx return (0); 2350210502Ssyrinx} 2351210502Ssyrinx 2352210502Ssyrinxint 2353210502Ssyrinxwlan_get_wepkeys(struct wlan_iface *wif __unused) 2354210502Ssyrinx{ 2355210502Ssyrinx /* XXX: should they be visible via SNMP */ 2356210502Ssyrinx return (0); 2357210502Ssyrinx} 2358210502Ssyrinx 2359210502Ssyrinxint 2360210502Ssyrinxwlan_set_wepkeys(struct wlan_iface *wif __unused) 2361210502Ssyrinx{ 2362210502Ssyrinx /* XXX: should they be configurable via SNMP */ 2363210502Ssyrinx return (0); 2364210502Ssyrinx} 2365210502Ssyrinx 2366210502Ssyrinxint 2367210502Ssyrinxwlan_get_mac_policy(struct wlan_iface *wif) 2368210502Ssyrinx{ 2369210502Ssyrinx int val = IEEE80211_MACCMD_POLICY; 2370210502Ssyrinx size_t argsize = 0; 2371210502Ssyrinx struct ieee80211req ireq; 2372210502Ssyrinx 2373210502Ssyrinx memset(&ireq, 0, sizeof(struct ieee80211req)); 2374210502Ssyrinx strlcpy(ireq.i_name, wif->wname, IFNAMSIZ); 2375210502Ssyrinx ireq.i_type = IEEE80211_IOC_MACCMD; 2376210502Ssyrinx ireq.i_val = IEEE80211_MACCMD_POLICY; 2377210502Ssyrinx 2378210502Ssyrinx if (ioctl(sock, SIOCG80211, &ireq) < 0) { 2379210502Ssyrinx if (errno != EINVAL) { 2380210502Ssyrinx syslog(LOG_ERR, "iface %s - get param: ioctl(%d) " 2381210502Ssyrinx "failed: %s", wif->wname, ireq.i_type, 2382210502Ssyrinx strerror(errno)); 2383210502Ssyrinx wif->macsupported = 0; 2384210502Ssyrinx return (-1); 2385210502Ssyrinx } else { 2386210502Ssyrinx wif->macsupported = 1; 2387210502Ssyrinx wif->mac_policy = wlanMACAccessControlPolicy_open; 2388210502Ssyrinx return (0); 2389210502Ssyrinx } 2390310901Sngie 2391210502Ssyrinx } 2392210502Ssyrinx 2393210502Ssyrinx wif->macsupported = 1; 2394210502Ssyrinx 2395210502Ssyrinx switch (val) { 2396210502Ssyrinx case IEEE80211_MACCMD_POLICY_ALLOW: 2397210502Ssyrinx wif->mac_policy = wlanMACAccessControlPolicy_allow; 2398210502Ssyrinx break; 2399210502Ssyrinx case IEEE80211_MACCMD_POLICY_DENY: 2400210502Ssyrinx wif->mac_policy = wlanMACAccessControlPolicy_deny; 2401210502Ssyrinx break; 2402210502Ssyrinx case IEEE80211_MACCMD_POLICY_RADIUS: 2403210502Ssyrinx wif->mac_policy = wlanMACAccessControlPolicy_radius; 2404210502Ssyrinx break; 2405210502Ssyrinx case IEEE80211_MACCMD_POLICY_OPEN: 2406210502Ssyrinx /* FALLTHROUGH */ 2407210502Ssyrinx default: 2408210502Ssyrinx wif->mac_policy = wlanMACAccessControlPolicy_open; 2409210502Ssyrinx break; 2410210502Ssyrinx } 2411210502Ssyrinx 2412210502Ssyrinx argsize = 0; 2413210502Ssyrinx val = IEEE80211_MACCMD_LIST; 2414210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, 2415210502Ssyrinx &argsize, 0) < 0) 2416210502Ssyrinx return (-1); 2417210502Ssyrinx 2418210502Ssyrinx wif->mac_nacls = argsize / sizeof(struct ieee80211req_maclist *); 2419210502Ssyrinx return (0); 2420210502Ssyrinx} 2421210502Ssyrinx 2422210502Ssyrinxint 2423210502Ssyrinxwlan_set_mac_policy(struct wlan_iface *wif) 2424210502Ssyrinx{ 2425210502Ssyrinx int val; 2426210502Ssyrinx size_t argsize = 0; 2427210502Ssyrinx 2428210502Ssyrinx if (!wif->macsupported) 2429210502Ssyrinx return (-1); 2430210502Ssyrinx 2431210502Ssyrinx switch (wif->mac_policy) { 2432210502Ssyrinx case wlanMACAccessControlPolicy_allow: 2433210502Ssyrinx val = IEEE80211_MACCMD_POLICY_ALLOW; 2434210502Ssyrinx break; 2435210502Ssyrinx case wlanMACAccessControlPolicy_deny: 2436210502Ssyrinx val = IEEE80211_MACCMD_POLICY_DENY; 2437210502Ssyrinx break; 2438210502Ssyrinx case wlanMACAccessControlPolicy_radius: 2439210502Ssyrinx val = IEEE80211_MACCMD_POLICY_RADIUS; 2440210502Ssyrinx break; 2441210502Ssyrinx case wlanMACAccessControlPolicy_open: 2442210502Ssyrinx val = IEEE80211_MACCMD_POLICY_OPEN; 2443210502Ssyrinx break; 2444210502Ssyrinx default: 2445210502Ssyrinx return (-1); 2446210502Ssyrinx } 2447210502Ssyrinx 2448210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, 2449210502Ssyrinx &argsize, 1) < 0) 2450210502Ssyrinx return (-1); 2451210502Ssyrinx 2452210502Ssyrinx return (0); 2453210502Ssyrinx} 2454210502Ssyrinx 2455210502Ssyrinxint 2456210502Ssyrinxwlan_flush_mac_mac(struct wlan_iface *wif) 2457210502Ssyrinx{ 2458210502Ssyrinx int val = IEEE80211_MACCMD_FLUSH; 2459210502Ssyrinx size_t argsize = 0; 2460210502Ssyrinx 2461210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, 2462210502Ssyrinx &argsize, 1) < 0) 2463210502Ssyrinx return (-1); 2464210502Ssyrinx 2465210502Ssyrinx return (0); 2466210502Ssyrinx} 2467210502Ssyrinx 2468210502Ssyrinxstatic int 2469210502Ssyrinxwlan_add_mac_macinfo(struct wlan_iface *wif, 2470210502Ssyrinx const struct ieee80211req_maclist *ml) 2471210502Ssyrinx{ 2472210502Ssyrinx struct wlan_mac_mac *mmac; 2473210502Ssyrinx 2474210502Ssyrinx if ((mmac = wlan_mac_new_mac(ml->ml_macaddr)) == NULL) 2475210502Ssyrinx return (-1); 2476210502Ssyrinx 2477210502Ssyrinx mmac->mac_status = RowStatus_active; 2478210502Ssyrinx if (wlan_mac_add_mac(wif, mmac) < 0) { 2479210502Ssyrinx wlan_mac_free_mac(mmac); 2480210502Ssyrinx return (-1); 2481210502Ssyrinx } 2482210502Ssyrinx 2483210502Ssyrinx return (0); 2484210502Ssyrinx} 2485210502Ssyrinx 2486210502Ssyrinxint 2487210502Ssyrinxwlan_get_mac_acl_macs(struct wlan_iface *wif) 2488210502Ssyrinx{ 2489210502Ssyrinx int i, nacls, val = IEEE80211_MACCMD_LIST; 2490210502Ssyrinx size_t argsize = 0; 2491210502Ssyrinx uint8_t *data; 2492210502Ssyrinx struct ieee80211req ireq; 2493210502Ssyrinx const struct ieee80211req_maclist *acllist; 2494210502Ssyrinx 2495210502Ssyrinx if (wif->mac_policy == wlanMACAccessControlPolicy_radius) { 2496210502Ssyrinx wif->mac_nacls = 0; 2497210502Ssyrinx return (0); 2498210502Ssyrinx } 2499210502Ssyrinx 2500210502Ssyrinx memset(&ireq, 0, sizeof(struct ieee80211req)); 2501210502Ssyrinx strlcpy(ireq.i_name, wif->wname, IFNAMSIZ); 2502210502Ssyrinx ireq.i_type = IEEE80211_IOC_MACCMD; 2503210502Ssyrinx ireq.i_val = IEEE80211_MACCMD_LIST; 2504210502Ssyrinx 2505210502Ssyrinx 2506210502Ssyrinx if (ioctl(sock, SIOCG80211, &ireq) < 0) { 2507210502Ssyrinx if (errno != EINVAL) { 2508210502Ssyrinx syslog(LOG_ERR, "iface %s - get param: ioctl(%d) " 2509210502Ssyrinx "failed: %s", wif->wname, ireq.i_type, 2510210502Ssyrinx strerror(errno)); 2511210502Ssyrinx wif->macsupported = 0; 2512210502Ssyrinx return (-1); 2513210502Ssyrinx } 2514210502Ssyrinx } 2515210502Ssyrinx 2516210502Ssyrinx if (argsize == 0) { 2517210502Ssyrinx wif->mac_nacls = 0; 2518210502Ssyrinx return (0); 2519210502Ssyrinx } 2520210502Ssyrinx 2521210502Ssyrinx if ((data = (uint8_t *)malloc(argsize)) == NULL) 2522210502Ssyrinx return (-1); 2523210502Ssyrinx 2524210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, data, 2525210502Ssyrinx &argsize, 0) < 0) 2526210502Ssyrinx return (-1); 2527210502Ssyrinx 2528210502Ssyrinx nacls = argsize / sizeof(*acllist); 2529210502Ssyrinx acllist = (struct ieee80211req_maclist *) data; 2530210502Ssyrinx for (i = 0; i < nacls; i++) 2531210502Ssyrinx (void)wlan_add_mac_macinfo(wif, acllist + i); 2532210502Ssyrinx 2533210502Ssyrinx wif->mac_nacls = nacls; 2534210502Ssyrinx return (0); 2535210502Ssyrinx} 2536210502Ssyrinx 2537210502Ssyrinxint 2538210502Ssyrinxwlan_add_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac) 2539210502Ssyrinx{ 2540210502Ssyrinx int val = 0; 2541210502Ssyrinx size_t argsize = IEEE80211_ADDR_LEN; 2542210502Ssyrinx struct ieee80211req_mlme mlme; 2543210502Ssyrinx 2544210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_ADDMAC, &val, 2545210502Ssyrinx mmac->mac, &argsize, 1) < 0) 2546210502Ssyrinx return (-1); 2547210502Ssyrinx 2548210502Ssyrinx mmac->mac_status = RowStatus_active; 2549210502Ssyrinx 2550210502Ssyrinx /* If policy is deny, try to kick the station just in case. */ 2551210502Ssyrinx if (wif->mac_policy != wlanMACAccessControlPolicy_deny) 2552210502Ssyrinx return (0); 2553210502Ssyrinx 2554210502Ssyrinx memset(&mlme, 0, sizeof(mlme)); 2555210502Ssyrinx mlme.im_op = IEEE80211_MLME_DEAUTH; 2556210502Ssyrinx mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; 2557210502Ssyrinx memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN); 2558210502Ssyrinx argsize = sizeof(struct ieee80211req_mlme); 2559210502Ssyrinx 2560210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme, 2561210502Ssyrinx &argsize, 1) < 0 && errno != ENOENT) 2562210502Ssyrinx return (-1); 2563210502Ssyrinx 2564210502Ssyrinx return (0); 2565210502Ssyrinx} 2566210502Ssyrinx 2567210502Ssyrinxint 2568210502Ssyrinxwlan_del_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac) 2569210502Ssyrinx{ 2570210502Ssyrinx int val = 0; 2571210502Ssyrinx size_t argsize = IEEE80211_ADDR_LEN; 2572210502Ssyrinx struct ieee80211req_mlme mlme; 2573210502Ssyrinx 2574210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_DELMAC, &val, 2575210502Ssyrinx mmac->mac, &argsize, 1) < 0) 2576210502Ssyrinx return (-1); 2577210502Ssyrinx 2578210502Ssyrinx mmac->mac_status = RowStatus_active; 2579210502Ssyrinx 2580210502Ssyrinx /* If policy is allow, try to kick the station just in case. */ 2581210502Ssyrinx if (wif->mac_policy != wlanMACAccessControlPolicy_allow) 2582210502Ssyrinx return (0); 2583210502Ssyrinx 2584210502Ssyrinx memset(&mlme, 0, sizeof(mlme)); 2585210502Ssyrinx mlme.im_op = IEEE80211_MLME_DEAUTH; 2586210502Ssyrinx mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; 2587210502Ssyrinx memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN); 2588210502Ssyrinx argsize = sizeof(struct ieee80211req_mlme); 2589210502Ssyrinx 2590210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme, 2591210502Ssyrinx &argsize, 1) < 0 && errno != ENOENT) 2592210502Ssyrinx return (-1); 2593210502Ssyrinx 2594210502Ssyrinx return (0); 2595210502Ssyrinx} 2596210502Ssyrinx 2597210502Ssyrinxint 2598210502Ssyrinxwlan_peer_set_vlan(struct wlan_iface *wif, struct wlan_peer *wip, int vlan) 2599210502Ssyrinx{ 2600210502Ssyrinx int val = 0; 2601210502Ssyrinx size_t argsize; 2602210502Ssyrinx struct ieee80211req_sta_vlan vreq; 2603210502Ssyrinx 2604210502Ssyrinx memcpy(vreq.sv_macaddr, wip->pmac, IEEE80211_ADDR_LEN); 2605210502Ssyrinx vreq.sv_vlan = vlan; 2606210502Ssyrinx argsize = sizeof(struct ieee80211req_sta_vlan); 2607210502Ssyrinx 2608210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_VLAN, 2609210502Ssyrinx &val, &vreq, &argsize, 1) < 0) 2610210502Ssyrinx return (-1); 2611210502Ssyrinx 2612210502Ssyrinx wip->vlan = vlan; 2613210502Ssyrinx 2614210502Ssyrinx return (0); 2615210502Ssyrinx} 2616210502Ssyrinx 2617210502Ssyrinx/* XXX */ 2618210502Ssyrinx#ifndef IEEE80211_NODE_AUTH 2619210502Ssyrinx#define IEEE80211_NODE_AUTH 0x000001 /* authorized for data */ 2620210502Ssyrinx#define IEEE80211_NODE_QOS 0x000002 /* QoS enabled */ 2621210502Ssyrinx#define IEEE80211_NODE_ERP 0x000004 /* ERP enabled */ 2622210502Ssyrinx#define IEEE80211_NODE_PWR_MGT 0x000010 /* power save mode enabled */ 2623210502Ssyrinx#define IEEE80211_NODE_AREF 0x000020 /* authentication ref held */ 2624210502Ssyrinx#define IEEE80211_NODE_HT 0x000040 /* HT enabled */ 2625210502Ssyrinx#define IEEE80211_NODE_HTCOMPAT 0x000080 /* HT setup w/ vendor OUI's */ 2626210502Ssyrinx#define IEEE80211_NODE_WPS 0x000100 /* WPS association */ 2627210502Ssyrinx#define IEEE80211_NODE_TSN 0x000200 /* TSN association */ 2628210502Ssyrinx#define IEEE80211_NODE_AMPDU_RX 0x000400 /* AMPDU rx enabled */ 2629210502Ssyrinx#define IEEE80211_NODE_AMPDU_TX 0x000800 /* AMPDU tx enabled */ 2630210502Ssyrinx#define IEEE80211_NODE_MIMO_PS 0x001000 /* MIMO power save enabled */ 2631210502Ssyrinx#define IEEE80211_NODE_MIMO_RTS 0x002000 /* send RTS in MIMO PS */ 2632210502Ssyrinx#define IEEE80211_NODE_RIFS 0x004000 /* RIFS enabled */ 2633210502Ssyrinx#define IEEE80211_NODE_SGI20 0x008000 /* Short GI in HT20 enabled */ 2634210502Ssyrinx#define IEEE80211_NODE_SGI40 0x010000 /* Short GI in HT40 enabled */ 2635210502Ssyrinx#define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ 2636210502Ssyrinx#define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */ 2637210502Ssyrinx#define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */ 2638210502Ssyrinx#endif 2639210502Ssyrinx 2640210502Ssyrinxstatic uint32_t 2641210502Ssyrinxwlan_peerstate_to_snmp(uint32_t pstate) 2642210502Ssyrinx{ 2643210502Ssyrinx uint32_t sstate = 0; 2644210502Ssyrinx 2645210502Ssyrinx if ((pstate & IEEE80211_NODE_AUTH) != 0) 2646210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_authorizedForData); 2647210502Ssyrinx if ((pstate & IEEE80211_NODE_QOS) != 0) 2648210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_qosEnabled); 2649210502Ssyrinx if ((pstate & IEEE80211_NODE_ERP) != 0) 2650210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_erpEnabled); 2651210502Ssyrinx if ((pstate & IEEE80211_NODE_PWR_MGT) != 0) 2652210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_powerSaveMode); 2653210502Ssyrinx if ((pstate & IEEE80211_NODE_AREF) != 0) 2654210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_authRefHeld); 2655210502Ssyrinx if ((pstate & IEEE80211_NODE_HT) != 0) 2656210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_htEnabled); 2657210502Ssyrinx if ((pstate & IEEE80211_NODE_HTCOMPAT) != 0) 2658210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_htCompat); 2659210502Ssyrinx if ((pstate & IEEE80211_NODE_WPS) != 0) 2660210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_wpsAssoc); 2661210502Ssyrinx if ((pstate & IEEE80211_NODE_TSN) != 0) 2662210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_tsnAssoc); 2663210502Ssyrinx if ((pstate & IEEE80211_NODE_AMPDU_RX) != 0) 2664210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_ampduRx); 2665210502Ssyrinx if ((pstate & IEEE80211_NODE_AMPDU_TX) != 0) 2666210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_ampduTx); 2667210502Ssyrinx if ((pstate & IEEE80211_NODE_MIMO_PS) != 0) 2668210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_mimoPowerSave); 2669210502Ssyrinx if ((pstate & IEEE80211_NODE_MIMO_RTS) != 0) 2670210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_sendRts); 2671210502Ssyrinx if ((pstate & IEEE80211_NODE_RIFS) != 0) 2672210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_rifs); 2673210502Ssyrinx if ((pstate & IEEE80211_NODE_SGI20) != 0) 2674210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT20); 2675210502Ssyrinx if ((pstate & IEEE80211_NODE_SGI40) != 0) 2676210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT40); 2677210502Ssyrinx if ((pstate & IEEE80211_NODE_AMSDU_RX) != 0) 2678210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_amsduRx); 2679210502Ssyrinx if ((pstate & IEEE80211_NODE_AMSDU_TX) != 0) 2680210502Ssyrinx sstate |= (0x1 << WlanIfacePeerFlagsType_amsduTx); 2681210502Ssyrinx 2682210502Ssyrinx return (sstate); 2683210502Ssyrinx} 2684210502Ssyrinx 2685210502Ssyrinxstatic struct wlan_peer * 2686210502Ssyrinxwlan_add_peerinfo(const struct ieee80211req_sta_info *si) 2687210502Ssyrinx{ 2688210502Ssyrinx struct wlan_peer *wip; 2689210502Ssyrinx 2690210502Ssyrinx if ((wip = wlan_new_peer(si->isi_macaddr))== NULL) 2691210502Ssyrinx return (NULL); 2692210502Ssyrinx 2693210502Ssyrinx wip->associd = IEEE80211_AID(si->isi_associd); 2694210502Ssyrinx wip->vlan = si->isi_vlan; 2695210502Ssyrinx wip->frequency = si->isi_freq; 2696210502Ssyrinx wip->fflags = si->isi_flags; 2697210502Ssyrinx wip->txrate = si->isi_txrate; 2698210502Ssyrinx wip->rssi = si->isi_rssi; 2699210502Ssyrinx wip->idle = si->isi_inact; 2700210502Ssyrinx wip->txseqs = si->isi_txseqs[0]; /* XXX */ 2701210502Ssyrinx wip->rxseqs = si->isi_rxseqs[0]; /* XXX */ 2702210502Ssyrinx wip->txpower = si->isi_txpower; 2703210502Ssyrinx wip->capinfo = wlan_peercaps_to_snmp(si->isi_capinfo); 2704210502Ssyrinx wip->state = wlan_peerstate_to_snmp(si->isi_state); 2705210502Ssyrinx wip->local_id = si->isi_localid; 2706210502Ssyrinx wip->peer_id = si->isi_peerid; 2707210502Ssyrinx 2708210502Ssyrinx return (wip); 2709210502Ssyrinx} 2710210502Ssyrinx 2711210502Ssyrinxint 2712210502Ssyrinxwlan_get_peerinfo(struct wlan_iface *wif) 2713210502Ssyrinx{ 2714210502Ssyrinx union { 2715210502Ssyrinx struct ieee80211req_sta_req req; 2716210502Ssyrinx uint8_t buf[24 * 1024]; 2717210502Ssyrinx } u; 2718210502Ssyrinx const uint8_t *cp; 2719210502Ssyrinx int val = 0; 2720210502Ssyrinx size_t len; 2721210502Ssyrinx struct ieee80211req_sta_info si; 2722210502Ssyrinx struct wlan_peer *wip; 2723210502Ssyrinx 2724210502Ssyrinx /* Get all stations - broadcast address */ 2725210502Ssyrinx (void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN); 2726210502Ssyrinx len = sizeof(u); 2727210502Ssyrinx 2728210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_INFO, 2729210502Ssyrinx & val, &u, &len, 0) < 0) 2730210502Ssyrinx return (-1); 2731210502Ssyrinx 2732210502Ssyrinx if (len < sizeof(struct ieee80211req_sta_info)) 2733210502Ssyrinx return (-1); 2734210502Ssyrinx 2735210502Ssyrinx cp = (const uint8_t *) u.req.info; 2736210502Ssyrinx do { 2737210502Ssyrinx memcpy(&si, cp, sizeof(struct ieee80211req_sta_info)); 2738210502Ssyrinx if ((wip = wlan_add_peerinfo(&si)) != NULL && 2739210502Ssyrinx wlan_add_peer(wif, wip) < 0) 2740210502Ssyrinx wlan_free_peer(wip); 2741210502Ssyrinx cp += si.isi_len, len -= si.isi_len; 2742210502Ssyrinx } while (len >= sizeof(struct ieee80211req_sta_info)); 2743210502Ssyrinx 2744210502Ssyrinx return (0); 2745210502Ssyrinx} 2746210502Ssyrinx 2747210502Ssyrinx/************************************************************************ 2748210502Ssyrinx * Wireless MESH & HWMP sysctl config. 2749210502Ssyrinx */ 2750210502Ssyrinxconst char wlan_sysctl_name[] = "net.wlan."; 2751210502Ssyrinx 2752210502Ssyrinxstatic const char *wlan_sysctl[] = { 2753210502Ssyrinx "mesh.retrytimeout", 2754210502Ssyrinx "mesh.holdingtimeout", 2755210502Ssyrinx "mesh.confirmtimeout", 2756210502Ssyrinx "mesh.maxretries", 2757210502Ssyrinx "hwmp.targetonly", 2758210502Ssyrinx "hwmp.replyforward", 2759210502Ssyrinx "hwmp.pathlifetime", 2760210502Ssyrinx "hwmp.roottimeout", 2761210502Ssyrinx "hwmp.rootint", 2762210502Ssyrinx "hwmp.rannint", 2763210502Ssyrinx "hwmp.inact", 2764210502Ssyrinx}; 2765210502Ssyrinx 2766210502Ssyrinxint32_t 2767210502Ssyrinxwlan_do_sysctl(struct wlan_config *cfg, enum wlan_syscl which, int set) 2768210502Ssyrinx{ 2769210502Ssyrinx char mib_name[100]; 2770210502Ssyrinx int val, sval; 2771210502Ssyrinx size_t len, vlen; 2772210502Ssyrinx 2773210502Ssyrinx if (set) { 2774210502Ssyrinx vlen = sizeof(sval); 2775210502Ssyrinx switch (which) { 2776210502Ssyrinx case WLAN_MESH_RETRY_TO: 2777210502Ssyrinx sval = cfg->mesh_retryto; 2778210502Ssyrinx break; 2779210502Ssyrinx case WLAN_MESH_HOLDING_TO: 2780210502Ssyrinx sval = cfg->mesh_holdingto; 2781210502Ssyrinx break; 2782210502Ssyrinx case WLAN_MESH_CONFIRM_TO: 2783210502Ssyrinx sval = cfg->mesh_confirmto; 2784210502Ssyrinx break; 2785210502Ssyrinx case WLAN_MESH_MAX_RETRIES: 2786210502Ssyrinx sval = cfg->mesh_maxretries; 2787210502Ssyrinx break; 2788210502Ssyrinx case WLAN_HWMP_TARGET_ONLY: 2789210502Ssyrinx sval = cfg->hwmp_targetonly; 2790210502Ssyrinx break; 2791210502Ssyrinx case WLAN_HWMP_REPLY_FORWARD: 2792210502Ssyrinx sval = cfg->hwmp_replyforward; 2793210502Ssyrinx break; 2794210502Ssyrinx case WLAN_HWMP_PATH_LIFETIME: 2795210502Ssyrinx sval = cfg->hwmp_pathlifetime; 2796210502Ssyrinx break; 2797210502Ssyrinx case WLAN_HWMP_ROOT_TO: 2798210502Ssyrinx sval = cfg->hwmp_roottimeout; 2799210502Ssyrinx break; 2800210502Ssyrinx case WLAN_HWMP_ROOT_INT: 2801210502Ssyrinx sval = cfg->hwmp_rootint; 2802210502Ssyrinx break; 2803210502Ssyrinx case WLAN_HWMP_RANN_INT: 2804210502Ssyrinx sval = cfg->hwmp_rannint; 2805210502Ssyrinx break; 2806210502Ssyrinx case WLAN_HWMP_INACTIVITY_TO: 2807210502Ssyrinx sval = cfg->hwmp_inact; 2808210502Ssyrinx break; 2809210502Ssyrinx default: 2810210502Ssyrinx return (-1); 2811210502Ssyrinx } 2812210502Ssyrinx } else { 2813210502Ssyrinx if (which >= WLAN_SYSCTL_MAX) 2814210502Ssyrinx return (-1); 2815210502Ssyrinx vlen = 0; 2816210502Ssyrinx } 2817210502Ssyrinx 2818210502Ssyrinx strlcpy(mib_name, wlan_sysctl_name, sizeof(mib_name)); 2819210502Ssyrinx strlcat(mib_name, wlan_sysctl[which], sizeof(mib_name)); 2820210502Ssyrinx len = sizeof (val); 2821210502Ssyrinx 2822210502Ssyrinx if (sysctlbyname(mib_name, &val, &len, (set? &sval : NULL), vlen) < 0) { 2823210502Ssyrinx syslog(LOG_ERR, "sysctl(%s) failed - %s", mib_name, 2824210502Ssyrinx strerror(errno)); 2825210502Ssyrinx return (-1); 2826210502Ssyrinx } 2827210502Ssyrinx 2828210502Ssyrinx switch (which) { 2829210502Ssyrinx case WLAN_MESH_RETRY_TO: 2830210502Ssyrinx cfg->mesh_retryto = val; 2831210502Ssyrinx break; 2832210502Ssyrinx case WLAN_MESH_HOLDING_TO: 2833210502Ssyrinx cfg->mesh_holdingto = val; 2834210502Ssyrinx break; 2835210502Ssyrinx case WLAN_MESH_CONFIRM_TO: 2836210502Ssyrinx cfg->mesh_confirmto = val; 2837210502Ssyrinx break; 2838210502Ssyrinx case WLAN_MESH_MAX_RETRIES: 2839210502Ssyrinx cfg->mesh_maxretries = val; 2840210502Ssyrinx break; 2841210502Ssyrinx case WLAN_HWMP_TARGET_ONLY: 2842210502Ssyrinx cfg->hwmp_targetonly = val; 2843210502Ssyrinx break; 2844210502Ssyrinx case WLAN_HWMP_REPLY_FORWARD: 2845210502Ssyrinx cfg->hwmp_replyforward = val; 2846210502Ssyrinx break; 2847210502Ssyrinx case WLAN_HWMP_PATH_LIFETIME: 2848210502Ssyrinx cfg->hwmp_pathlifetime = val; 2849210502Ssyrinx break; 2850210502Ssyrinx case WLAN_HWMP_ROOT_TO: 2851210502Ssyrinx cfg->hwmp_roottimeout = val; 2852210502Ssyrinx break; 2853210502Ssyrinx case WLAN_HWMP_ROOT_INT: 2854210502Ssyrinx cfg->hwmp_rootint = val; 2855210502Ssyrinx break; 2856210502Ssyrinx case WLAN_HWMP_RANN_INT: 2857210502Ssyrinx cfg->hwmp_rannint = val; 2858210502Ssyrinx break; 2859210502Ssyrinx case WLAN_HWMP_INACTIVITY_TO: 2860210502Ssyrinx cfg->hwmp_inact = val; 2861210502Ssyrinx break; 2862210502Ssyrinx default: 2863210502Ssyrinx /* NOTREACHED */ 2864210502Ssyrinx abort(); 2865210502Ssyrinx } 2866210502Ssyrinx 2867210502Ssyrinx return (0); 2868210502Ssyrinx} 2869210502Ssyrinx 2870210502Ssyrinxint 2871210502Ssyrinxwlan_mesh_config_get(struct wlan_iface *wif, int which) 2872210502Ssyrinx{ 2873210502Ssyrinx int op, val = 0; 2874210502Ssyrinx size_t argsize = 0; 2875210502Ssyrinx uint8_t data[32], *pd = NULL; 2876210502Ssyrinx 2877210502Ssyrinx switch (which) { 2878210502Ssyrinx case LEAF_wlanMeshTTL: 2879210502Ssyrinx op = IEEE80211_IOC_MESH_TTL; 2880210502Ssyrinx break; 2881210502Ssyrinx case LEAF_wlanMeshPeeringEnabled: 2882210502Ssyrinx op = IEEE80211_IOC_MESH_AP; 2883210502Ssyrinx break; 2884210502Ssyrinx case LEAF_wlanMeshForwardingEnabled: 2885210502Ssyrinx op = IEEE80211_IOC_MESH_FWRD; 2886210502Ssyrinx break; 2887210502Ssyrinx case LEAF_wlanMeshMetric: 2888210502Ssyrinx op = IEEE80211_IOC_MESH_PR_METRIC; 2889210502Ssyrinx pd = data; 2890210502Ssyrinx argsize = sizeof(data); 2891210502Ssyrinx break; 2892210502Ssyrinx case LEAF_wlanMeshPath: 2893210502Ssyrinx op = IEEE80211_IOC_MESH_PR_PATH; 2894210502Ssyrinx pd = data; 2895210502Ssyrinx argsize = sizeof(data); 2896210502Ssyrinx break; 2897210502Ssyrinx case LEAF_wlanMeshRoutesFlush: 2898210502Ssyrinx return (0); 2899210502Ssyrinx default: 2900210502Ssyrinx return (-1); 2901210502Ssyrinx } 2902210502Ssyrinx 2903210502Ssyrinx if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 0) < 0) 2904210502Ssyrinx return (-1); 2905210502Ssyrinx 2906210502Ssyrinx switch (which) { 2907210502Ssyrinx case LEAF_wlanMeshTTL: 2908210502Ssyrinx wif->mesh_ttl = val; 2909210502Ssyrinx break; 2910210502Ssyrinx case LEAF_wlanMeshPeeringEnabled: 2911210502Ssyrinx if (val) 2912210502Ssyrinx wif->mesh_peering = wlanMeshPeeringEnabled_true; 2913210502Ssyrinx else 2914210502Ssyrinx wif->mesh_peering = wlanMeshPeeringEnabled_false; 2915210502Ssyrinx break; 2916210502Ssyrinx case LEAF_wlanMeshForwardingEnabled: 2917210502Ssyrinx if (val) 2918210502Ssyrinx wif->mesh_forwarding = wlanMeshForwardingEnabled_true; 2919210502Ssyrinx else 2920210502Ssyrinx wif->mesh_forwarding = wlanMeshForwardingEnabled_false; 2921210502Ssyrinx break; 2922210502Ssyrinx case LEAF_wlanMeshMetric: 2923210502Ssyrinx data[argsize] = '\0'; 2924210502Ssyrinx if (strcmp(data, "AIRTIME") == 0) 2925210502Ssyrinx wif->mesh_metric = wlanMeshMetric_airtime; 2926210502Ssyrinx else 2927210502Ssyrinx wif->mesh_metric = wlanMeshMetric_unknown; 2928210502Ssyrinx break; 2929210502Ssyrinx case LEAF_wlanMeshPath: 2930210502Ssyrinx data[argsize] = '\0'; 2931210502Ssyrinx if (strcmp(data, "HWMP") == 0) 2932210502Ssyrinx wif->mesh_path = wlanMeshPath_hwmp; 2933210502Ssyrinx else 2934210502Ssyrinx wif->mesh_path = wlanMeshPath_unknown; 2935210502Ssyrinx } 2936210502Ssyrinx 2937210502Ssyrinx return (0); 2938210502Ssyrinx} 2939210502Ssyrinx 2940210502Ssyrinxint 2941210502Ssyrinxwlan_mesh_config_set(struct wlan_iface *wif, int which) 2942210502Ssyrinx{ 2943210502Ssyrinx int op, val = 0; 2944210502Ssyrinx size_t argsize = 0; 2945210502Ssyrinx uint8_t data[32], *pd = NULL; 2946210502Ssyrinx 2947210502Ssyrinx switch (which) { 2948210502Ssyrinx case LEAF_wlanMeshTTL: 2949210502Ssyrinx op = IEEE80211_IOC_MESH_TTL; 2950210502Ssyrinx val = wif->mesh_ttl; 2951210502Ssyrinx break; 2952210502Ssyrinx case LEAF_wlanMeshPeeringEnabled: 2953210502Ssyrinx op = IEEE80211_IOC_MESH_AP; 2954210502Ssyrinx if (wif->mesh_peering == wlanMeshPeeringEnabled_true) 2955210502Ssyrinx val = 1; 2956210502Ssyrinx break; 2957210502Ssyrinx case LEAF_wlanMeshForwardingEnabled: 2958210502Ssyrinx if (wif->mesh_forwarding == wlanMeshForwardingEnabled_true) 2959210502Ssyrinx val = 1; 2960210502Ssyrinx op = IEEE80211_IOC_MESH_FWRD; 2961210502Ssyrinx break; 2962210502Ssyrinx case LEAF_wlanMeshMetric: 2963210502Ssyrinx op = IEEE80211_IOC_MESH_PR_METRIC; 2964210502Ssyrinx if (wif->mesh_metric == wlanMeshMetric_airtime) 2965210502Ssyrinx strcpy(data, "AIRTIME"); 2966210502Ssyrinx else 2967210502Ssyrinx return (-1); 2968210502Ssyrinx pd = data; 2969210502Ssyrinx argsize = sizeof(data); 2970210502Ssyrinx break; 2971210502Ssyrinx case LEAF_wlanMeshPath: 2972210502Ssyrinx op = IEEE80211_IOC_MESH_PR_PATH; 2973210502Ssyrinx if (wif->mesh_path == wlanMeshPath_hwmp) 2974210502Ssyrinx strcpy(data, "HWMP"); 2975210502Ssyrinx else 2976210502Ssyrinx return (-1); 2977210502Ssyrinx pd = data; 2978210502Ssyrinx argsize = sizeof(data); 2979210502Ssyrinx break; 2980210502Ssyrinx default: 2981210502Ssyrinx return (-1); 2982210502Ssyrinx } 2983210502Ssyrinx 2984210502Ssyrinx if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 1) < 0) 2985210502Ssyrinx return (-1); 2986210502Ssyrinx 2987210502Ssyrinx return(0); 2988210502Ssyrinx} 2989210502Ssyrinx 2990210502Ssyrinxint 2991210502Ssyrinxwlan_mesh_flush_routes(struct wlan_iface *wif) 2992210502Ssyrinx{ 2993210502Ssyrinx int val = IEEE80211_MESH_RTCMD_FLUSH; 2994210502Ssyrinx size_t argsize = 0; 2995210502Ssyrinx 2996210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, NULL, 2997210502Ssyrinx &argsize, 1) < 0) 2998210502Ssyrinx return (-1); 2999210502Ssyrinx 3000210502Ssyrinx return (0); 3001210502Ssyrinx} 3002210502Ssyrinx 3003210502Ssyrinxint 3004210502Ssyrinxwlan_mesh_add_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr) 3005210502Ssyrinx{ 3006210502Ssyrinx int val = IEEE80211_MESH_RTCMD_ADD; 3007210502Ssyrinx size_t argsize = IEEE80211_ADDR_LEN; 3008210502Ssyrinx 3009210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, 3010210502Ssyrinx wmr->imroute.imr_dest, &argsize, 1) < 0) 3011210502Ssyrinx return (-1); 3012210502Ssyrinx 3013210502Ssyrinx wmr->mroute_status = RowStatus_active; 3014210502Ssyrinx 3015210502Ssyrinx return (0); 3016210502Ssyrinx} 3017210502Ssyrinx 3018210502Ssyrinxint 3019210502Ssyrinxwlan_mesh_del_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr) 3020210502Ssyrinx{ 3021210502Ssyrinx int val = IEEE80211_MESH_RTCMD_DELETE; 3022210502Ssyrinx size_t argsize = IEEE80211_ADDR_LEN; 3023210502Ssyrinx 3024210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, 3025210502Ssyrinx wmr->imroute.imr_dest, &argsize, 1) < 0) 3026210502Ssyrinx return (-1); 3027210502Ssyrinx 3028210502Ssyrinx wmr->mroute_status = RowStatus_destroy; 3029210502Ssyrinx 3030210502Ssyrinx return (0); 3031210502Ssyrinx} 3032210502Ssyrinx 3033210502Ssyrinxint 3034210502Ssyrinxwlan_mesh_get_routelist(struct wlan_iface *wif) 3035210502Ssyrinx{ 3036210502Ssyrinx int i, nroutes, val = IEEE80211_MESH_RTCMD_LIST; 3037210502Ssyrinx size_t argsize; 3038210502Ssyrinx struct ieee80211req_mesh_route routes[128]; 3039210502Ssyrinx struct ieee80211req_mesh_route *rt; 3040210502Ssyrinx struct wlan_mesh_route *wmr; 3041210502Ssyrinx 3042210502Ssyrinx argsize = sizeof(routes); 3043210502Ssyrinx if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, routes, 3044210502Ssyrinx &argsize, 0) < 0) /* XXX: ENOMEM? */ 3045210502Ssyrinx return (-1); 3046210502Ssyrinx 3047210502Ssyrinx nroutes = argsize / sizeof(*rt); 3048210502Ssyrinx for (i = 0; i < nroutes; i++) { 3049210502Ssyrinx rt = routes + i; 3050210502Ssyrinx if ((wmr = wlan_mesh_new_route(rt->imr_dest)) == NULL) 3051210502Ssyrinx return (-1); 3052210502Ssyrinx memcpy(&wmr->imroute, rt, sizeof(*rt)); 3053210502Ssyrinx wmr->mroute_status = RowStatus_active; 3054210502Ssyrinx if (wlan_mesh_add_rtentry(wif, wmr) < 0) 3055210502Ssyrinx wlan_mesh_free_route(wmr); 3056210502Ssyrinx } 3057210502Ssyrinx 3058210502Ssyrinx return (0); 3059210502Ssyrinx} 3060210502Ssyrinx 3061210502Ssyrinxint 3062210502Ssyrinxwlan_hwmp_config_get(struct wlan_iface *wif, int which) 3063210502Ssyrinx{ 3064210502Ssyrinx int op, val = 0; 3065210502Ssyrinx size_t argsize = 0; 3066210502Ssyrinx 3067210502Ssyrinx switch (which) { 3068210502Ssyrinx case LEAF_wlanHWMPRootMode: 3069210502Ssyrinx op = IEEE80211_IOC_HWMP_ROOTMODE; 3070210502Ssyrinx break; 3071210502Ssyrinx case LEAF_wlanHWMPMaxHops: 3072210502Ssyrinx op = IEEE80211_IOC_HWMP_MAXHOPS; 3073210502Ssyrinx break; 3074210502Ssyrinx default: 3075210502Ssyrinx return (-1); 3076210502Ssyrinx } 3077210502Ssyrinx 3078210502Ssyrinx if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0) 3079210502Ssyrinx return (-1); 3080210502Ssyrinx 3081210502Ssyrinx switch (which) { 3082210502Ssyrinx case LEAF_wlanHWMPRootMode: 3083210502Ssyrinx switch (val) { 3084210502Ssyrinx case IEEE80211_HWMP_ROOTMODE_NORMAL: 3085210502Ssyrinx wif->hwmp_root_mode = wlanHWMPRootMode_normal; 3086210502Ssyrinx break; 3087210502Ssyrinx case IEEE80211_HWMP_ROOTMODE_PROACTIVE: 3088210502Ssyrinx wif->hwmp_root_mode = wlanHWMPRootMode_proactive; 3089210502Ssyrinx break; 3090210502Ssyrinx case IEEE80211_HWMP_ROOTMODE_RANN: 3091210502Ssyrinx wif->hwmp_root_mode = wlanHWMPRootMode_rann; 3092210502Ssyrinx break; 3093210502Ssyrinx case IEEE80211_HWMP_ROOTMODE_DISABLED: 3094210502Ssyrinx default: 3095210502Ssyrinx wif->hwmp_root_mode = wlanHWMPRootMode_disabled; 3096210502Ssyrinx break; 3097210502Ssyrinx } 3098210502Ssyrinx break; 3099210502Ssyrinx case LEAF_wlanHWMPMaxHops: 3100210502Ssyrinx wif->hwmp_max_hops = val; 3101210502Ssyrinx break; 3102210502Ssyrinx } 3103210502Ssyrinx 3104210502Ssyrinx return (0); 3105210502Ssyrinx} 3106210502Ssyrinx 3107210502Ssyrinxint 3108210502Ssyrinxwlan_hwmp_config_set(struct wlan_iface *wif, int which) 3109210502Ssyrinx{ 3110210502Ssyrinx int op, val = 0; 3111210502Ssyrinx size_t argsize = 0; 3112210502Ssyrinx 3113210502Ssyrinx switch (which) { 3114210502Ssyrinx case LEAF_wlanHWMPRootMode: 3115210502Ssyrinx op = IEEE80211_IOC_HWMP_ROOTMODE; 3116210502Ssyrinx switch (wif->hwmp_root_mode) { 3117210502Ssyrinx case wlanHWMPRootMode_disabled: 3118210502Ssyrinx val = IEEE80211_HWMP_ROOTMODE_DISABLED; 3119210502Ssyrinx break; 3120210502Ssyrinx case wlanHWMPRootMode_normal: 3121210502Ssyrinx val = IEEE80211_HWMP_ROOTMODE_NORMAL; 3122210502Ssyrinx break; 3123210502Ssyrinx case wlanHWMPRootMode_proactive: 3124210502Ssyrinx val = IEEE80211_HWMP_ROOTMODE_PROACTIVE; 3125210502Ssyrinx break; 3126210502Ssyrinx case wlanHWMPRootMode_rann: 3127210502Ssyrinx val = IEEE80211_HWMP_ROOTMODE_RANN; 3128210502Ssyrinx break; 3129210502Ssyrinx default: 3130210502Ssyrinx return (-1); 3131210502Ssyrinx } 3132210502Ssyrinx break; 3133210502Ssyrinx case LEAF_wlanHWMPMaxHops: 3134210502Ssyrinx op = IEEE80211_IOC_HWMP_MAXHOPS; 3135210502Ssyrinx val = wif->hwmp_max_hops; 3136210502Ssyrinx break; 3137210502Ssyrinx default: 3138210502Ssyrinx return (-1); 3139210502Ssyrinx } 3140210502Ssyrinx 3141210502Ssyrinx if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0) 3142210502Ssyrinx return (-1); 3143210502Ssyrinx 3144210502Ssyrinx return (0); 3145210502Ssyrinx} 3146