1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2010 The FreeBSD Foundation 5 * All rights reserved. 6 7 * This software was developed by Shteryana Sotirova Shopova under 8 * sponsorship from the FreeBSD Foundation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $FreeBSD$ 32 */ 33 34 #include <sys/ioctl.h> 35 #include <sys/param.h> 36 #include <sys/module.h> 37 #include <sys/linker.h> 38 #include <sys/socket.h> 39 #include <sys/sysctl.h> 40 41 #include <net/if.h> 42 #include <net/if_dl.h> 43 #include <net/if_media.h> 44 #include <net/if_mib.h> 45 #include <net/if_types.h> 46 #include <net80211/ieee80211.h> 47 #include <net80211/ieee80211_ioctl.h> 48 #include <net80211/ieee80211_regdomain.h> 49 50 #include <errno.h> 51 #include <ifaddrs.h> 52 #include <stdarg.h> 53 #include <stdlib.h> 54 #include <stdio.h> 55 #include <string.h> 56 #include <syslog.h> 57 58 #include <bsnmp/snmpmod.h> 59 #include <bsnmp/snmp_mibII.h> 60 61 #define SNMPTREE_TYPES 62 #include "wlan_tree.h" 63 #include "wlan_snmp.h" 64 65 static int sock = -1; 66 67 static int wlan_ioctl(char *, uint16_t, int *, void *, size_t *, int); 68 static int wlan_kmod_load(const char *); 69 static uint32_t wlan_drivercaps_to_snmp(uint32_t); 70 static uint32_t wlan_cryptocaps_to_snmp(uint32_t); 71 static uint32_t wlan_htcaps_to_snmp(uint32_t); 72 static uint32_t wlan_peerstate_to_snmp(uint32_t); 73 static uint32_t wlan_peercaps_to_snmp(uint32_t ); 74 static uint32_t wlan_channel_flags_to_snmp_phy(uint32_t); 75 static uint32_t wlan_regdomain_to_snmp(int); 76 static uint32_t wlan_snmp_to_scan_flags(int); 77 static int wlan_config_snmp2ioctl(int); 78 static int wlan_snmp_to_regdomain(enum WlanRegDomainCode); 79 static int wlan_config_get_country(struct wlan_iface *); 80 static int wlan_config_set_country(struct wlan_iface *, char *, int); 81 static int wlan_config_get_dchannel(struct wlan_iface *wif); 82 static int wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t); 83 static int wlan_config_get_bssid(struct wlan_iface *); 84 static int wlan_config_set_bssid(struct wlan_iface *, uint8_t *); 85 static void wlan_config_set_snmp_intval(struct wlan_iface *, int, int); 86 static int wlan_config_snmp2value(int, int, int *); 87 static int wlan_config_check(struct wlan_iface *, int); 88 static int wlan_config_get_intval(struct wlan_iface *, int); 89 static int wlan_config_set_intval(struct wlan_iface *, int, int); 90 static int wlan_add_new_scan_result(struct wlan_iface *, 91 const struct ieee80211req_scan_result *, uint8_t *); 92 static int wlan_add_mac_macinfo(struct wlan_iface *, 93 const struct ieee80211req_maclist *); 94 static struct wlan_peer *wlan_add_peerinfo(const struct ieee80211req_sta_info *); 95 96 int 97 wlan_ioctl_init(void) 98 { 99 if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 100 syslog(LOG_ERR, "cannot open socket : %s", strerror(errno)); 101 return (-1); 102 } 103 104 return (0); 105 } 106 /* 107 * Load the needed modules in kernel if not already there. 108 */ 109 enum wlan_kmodules { 110 WLAN_KMOD = 0, 111 WLAN_KMOD_ACL, 112 WLAN_KMOD_WEP, 113 WLAN_KMODS_MAX 114 }; 115 116 static const char *wmod_names[] = { 117 "wlan", 118 "wlan_wlan_acl", 119 "wlan_wep", 120 NULL 121 }; 122 123 static int 124 wlan_kmod_load(const char *modname) 125 { 126 int fileid, modid; 127 struct module_stat mstat; 128 129 mstat.version = sizeof(struct module_stat); 130 for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { 131 for (modid = kldfirstmod(fileid); modid > 0; 132 modid = modfnext(modid)) { 133 if (modstat(modid, &mstat) < 0) 134 continue; 135 if (strcmp(modname, mstat.name) == 0) 136 return (0); 137 } 138 } 139 140 /* Not present - load it. */ 141 if (kldload(modname) < 0) { 142 syslog(LOG_ERR, "failed to load %s kernel module - %s", modname, 143 strerror(errno)); 144 return (-1); 145 } 146 147 return (1); 148 } 149 150 int 151 wlan_kmodules_load(void) 152 { 153 if (wlan_kmod_load(wmod_names[WLAN_KMOD]) < 0) 154 return (-1); 155 156 if (wlan_kmod_load(wmod_names[WLAN_KMOD_ACL]) > 0) 157 syslog(LOG_NOTICE, "SNMP wlan loaded %s module", 158 wmod_names[WLAN_KMOD_ACL]); 159 160 if (wlan_kmod_load(wmod_names[WLAN_KMOD_WEP]) > 0) 161 syslog(LOG_NOTICE, "SNMP wlan loaded %s module", 162 wmod_names[WLAN_KMOD_WEP]); 163 164 return (0); 165 } 166 167 /* XXX: FIXME */ 168 static int 169 wlan_ioctl(char *wif_name, uint16_t req_type, int *val, void *arg, 170 size_t *argsize, int set) 171 { 172 struct ieee80211req ireq; 173 174 memset(&ireq, 0, sizeof(struct ieee80211req)); 175 strlcpy(ireq.i_name, wif_name, IFNAMSIZ); 176 177 ireq.i_type = req_type; 178 ireq.i_val = *val; 179 ireq.i_len = *argsize; 180 ireq.i_data = arg; 181 182 if (ioctl(sock, set ? SIOCS80211 : SIOCG80211, &ireq) < 0) { 183 syslog(LOG_ERR, "iface %s - %s param: ioctl(%d) " 184 "failed: %s", wif_name, set ? "set" : "get", 185 req_type, strerror(errno)); 186 return (-1); 187 } 188 189 *argsize = ireq.i_len; 190 *val = ireq.i_val; 191 192 return (0); 193 } 194 195 int 196 wlan_check_media(char *ifname) 197 { 198 struct ifmediareq ifmr; 199 200 memset(&ifmr, 0, sizeof(struct ifmediareq)); 201 strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); 202 203 if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0 || ifmr.ifm_count == 0) 204 return (0); /* Interface doesn't support SIOCGIFMEDIA. */ 205 206 if ((ifmr.ifm_status & IFM_AVALID) == 0) 207 return (0); 208 209 return (IFM_TYPE(ifmr.ifm_active)); 210 } 211 212 int 213 wlan_get_opmode(struct wlan_iface *wif) 214 { 215 struct ifmediareq ifmr; 216 217 memset(&ifmr, 0, sizeof(struct ifmediareq)); 218 strlcpy(ifmr.ifm_name, wif->wname, sizeof(ifmr.ifm_name)); 219 220 if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0) { 221 if (errno == ENXIO) 222 return (-1); 223 wif->mode = WlanIfaceOperatingModeType_station; 224 return (0); 225 } 226 227 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) { 228 if (ifmr.ifm_current & IFM_FLAG0) 229 wif->mode = WlanIfaceOperatingModeType_adhocDemo; 230 else 231 wif->mode = WlanIfaceOperatingModeType_ibss; 232 } else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 233 wif->mode = WlanIfaceOperatingModeType_hostAp; 234 else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 235 wif->mode = WlanIfaceOperatingModeType_monitor; 236 else if (ifmr.ifm_current & IFM_IEEE80211_MBSS) 237 wif->mode = WlanIfaceOperatingModeType_meshPoint; 238 else if (ifmr.ifm_current & IFM_IEEE80211_WDS) 239 wif->mode = WlanIfaceOperatingModeType_wds; 240 241 return (0); 242 } 243 244 int 245 wlan_config_state(struct wlan_iface *wif, uint8_t set) 246 { 247 int flags; 248 struct ifreq ifr; 249 250 memset(&ifr, 0, sizeof(ifr)); 251 strcpy(ifr.ifr_name, wif->wname); 252 253 if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { 254 syslog(LOG_ERR, "set %s status: ioctl(SIOCGIFFLAGS) " 255 "failed: %s", wif->wname, strerror(errno)); 256 return (-1); 257 } 258 259 if (set == 0) { 260 if ((ifr.ifr_flags & IFF_UP) != 0) 261 wif->state = wlanIfaceState_up; 262 else 263 wif->state = wlanIfaceState_down; 264 return (0); 265 } 266 267 flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); 268 269 if (wif->state == wlanIfaceState_up) 270 flags |= IFF_UP; 271 else 272 flags &= ~IFF_UP; 273 274 ifr.ifr_flags = flags & 0xffff; 275 ifr.ifr_flagshigh = flags >> 16; 276 if (ioctl(sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { 277 syslog(LOG_ERR, "set %s %s: ioctl(SIOCSIFFLAGS) failed: %s", 278 wif->wname, wif->state == wlanIfaceState_up?"up":"down", 279 strerror(errno)); 280 return (-1); 281 } 282 283 return (0); 284 } 285 286 int 287 wlan_get_local_addr(struct wlan_iface *wif) 288 { 289 int len; 290 char ifname[IFNAMSIZ]; 291 struct ifaddrs *ifap, *ifa; 292 struct sockaddr_dl sdl; 293 294 if (getifaddrs(&ifap) != 0) { 295 syslog(LOG_ERR, "wlan get mac: getifaddrs() failed - %s", 296 strerror(errno)); 297 return (-1); 298 } 299 300 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 301 if (ifa->ifa_addr->sa_family != AF_LINK) 302 continue; 303 memcpy(&sdl, ifa->ifa_addr, sizeof(struct sockaddr_dl)); 304 if (sdl.sdl_alen > IEEE80211_ADDR_LEN) 305 continue; 306 if ((len = sdl.sdl_nlen) >= IFNAMSIZ) 307 len = IFNAMSIZ - 1; 308 memcpy(ifname, sdl.sdl_data, len); 309 ifname[len] = '\0'; 310 if (strcmp(wif->wname, ifname) == 0) 311 break; 312 } 313 314 freeifaddrs(ifap); 315 return (0); 316 } 317 318 int 319 wlan_get_parent(struct wlan_iface *wif __unused) 320 { 321 /* XXX: There's no way to fetch this from the kernel. */ 322 return (0); 323 } 324 325 /* XXX */ 326 #define IEEE80211_C_STA 0x00000001 /* CAPABILITY: STA available */ 327 #define IEEE80211_C_8023ENCAP 0x00000002 /* CAPABILITY: 802.3 encap */ 328 #define IEEE80211_C_FF 0x00000040 /* CAPABILITY: ATH FF avail */ 329 #define IEEE80211_C_TURBOP 0x00000080 /* CAPABILITY: ATH Turbo avail*/ 330 #define IEEE80211_C_IBSS 0x00000100 /* CAPABILITY: IBSS available */ 331 #define IEEE80211_C_PMGT 0x00000200 /* CAPABILITY: Power mgmt */ 332 #define IEEE80211_C_HOSTAP 0x00000400 /* CAPABILITY: HOSTAP avail */ 333 #define IEEE80211_C_AHDEMO 0x00000800 /* CAPABILITY: Old Adhoc Demo */ 334 #define IEEE80211_C_SWRETRY 0x00001000 /* CAPABILITY: sw tx retry */ 335 #define IEEE80211_C_TXPMGT 0x00002000 /* CAPABILITY: tx power mgmt */ 336 #define IEEE80211_C_SHSLOT 0x00004000 /* CAPABILITY: short slottime */ 337 #define IEEE80211_C_SHPREAMBLE 0x00008000 /* CAPABILITY: short preamble */ 338 #define IEEE80211_C_MONITOR 0x00010000 /* CAPABILITY: monitor mode */ 339 #define IEEE80211_C_DFS 0x00020000 /* CAPABILITY: DFS/radar avail*/ 340 #define IEEE80211_C_MBSS 0x00040000 /* CAPABILITY: MBSS available */ 341 /* 0x7c0000 available */ 342 #define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */ 343 #define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */ 344 #define IEEE80211_C_WPA 0x01800000 /* CAPABILITY: WPA1+WPA2 avail*/ 345 #define IEEE80211_C_BURST 0x02000000 /* CAPABILITY: frame bursting */ 346 #define IEEE80211_C_WME 0x04000000 /* CAPABILITY: WME avail */ 347 #define IEEE80211_C_WDS 0x08000000 /* CAPABILITY: 4-addr support */ 348 /* 0x10000000 reserved */ 349 #define IEEE80211_C_BGSCAN 0x20000000 /* CAPABILITY: bg scanning */ 350 #define IEEE80211_C_TXFRAG 0x40000000 /* CAPABILITY: tx fragments */ 351 #define IEEE80211_C_TDMA 0x80000000 /* CAPABILITY: TDMA avail */ 352 353 static uint32_t 354 wlan_drivercaps_to_snmp(uint32_t dcaps) 355 { 356 uint32_t scaps = 0; 357 358 if ((dcaps & IEEE80211_C_STA) != 0) 359 scaps |= (0x1 << WlanDriverCaps_station); 360 if ((dcaps & IEEE80211_C_8023ENCAP) != 0) 361 scaps |= (0x1 << WlanDriverCaps_ieee8023encap); 362 if ((dcaps & IEEE80211_C_FF) != 0) 363 scaps |= (0x1 << WlanDriverCaps_athFastFrames); 364 if ((dcaps & IEEE80211_C_TURBOP) != 0) 365 scaps |= (0x1 << WlanDriverCaps_athTurbo); 366 if ((dcaps & IEEE80211_C_IBSS) != 0) 367 scaps |= (0x1 << WlanDriverCaps_ibss); 368 if ((dcaps & IEEE80211_C_PMGT) != 0) 369 scaps |= (0x1 << WlanDriverCaps_pmgt); 370 if ((dcaps & IEEE80211_C_HOSTAP) != 0) 371 scaps |= (0x1 << WlanDriverCaps_hostAp); 372 if ((dcaps & IEEE80211_C_AHDEMO) != 0) 373 scaps |= (0x1 << WlanDriverCaps_ahDemo); 374 if ((dcaps & IEEE80211_C_SWRETRY) != 0) 375 scaps |= (0x1 << WlanDriverCaps_swRetry); 376 if ((dcaps & IEEE80211_C_TXPMGT) != 0) 377 scaps |= (0x1 << WlanDriverCaps_txPmgt); 378 if ((dcaps & IEEE80211_C_SHSLOT) != 0) 379 scaps |= (0x1 << WlanDriverCaps_shortSlot); 380 if ((dcaps & IEEE80211_C_SHPREAMBLE) != 0) 381 scaps |= (0x1 << WlanDriverCaps_shortPreamble); 382 if ((dcaps & IEEE80211_C_MONITOR) != 0) 383 scaps |= (0x1 << WlanDriverCaps_monitor); 384 if ((dcaps & IEEE80211_C_DFS) != 0) 385 scaps |= (0x1 << WlanDriverCaps_dfs); 386 if ((dcaps & IEEE80211_C_MBSS) != 0) 387 scaps |= (0x1 << WlanDriverCaps_mbss); 388 if ((dcaps & IEEE80211_C_WPA1) != 0) 389 scaps |= (0x1 << WlanDriverCaps_wpa1); 390 if ((dcaps & IEEE80211_C_WPA2) != 0) 391 scaps |= (0x1 << WlanDriverCaps_wpa2); 392 if ((dcaps & IEEE80211_C_BURST) != 0) 393 scaps |= (0x1 << WlanDriverCaps_burst); 394 if ((dcaps & IEEE80211_C_WME) != 0) 395 scaps |= (0x1 << WlanDriverCaps_wme); 396 if ((dcaps & IEEE80211_C_WDS) != 0) 397 scaps |= (0x1 << WlanDriverCaps_wds); 398 if ((dcaps & IEEE80211_C_BGSCAN) != 0) 399 scaps |= (0x1 << WlanDriverCaps_bgScan); 400 if ((dcaps & IEEE80211_C_TXFRAG) != 0) 401 scaps |= (0x1 << WlanDriverCaps_txFrag); 402 if ((dcaps & IEEE80211_C_TDMA) != 0) 403 scaps |= (0x1 << WlanDriverCaps_tdma); 404 405 return (scaps); 406 } 407 408 static uint32_t 409 wlan_cryptocaps_to_snmp(uint32_t ccaps) 410 { 411 uint32_t scaps = 0; 412 413 #if NOT_YET 414 if ((ccaps & IEEE80211_CRYPTO_WEP) != 0) 415 scaps |= (0x1 << wlanCryptoCaps_wep); 416 if ((ccaps & IEEE80211_CRYPTO_TKIP) != 0) 417 scaps |= (0x1 << wlanCryptoCaps_tkip); 418 if ((ccaps & IEEE80211_CRYPTO_AES_OCB) != 0) 419 scaps |= (0x1 << wlanCryptoCaps_aes); 420 if ((ccaps & IEEE80211_CRYPTO_AES_CCM) != 0) 421 scaps |= (0x1 << wlanCryptoCaps_aesCcm); 422 if ((ccaps & IEEE80211_CRYPTO_TKIPMIC) != 0) 423 scaps |= (0x1 << wlanCryptoCaps_tkipMic); 424 if ((ccaps & IEEE80211_CRYPTO_CKIP) != 0) 425 scaps |= (0x1 << wlanCryptoCaps_ckip); 426 #else /* !NOT_YET */ 427 scaps = ccaps; 428 #endif 429 return (scaps); 430 } 431 432 #define IEEE80211_HTC_AMPDU 0x00010000 /* CAPABILITY: A-MPDU tx */ 433 #define IEEE80211_HTC_AMSDU 0x00020000 /* CAPABILITY: A-MSDU tx */ 434 /* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */ 435 #define IEEE80211_HTC_HT 0x00040000 /* CAPABILITY: HT operation */ 436 #define IEEE80211_HTC_SMPS 0x00080000 /* CAPABILITY: MIMO power save*/ 437 #define IEEE80211_HTC_RIFS 0x00100000 /* CAPABILITY: RIFS support */ 438 439 static uint32_t 440 wlan_htcaps_to_snmp(uint32_t hcaps) 441 { 442 uint32_t scaps = 0; 443 444 if ((hcaps & IEEE80211_HTCAP_LDPC) != 0) 445 scaps |= (0x1 << WlanHTCaps_ldpc); 446 if ((hcaps & IEEE80211_HTCAP_CHWIDTH40) != 0) 447 scaps |= (0x1 << WlanHTCaps_chwidth40); 448 if ((hcaps & IEEE80211_HTCAP_GREENFIELD) != 0) 449 scaps |= (0x1 << WlanHTCaps_greenField); 450 if ((hcaps & IEEE80211_HTCAP_SHORTGI20) != 0) 451 scaps |= (0x1 << WlanHTCaps_shortGi20); 452 if ((hcaps & IEEE80211_HTCAP_SHORTGI40) != 0) 453 scaps |= (0x1 << WlanHTCaps_shortGi40); 454 if ((hcaps & IEEE80211_HTCAP_TXSTBC) != 0) 455 scaps |= (0x1 << WlanHTCaps_txStbc); 456 if ((hcaps & IEEE80211_HTCAP_DELBA) != 0) 457 scaps |= (0x1 << WlanHTCaps_delba); 458 if ((hcaps & IEEE80211_HTCAP_MAXAMSDU_7935) != 0) 459 scaps |= (0x1 << WlanHTCaps_amsdu7935); 460 if ((hcaps & IEEE80211_HTCAP_DSSSCCK40) != 0) 461 scaps |= (0x1 << WlanHTCaps_dssscck40); 462 if ((hcaps & IEEE80211_HTCAP_PSMP) != 0) 463 scaps |= (0x1 << WlanHTCaps_psmp); 464 if ((hcaps & IEEE80211_HTCAP_40INTOLERANT) != 0) 465 scaps |= (0x1 << WlanHTCaps_fortyMHzIntolerant); 466 if ((hcaps & IEEE80211_HTCAP_LSIGTXOPPROT) != 0) 467 scaps |= (0x1 << WlanHTCaps_lsigTxOpProt); 468 if ((hcaps & IEEE80211_HTC_AMPDU) != 0) 469 scaps |= (0x1 << WlanHTCaps_htcAmpdu); 470 if ((hcaps & IEEE80211_HTC_AMSDU) != 0) 471 scaps |= (0x1 << WlanHTCaps_htcAmsdu); 472 if ((hcaps & IEEE80211_HTC_HT) != 0) 473 scaps |= (0x1 << WlanHTCaps_htcHt); 474 if ((hcaps & IEEE80211_HTC_SMPS) != 0) 475 scaps |= (0x1 << WlanHTCaps_htcSmps); 476 if ((hcaps & IEEE80211_HTC_RIFS) != 0) 477 scaps |= (0x1 << WlanHTCaps_htcRifs); 478 479 return (scaps); 480 } 481 482 /* XXX: Not here? */ 483 #define WLAN_SET_TDMA_OPMODE(w) do { \ 484 if ((w)->mode == WlanIfaceOperatingModeType_adhocDemo && \ 485 ((w)->drivercaps & WlanDriverCaps_tdma) != 0) \ 486 (w)->mode = WlanIfaceOperatingModeType_tdma; \ 487 } while (0) 488 int 489 wlan_get_driver_caps(struct wlan_iface *wif) 490 { 491 int val = 0; 492 size_t argsize; 493 struct ieee80211_devcaps_req dc; 494 495 memset(&dc, 0, sizeof(struct ieee80211_devcaps_req)); 496 argsize = sizeof(struct ieee80211_devcaps_req); 497 498 if (wlan_ioctl(wif->wname, IEEE80211_IOC_DEVCAPS, &val, &dc, 499 &argsize, 0) < 0) 500 return (-1); 501 502 wif->drivercaps = wlan_drivercaps_to_snmp(dc.dc_drivercaps); 503 wif->cryptocaps = wlan_cryptocaps_to_snmp(dc.dc_cryptocaps); 504 wif->htcaps = wlan_htcaps_to_snmp(dc.dc_htcaps); 505 506 WLAN_SET_TDMA_OPMODE(wif); 507 508 argsize = dc.dc_chaninfo.ic_nchans * sizeof(struct ieee80211_channel); 509 wif->chanlist = (struct ieee80211_channel *)malloc(argsize); 510 if (wif->chanlist == NULL) 511 return (0); 512 513 memcpy(wif->chanlist, dc.dc_chaninfo.ic_chans, argsize); 514 wif->nchannels = dc.dc_chaninfo.ic_nchans; 515 516 return (0); 517 } 518 519 uint8_t 520 wlan_channel_state_to_snmp(uint8_t cstate) 521 { 522 uint8_t cs = 0; 523 524 if ((cstate & IEEE80211_CHANSTATE_RADAR) != 0) 525 cs |= (0x1 << WlanIfaceChannelStateType_radar); 526 if ((cstate & IEEE80211_CHANSTATE_CACDONE) != 0) 527 cs |= (0x1 << WlanIfaceChannelStateType_cacDone); 528 if ((cstate & IEEE80211_CHANSTATE_CWINT) != 0) 529 cs |= (0x1 << WlanIfaceChannelStateType_interferenceDetected); 530 if ((cstate & IEEE80211_CHANSTATE_NORADAR) != 0) 531 cs |= (0x1 << WlanIfaceChannelStateType_radarClear); 532 533 return (cs); 534 } 535 536 uint32_t 537 wlan_channel_flags_to_snmp(uint32_t cflags) 538 { 539 uint32_t cf = 0; 540 541 if ((cflags & IEEE80211_CHAN_TURBO) != 0) 542 cf |= (0x1 << WlanIfaceChannelFlagsType_turbo); 543 if ((cflags & IEEE80211_CHAN_CCK) != 0) 544 cf |= (0x1 << WlanIfaceChannelFlagsType_cck); 545 if ((cflags & IEEE80211_CHAN_OFDM) != 0) 546 cf |= (0x1 << WlanIfaceChannelFlagsType_ofdm); 547 if ((cflags & IEEE80211_CHAN_2GHZ) != 0) 548 cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum2Ghz); 549 if ((cflags & IEEE80211_CHAN_5GHZ) != 0) 550 cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum5Ghz); 551 if ((cflags & IEEE80211_CHAN_PASSIVE) != 0) 552 cf |= (0x1 << WlanIfaceChannelFlagsType_passiveScan); 553 if ((cflags & IEEE80211_CHAN_DYN) != 0) 554 cf |= (0x1 << WlanIfaceChannelFlagsType_dynamicCckOfdm); 555 if ((cflags & IEEE80211_CHAN_GFSK) != 0) 556 cf |= (0x1 << WlanIfaceChannelFlagsType_gfsk); 557 if ((cflags & IEEE80211_CHAN_GSM) != 0) 558 cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum900Mhz); 559 if ((cflags & IEEE80211_CHAN_STURBO) != 0) 560 cf |= (0x1 << WlanIfaceChannelFlagsType_dot11aStaticTurbo); 561 if ((cflags & IEEE80211_CHAN_HALF) != 0) 562 cf |= (0x1 << WlanIfaceChannelFlagsType_halfRate); 563 if ((cflags & IEEE80211_CHAN_QUARTER) != 0) 564 cf |= (0x1 << WlanIfaceChannelFlagsType_quarterRate); 565 if ((cflags & IEEE80211_CHAN_HT20) != 0) 566 cf |= (0x1 << WlanIfaceChannelFlagsType_ht20); 567 if ((cflags & IEEE80211_CHAN_HT40U) != 0) 568 cf |= (0x1 << WlanIfaceChannelFlagsType_ht40u); 569 if ((cflags & IEEE80211_CHAN_HT40D) != 0) 570 cf |= (0x1 << WlanIfaceChannelFlagsType_ht40d); 571 if ((cflags & IEEE80211_CHAN_DFS) != 0) 572 cf |= (0x1 << WlanIfaceChannelFlagsType_dfs); 573 if ((cflags & IEEE80211_CHAN_4MSXMIT) != 0) 574 cf |= (0x1 << WlanIfaceChannelFlagsType_xmit4ms); 575 if ((cflags & IEEE80211_CHAN_NOADHOC) != 0) 576 cf |= (0x1 << WlanIfaceChannelFlagsType_noAdhoc); 577 if ((cflags & IEEE80211_CHAN_NOHOSTAP) != 0) 578 cf |= (0x1 << WlanIfaceChannelFlagsType_noHostAp); 579 if ((cflags & IEEE80211_CHAN_11D) != 0) 580 cf |= (0x1 << WlanIfaceChannelFlagsType_dot11d); 581 582 return (cf); 583 } 584 585 /* XXX: */ 586 #define WLAN_SNMP_MAX_CHANS 256 587 int 588 wlan_get_channel_list(struct wlan_iface *wif) 589 { 590 int val = 0; 591 uint32_t i, nchans; 592 size_t argsize; 593 struct ieee80211req_chaninfo *chaninfo; 594 struct ieee80211req_chanlist active; 595 const struct ieee80211_channel *c; 596 597 argsize = sizeof(struct ieee80211req_chaninfo) + 598 sizeof(struct ieee80211_channel) * WLAN_SNMP_MAX_CHANS; 599 chaninfo = (struct ieee80211req_chaninfo *)malloc(argsize); 600 if (chaninfo == NULL) 601 return (-1); 602 603 if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANINFO, &val, chaninfo, 604 &argsize, 0) < 0) 605 return (-1); 606 607 argsize = sizeof(active); 608 if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANLIST, &val, &active, 609 &argsize, 0) < 0) 610 goto error; 611 612 for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) { 613 c = &chaninfo->ic_chans[i]; 614 if (!isset(active.ic_channels, c->ic_ieee)) 615 continue; 616 nchans++; 617 } 618 wif->chanlist = (struct ieee80211_channel *)reallocf(wif->chanlist, 619 nchans * sizeof(*c)); 620 if (wif->chanlist == NULL) 621 goto error; 622 wif->nchannels = nchans; 623 for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) { 624 c = &chaninfo->ic_chans[i]; 625 if (!isset(active.ic_channels, c->ic_ieee)) 626 continue; 627 memcpy(wif->chanlist + nchans, c, sizeof (*c)); 628 nchans++; 629 } 630 631 free(chaninfo); 632 return (0); 633 error: 634 wif->nchannels = 0; 635 free(chaninfo); 636 return (-1); 637 } 638 639 static enum WlanIfPhyMode 640 wlan_channel_flags_to_snmp_phy(uint32_t cflags) 641 { 642 /* XXX: recheck */ 643 if ((cflags & IEEE80211_CHAN_A) != 0) 644 return (WlanIfPhyMode_dot11a); 645 if ((cflags & IEEE80211_CHAN_B) != 0) 646 return (WlanIfPhyMode_dot11b); 647 if ((cflags & IEEE80211_CHAN_G) != 0 || 648 (cflags & IEEE80211_CHAN_PUREG) != 0) 649 return (WlanIfPhyMode_dot11g); 650 if ((cflags & IEEE80211_CHAN_FHSS) != 0) 651 return (WlanIfPhyMode_fh); 652 if ((cflags & IEEE80211_CHAN_TURBO) != 0 && 653 (cflags & IEEE80211_CHAN_A) != 0) 654 return (WlanIfPhyMode_turboA); 655 if ((cflags & IEEE80211_CHAN_TURBO) != 0 && 656 (cflags & IEEE80211_CHAN_G) != 0) 657 return (WlanIfPhyMode_turboG); 658 if ((cflags & IEEE80211_CHAN_STURBO) != 0) 659 return (WlanIfPhyMode_sturboA); 660 if ((cflags & IEEE80211_CHAN_HALF) != 0) 661 return (WlanIfPhyMode_ofdmHalf); 662 if ((cflags & IEEE80211_CHAN_QUARTER) != 0) 663 return (WlanIfPhyMode_ofdmQuarter); 664 665 return (WlanIfPhyMode_auto); 666 } 667 668 int 669 wlan_get_roam_params(struct wlan_iface *wif) 670 { 671 int val = 0; 672 size_t argsize; 673 674 argsize = sizeof(struct ieee80211_roamparams_req); 675 if (wlan_ioctl(wif->wname, IEEE80211_IOC_ROAM, &val, 676 &wif->roamparams, &argsize, 0) < 0) 677 return (-1); 678 679 return (0); 680 } 681 682 int 683 wlan_get_tx_params(struct wlan_iface *wif) 684 { 685 int val = 0; 686 size_t argsize; 687 688 /* 689 * XXX: Reset IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA 690 * and IEEE80211_MODE_11NG modes. 691 */ 692 argsize = sizeof(struct ieee80211_txparams_req); 693 if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val, 694 &wif->txparams, &argsize, 0) < 0) 695 return (-1); 696 697 return (0); 698 } 699 700 int 701 wlan_set_tx_params(struct wlan_iface *wif, int32_t pmode __unused) 702 { 703 int val = 0; 704 size_t argsize; 705 706 /* 707 * XXX: Set IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA 708 * and IEEE80211_MODE_11NG modes. 709 */ 710 argsize = sizeof(struct ieee80211_txparams_req); 711 if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val, 712 &wif->txparams, &argsize, 1) < 0) 713 return (-1); 714 715 return (0); 716 } 717 718 int 719 wlan_clone_create(struct wlan_iface *wif) 720 { 721 struct ifreq ifr; 722 struct ieee80211_clone_params wcp; 723 static const uint8_t zerobssid[IEEE80211_ADDR_LEN]; 724 725 memset(&wcp, 0, sizeof(wcp)); 726 memset(&ifr, 0, sizeof(ifr)); 727 728 /* Sanity checks. */ 729 if (wif == NULL || wif->pname[0] == '\0' || wif->mode > WLAN_IFMODE_MAX) 730 return (SNMP_ERR_INCONS_VALUE); 731 732 if (wif->mode == WlanIfaceOperatingModeType_wds && 733 memcmp(wif->dbssid, zerobssid, IEEE80211_ADDR_LEN) == 0) 734 return (SNMP_ERR_INCONS_VALUE); 735 736 strlcpy(wcp.icp_parent, wif->pname, IFNAMSIZ); 737 if ((wif->flags & WlanIfaceFlagsType_uniqueBssid) != 0) 738 wcp.icp_flags |= IEEE80211_CLONE_BSSID; 739 if ((wif->flags & WlanIfaceFlagsType_noBeacons) != 0) 740 wcp.icp_flags |= IEEE80211_CLONE_NOBEACONS; 741 if (wif->mode == WlanIfaceOperatingModeType_wds && 742 (wif->flags & WlanIfaceFlagsType_wdsLegacy) != 0) 743 wcp.icp_flags |= IEEE80211_CLONE_WDSLEGACY; 744 745 switch (wif->mode) { 746 case WlanIfaceOperatingModeType_ibss: 747 wcp.icp_opmode = IEEE80211_M_IBSS; 748 break; 749 case WlanIfaceOperatingModeType_station: 750 wcp.icp_opmode = IEEE80211_M_STA; 751 break; 752 case WlanIfaceOperatingModeType_wds: 753 wcp.icp_opmode = IEEE80211_M_WDS; 754 break; 755 case WlanIfaceOperatingModeType_adhocDemo: 756 wcp.icp_opmode = IEEE80211_M_AHDEMO; 757 break; 758 case WlanIfaceOperatingModeType_hostAp: 759 wcp.icp_opmode = IEEE80211_M_HOSTAP; 760 break; 761 case WlanIfaceOperatingModeType_monitor: 762 wcp.icp_opmode = IEEE80211_M_MONITOR; 763 break; 764 case WlanIfaceOperatingModeType_meshPoint: 765 wcp.icp_opmode = IEEE80211_M_MBSS; 766 break; 767 case WlanIfaceOperatingModeType_tdma: 768 wcp.icp_opmode = IEEE80211_M_AHDEMO; 769 wcp.icp_flags |= IEEE80211_CLONE_TDMA; 770 break; 771 } 772 773 memcpy(wcp.icp_bssid, wif->dbssid, IEEE80211_ADDR_LEN); 774 if (memcmp(wif->dlmac, zerobssid, IEEE80211_ADDR_LEN) != 0) { 775 memcpy(wcp.icp_macaddr, wif->dlmac, IEEE80211_ADDR_LEN); 776 wcp.icp_flags |= IEEE80211_CLONE_MACADDR; 777 } 778 779 strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ); 780 ifr.ifr_data = (caddr_t) &wcp; 781 782 if (ioctl(sock, SIOCIFCREATE2, (caddr_t) &ifr) < 0) { 783 syslog(LOG_ERR, "wlan clone create: ioctl(SIOCIFCREATE2) " 784 "failed: %s", strerror(errno)); 785 return (SNMP_ERR_GENERR); 786 } 787 788 return (SNMP_ERR_NOERROR); 789 } 790 791 int 792 wlan_clone_destroy(struct wlan_iface *wif) 793 { 794 struct ifreq ifr; 795 796 if (wif == NULL) 797 return (SNMP_ERR_INCONS_VALUE); 798 799 memset(&ifr, 0, sizeof(ifr)); 800 strcpy(ifr.ifr_name, wif->wname); 801 802 if (ioctl(sock, SIOCIFDESTROY, &ifr) < 0) { 803 syslog(LOG_ERR, "wlan clone destroy: ioctl(SIOCIFDESTROY) " 804 "failed: %s", strerror(errno)); 805 return (SNMP_ERR_GENERR); 806 } 807 808 return (SNMP_ERR_NOERROR); 809 } 810 811 static int 812 wlan_config_snmp2ioctl(int which) 813 { 814 int op; 815 816 switch (which) { 817 case LEAF_wlanIfacePacketBurst: 818 op = IEEE80211_IOC_BURST; 819 break; 820 case LEAF_wlanIfaceCountryCode: 821 op = IEEE80211_IOC_REGDOMAIN; 822 break; 823 case LEAF_wlanIfaceRegDomain: 824 op = IEEE80211_IOC_REGDOMAIN; 825 break; 826 case LEAF_wlanIfaceDesiredSsid: 827 op = IEEE80211_IOC_SSID; 828 break; 829 case LEAF_wlanIfaceDesiredChannel: 830 op = IEEE80211_IOC_CURCHAN; 831 break; 832 case LEAF_wlanIfaceDynamicFreqSelection: 833 op = IEEE80211_IOC_DFS; 834 break; 835 case LEAF_wlanIfaceFastFrames: 836 op = IEEE80211_IOC_FF; 837 break; 838 case LEAF_wlanIfaceDturbo: 839 op = IEEE80211_IOC_TURBOP; 840 break; 841 case LEAF_wlanIfaceTxPower: 842 op = IEEE80211_IOC_TXPOWER; 843 break; 844 case LEAF_wlanIfaceFragmentThreshold: 845 op = IEEE80211_IOC_FRAGTHRESHOLD; 846 break; 847 case LEAF_wlanIfaceRTSThreshold: 848 op = IEEE80211_IOC_RTSTHRESHOLD; 849 break; 850 case LEAF_wlanIfaceWlanPrivacySubscribe: 851 op = IEEE80211_IOC_WPS; 852 break; 853 case LEAF_wlanIfaceBgScan: 854 op = IEEE80211_IOC_BGSCAN; 855 break; 856 case LEAF_wlanIfaceBgScanIdle: 857 op = IEEE80211_IOC_BGSCAN_IDLE; 858 break; 859 case LEAF_wlanIfaceBgScanInterval: 860 op = IEEE80211_IOC_BGSCAN_INTERVAL; 861 break; 862 case LEAF_wlanIfaceBeaconMissedThreshold: 863 op = IEEE80211_IOC_BMISSTHRESHOLD; 864 break; 865 case LEAF_wlanIfaceDesiredBssid: 866 op = IEEE80211_IOC_BSSID; 867 break; 868 case LEAF_wlanIfaceRoamingMode: 869 op = IEEE80211_IOC_ROAMING; 870 break; 871 case LEAF_wlanIfaceDot11d: 872 op = IEEE80211_IOC_DOTD; 873 break; 874 case LEAF_wlanIfaceDot11h: 875 op = IEEE80211_IOC_DOTH; 876 break; 877 case LEAF_wlanIfaceDynamicWds: 878 op = IEEE80211_IOC_DWDS; 879 break; 880 case LEAF_wlanIfacePowerSave: 881 op = IEEE80211_IOC_POWERSAVE; 882 break; 883 case LEAF_wlanIfaceApBridge: 884 op = IEEE80211_IOC_APBRIDGE; 885 break; 886 case LEAF_wlanIfaceBeaconInterval: 887 op = IEEE80211_IOC_BEACON_INTERVAL; 888 break; 889 case LEAF_wlanIfaceDtimPeriod: 890 op = IEEE80211_IOC_DTIM_PERIOD; 891 break; 892 case LEAF_wlanIfaceHideSsid: 893 op = IEEE80211_IOC_HIDESSID; 894 break; 895 case LEAF_wlanIfaceInactivityProccess: 896 op = IEEE80211_IOC_INACTIVITY; 897 break; 898 case LEAF_wlanIfaceDot11gProtMode: 899 op = IEEE80211_IOC_PROTMODE; 900 break; 901 case LEAF_wlanIfaceDot11gPureMode: 902 op = IEEE80211_IOC_PUREG; 903 break; 904 case LEAF_wlanIfaceDot11nPureMode: 905 op = IEEE80211_IOC_PUREN; 906 break; 907 case LEAF_wlanIfaceDot11nAmpdu: 908 op = IEEE80211_IOC_AMPDU; 909 break; 910 case LEAF_wlanIfaceDot11nAmpduDensity: 911 op = IEEE80211_IOC_AMPDU_DENSITY; 912 break; 913 case LEAF_wlanIfaceDot11nAmpduLimit: 914 op = IEEE80211_IOC_AMPDU_LIMIT; 915 break; 916 case LEAF_wlanIfaceDot11nAmsdu: 917 op = IEEE80211_IOC_AMSDU; 918 break; 919 case LEAF_wlanIfaceDot11nAmsduLimit: 920 op = IEEE80211_IOC_AMSDU_LIMIT; 921 break; 922 case LEAF_wlanIfaceDot11nHighThroughput: 923 op = IEEE80211_IOC_HTCONF; 924 break; 925 case LEAF_wlanIfaceDot11nHTCompatible: 926 op = IEEE80211_IOC_HTCOMPAT; 927 break; 928 case LEAF_wlanIfaceDot11nHTProtMode: 929 op = IEEE80211_IOC_HTPROTMODE; 930 break; 931 case LEAF_wlanIfaceDot11nRIFS: 932 op = IEEE80211_IOC_RIFS; 933 break; 934 case LEAF_wlanIfaceDot11nShortGI: 935 op = IEEE80211_IOC_SHORTGI; 936 break; 937 case LEAF_wlanIfaceDot11nSMPSMode: 938 op = IEEE80211_IOC_SMPS; 939 break; 940 case LEAF_wlanIfaceTdmaSlot: 941 op = IEEE80211_IOC_TDMA_SLOT; 942 break; 943 case LEAF_wlanIfaceTdmaSlotCount: 944 op = IEEE80211_IOC_TDMA_SLOTCNT; 945 break; 946 case LEAF_wlanIfaceTdmaSlotLength: 947 op = IEEE80211_IOC_TDMA_SLOTLEN; 948 break; 949 case LEAF_wlanIfaceTdmaBeaconInterval: 950 op = IEEE80211_IOC_TDMA_BINTERVAL; 951 break; 952 default: 953 op = -1; 954 } 955 956 return (op); 957 } 958 959 static enum WlanRegDomainCode 960 wlan_regdomain_to_snmp(int which) 961 { 962 enum WlanRegDomainCode reg_domain; 963 964 switch (which) { 965 case SKU_FCC: 966 reg_domain = WlanRegDomainCode_fcc; 967 break; 968 case SKU_CA: 969 reg_domain = WlanRegDomainCode_ca; 970 break; 971 case SKU_ETSI: 972 reg_domain = WlanRegDomainCode_etsi; 973 break; 974 case SKU_ETSI2: 975 reg_domain = WlanRegDomainCode_etsi2; 976 break; 977 case SKU_ETSI3: 978 reg_domain = WlanRegDomainCode_etsi3; 979 break; 980 case SKU_FCC3: 981 reg_domain = WlanRegDomainCode_fcc3; 982 break; 983 case SKU_JAPAN: 984 reg_domain = WlanRegDomainCode_japan; 985 break; 986 case SKU_KOREA: 987 reg_domain = WlanRegDomainCode_korea; 988 break; 989 case SKU_APAC: 990 reg_domain = WlanRegDomainCode_apac; 991 break; 992 case SKU_APAC2: 993 reg_domain = WlanRegDomainCode_apac2; 994 break; 995 case SKU_APAC3: 996 reg_domain = WlanRegDomainCode_apac3; 997 break; 998 case SKU_ROW: 999 reg_domain = WlanRegDomainCode_row; 1000 break; 1001 case SKU_NONE: 1002 reg_domain = WlanRegDomainCode_none; 1003 break; 1004 case SKU_DEBUG: 1005 reg_domain = WlanRegDomainCode_debug; 1006 break; 1007 case SKU_SR9: 1008 reg_domain = WlanRegDomainCode_sr9; 1009 break; 1010 case SKU_XR9: 1011 reg_domain = WlanRegDomainCode_xr9; 1012 break; 1013 case SKU_GZ901: 1014 reg_domain = WlanRegDomainCode_gz901; 1015 break; 1016 case 0: 1017 reg_domain = WlanRegDomainCode_none; 1018 break; 1019 default: 1020 syslog(LOG_ERR, "unknown regdomain (0x%x) ", which); 1021 reg_domain = WlanRegDomainCode_none; 1022 break; 1023 } 1024 1025 return (reg_domain); 1026 } 1027 1028 static int 1029 wlan_snmp_to_regdomain(enum WlanRegDomainCode regdomain) 1030 { 1031 int which; 1032 1033 switch (regdomain) { 1034 case WlanRegDomainCode_fcc: 1035 which = SKU_FCC; 1036 break; 1037 case WlanRegDomainCode_ca: 1038 which = SKU_CA; 1039 break; 1040 case WlanRegDomainCode_etsi: 1041 which = SKU_ETSI; 1042 break; 1043 case WlanRegDomainCode_etsi2: 1044 which = SKU_ETSI2; 1045 break; 1046 case WlanRegDomainCode_etsi3: 1047 which = SKU_ETSI3; 1048 break; 1049 case WlanRegDomainCode_fcc3: 1050 which = SKU_FCC3; 1051 break; 1052 case WlanRegDomainCode_japan: 1053 which = SKU_JAPAN; 1054 break; 1055 case WlanRegDomainCode_korea: 1056 which = SKU_KOREA; 1057 break; 1058 case WlanRegDomainCode_apac: 1059 which = SKU_APAC; 1060 break; 1061 case WlanRegDomainCode_apac2: 1062 which = SKU_APAC2; 1063 break; 1064 case WlanRegDomainCode_apac3: 1065 which = SKU_APAC3; 1066 break; 1067 case WlanRegDomainCode_row: 1068 which = SKU_ROW; 1069 break; 1070 case WlanRegDomainCode_none: 1071 which = SKU_NONE; 1072 break; 1073 case WlanRegDomainCode_debug: 1074 which = SKU_DEBUG; 1075 break; 1076 case WlanRegDomainCode_sr9: 1077 which = SKU_SR9; 1078 break; 1079 case WlanRegDomainCode_xr9: 1080 which = SKU_XR9; 1081 break; 1082 case WlanRegDomainCode_gz901: 1083 which = SKU_GZ901; 1084 break; 1085 default: 1086 syslog(LOG_ERR, "unknown snmp regdomain (0x%x) ", regdomain); 1087 which = SKU_NONE; 1088 break; 1089 } 1090 1091 return (which); 1092 } 1093 1094 static int 1095 wlan_config_get_country(struct wlan_iface *wif) 1096 { 1097 int val = 0; 1098 size_t argsize; 1099 struct ieee80211_regdomain regdomain; 1100 1101 memset(®domain, 0, sizeof(regdomain)); 1102 argsize = sizeof(regdomain); 1103 1104 if (wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, ®domain, 1105 &argsize, 0) < 0) 1106 return (-1); 1107 1108 wif->reg_domain = wlan_regdomain_to_snmp(regdomain.regdomain); 1109 wif->country_code[0] = regdomain.isocc[0]; 1110 wif->country_code[1] = regdomain.isocc[1]; 1111 wif->country_code[2] = regdomain.location; 1112 1113 return (0); 1114 } 1115 1116 static int 1117 wlan_config_set_country(struct wlan_iface *wif, char *ccode, int rdomain) 1118 { 1119 int val = 0, txpowermax; 1120 uint32_t i; 1121 size_t argsize = 0; 1122 struct ieee80211_regdomain_req *regdomain; 1123 1124 if (wlan_get_channel_list(wif) < 0) 1125 return (-1); 1126 1127 if (wif->nchannels == 0) { 1128 syslog(LOG_ERR, "iface %s - set regdomain failed", wif->wname); 1129 return (-1); 1130 } 1131 1132 if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPOWMAX, &txpowermax, 0, 1133 &argsize, 0) < 0) 1134 return (-1); 1135 1136 regdomain = malloc(IEEE80211_REGDOMAIN_SIZE(wif->nchannels)); 1137 if (regdomain == NULL) 1138 return (-1); 1139 memset(regdomain, 0, IEEE80211_REGDOMAIN_SIZE(wif->nchannels)); 1140 argsize = IEEE80211_REGDOMAIN_SIZE(wif->nchannels); 1141 1142 /* XXX: recheck with how this is done by ifconfig(8) */ 1143 regdomain->rd.regdomain = wlan_snmp_to_regdomain(rdomain); 1144 regdomain->rd.isocc[0] = ccode[0]; 1145 regdomain->rd.isocc[1] = ccode[1]; 1146 regdomain->rd.location = ccode[2]; 1147 1148 /* XXX: fill the channel list properly */ 1149 regdomain->chaninfo.ic_nchans = wif->nchannels; 1150 memcpy(regdomain->chaninfo.ic_chans, wif->chanlist, 1151 wif->nchannels * sizeof(struct ieee80211_channel)); 1152 for (i = 0; i < wif->nchannels; i++) 1153 regdomain->chaninfo.ic_chans[i].ic_maxregpower = txpowermax; 1154 1155 wif->state = wlanIfaceState_down; 1156 if (wlan_config_state(wif, 1) < 0 || 1157 wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, regdomain, 1158 &argsize, 1) < 0) { 1159 free(regdomain); 1160 return (-1); 1161 } 1162 1163 wif->state = wlanIfaceState_up; 1164 (void)wlan_config_state(wif, 1); 1165 wif->reg_domain = wlan_regdomain_to_snmp(regdomain->rd.regdomain); 1166 wif->country_code[0] = regdomain->rd.isocc[0]; 1167 wif->country_code[1] = regdomain->rd.isocc[1]; 1168 wif->country_code[2] = regdomain->rd.location; 1169 free(regdomain); 1170 1171 return (0); 1172 } 1173 1174 int 1175 wlan_config_get_dssid(struct wlan_iface *wif) 1176 { 1177 int val = -1; 1178 size_t argsize = IEEE80211_NWID_LEN + 1; 1179 char ssid[IEEE80211_NWID_LEN + 1]; 1180 1181 memset(ssid, 0, IEEE80211_NWID_LEN + 1); 1182 1183 if (wlan_ioctl(wif->wname, 1184 (wif->mode == WlanIfaceOperatingModeType_meshPoint) ? 1185 IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid, 1186 &argsize, 0) < 0) 1187 return (-1); 1188 1189 if (argsize > IEEE80211_NWID_LEN) 1190 argsize = IEEE80211_NWID_LEN; 1191 memcpy(wif->desired_ssid, ssid, argsize); 1192 wif->desired_ssid[argsize] = '\0'; 1193 1194 return (0); 1195 } 1196 1197 int 1198 wlan_config_set_dssid(struct wlan_iface *wif, char *ssid, int slen) 1199 { 1200 int val = 0; 1201 size_t argsize = slen; 1202 1203 if (wlan_ioctl(wif->wname, 1204 (wif->mode == WlanIfaceOperatingModeType_meshPoint) ? 1205 IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid, 1206 &argsize, 1) < 0) 1207 return (-1); 1208 1209 if (argsize > IEEE80211_NWID_LEN) 1210 argsize = IEEE80211_NWID_LEN; 1211 memcpy(wif->desired_ssid, ssid, argsize); 1212 wif->desired_ssid[argsize] = '\0'; 1213 1214 return (0); 1215 } 1216 1217 static int 1218 wlan_config_get_dchannel(struct wlan_iface *wif) 1219 { 1220 uint32_t i = 0; 1221 int val = 0; 1222 size_t argsize = sizeof(struct ieee80211_channel); 1223 struct ieee80211_channel chan; 1224 1225 if (wlan_get_channel_list(wif) < 0) 1226 return (-1); 1227 1228 memset(&chan, 0, sizeof(chan)); 1229 if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan, 1230 &argsize, 0) < 0) 1231 return (-1); 1232 1233 for (i = 0; i < wif->nchannels; i++) 1234 if (chan.ic_ieee == wif->chanlist[i].ic_ieee && 1235 chan.ic_flags == wif->chanlist[i].ic_flags) { 1236 wif->desired_channel = i + 1; 1237 break; 1238 } 1239 1240 return (0); 1241 } 1242 1243 static int 1244 wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t dchannel) 1245 { 1246 int val = 0; 1247 size_t argsize = sizeof(struct ieee80211_channel); 1248 struct ieee80211_channel chan; 1249 1250 if (wlan_get_channel_list(wif) < 0) 1251 return (-1); 1252 1253 if (dchannel > wif->nchannels) 1254 return (-1); 1255 1256 memcpy(&chan, wif->chanlist + dchannel - 1, sizeof(chan)); 1257 if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan, 1258 &argsize, 1) < 0) 1259 return (-1); 1260 1261 wif->desired_channel = dchannel; 1262 1263 return (0); 1264 } 1265 1266 static int 1267 wlan_config_get_bssid(struct wlan_iface *wif) 1268 { 1269 int val = 0; 1270 size_t argsize = IEEE80211_ADDR_LEN; 1271 char bssid[IEEE80211_ADDR_LEN]; 1272 1273 memset(bssid, 0, IEEE80211_ADDR_LEN); 1274 1275 if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid, 1276 &argsize, 0) < 0 || argsize != IEEE80211_ADDR_LEN) 1277 return (-1); 1278 1279 memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN); 1280 1281 return (0); 1282 } 1283 1284 static int 1285 wlan_config_set_bssid(struct wlan_iface *wif, uint8_t *bssid) 1286 { 1287 int val = 0; 1288 size_t argsize = IEEE80211_ADDR_LEN; 1289 1290 if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid, 1291 &argsize, 1) < 0 || argsize != IEEE80211_ADDR_LEN) 1292 return (-1); 1293 1294 memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN); 1295 1296 return (0); 1297 } 1298 1299 /* 1300 * Convert the value returned by the kernel to the appropriate SNMP 1301 * representation and set the corresponding interface member accordingly. 1302 */ 1303 static void 1304 wlan_config_set_snmp_intval(struct wlan_iface *wif, int op, int val) 1305 { 1306 switch (op) { 1307 case IEEE80211_IOC_BURST: 1308 if (val == 0) 1309 wif->packet_burst = TruthValue_false; 1310 else 1311 wif->packet_burst = TruthValue_true; 1312 break; 1313 case IEEE80211_IOC_DFS: 1314 if (val == 0) 1315 wif->dyn_frequency = TruthValue_false; 1316 else 1317 wif->dyn_frequency = TruthValue_true; 1318 break; 1319 case IEEE80211_IOC_FF: 1320 if (val == 0) 1321 wif->fast_frames = TruthValue_false; 1322 else 1323 wif->fast_frames = TruthValue_true; 1324 break; 1325 case IEEE80211_IOC_TURBOP: 1326 if (val == 0) 1327 wif->dturbo = TruthValue_false; 1328 else 1329 wif->dturbo = TruthValue_true; 1330 break; 1331 case IEEE80211_IOC_TXPOWER: 1332 wif->tx_power = val / 2; 1333 break; 1334 case IEEE80211_IOC_FRAGTHRESHOLD: 1335 wif->frag_threshold = val; 1336 break; 1337 case IEEE80211_IOC_RTSTHRESHOLD: 1338 wif->rts_threshold = val; 1339 break; 1340 case IEEE80211_IOC_WPS: 1341 if (val == 0) 1342 wif->priv_subscribe = TruthValue_false; 1343 else 1344 wif->priv_subscribe = TruthValue_true; 1345 break; 1346 case IEEE80211_IOC_BGSCAN: 1347 if (val == 0) 1348 wif->bg_scan = TruthValue_false; 1349 else 1350 wif->bg_scan = TruthValue_true; 1351 break; 1352 case IEEE80211_IOC_BGSCAN_IDLE: 1353 wif->bg_scan_idle = val; 1354 break; 1355 case IEEE80211_IOC_BGSCAN_INTERVAL: 1356 wif->bg_scan_interval = val; 1357 break; 1358 case IEEE80211_IOC_BMISSTHRESHOLD: 1359 wif->beacons_missed = val; 1360 break; 1361 case IEEE80211_IOC_ROAMING: 1362 switch (val) { 1363 case IEEE80211_ROAMING_DEVICE: 1364 wif->roam_mode = wlanIfaceRoamingMode_device; 1365 break; 1366 case IEEE80211_ROAMING_MANUAL: 1367 wif->roam_mode = wlanIfaceRoamingMode_manual; 1368 break; 1369 case IEEE80211_ROAMING_AUTO: 1370 /* FALTHROUGH */ 1371 default: 1372 wif->roam_mode = wlanIfaceRoamingMode_auto; 1373 break; 1374 } 1375 break; 1376 case IEEE80211_IOC_DOTD: 1377 if (val == 0) 1378 wif->dot11d = TruthValue_false; 1379 else 1380 wif->dot11d = TruthValue_true; 1381 break; 1382 case IEEE80211_IOC_DOTH: 1383 if (val == 0) 1384 wif->dot11h = TruthValue_false; 1385 else 1386 wif->dot11h = TruthValue_true; 1387 break; 1388 case IEEE80211_IOC_DWDS: 1389 if (val == 0) 1390 wif->dynamic_wds = TruthValue_false; 1391 else 1392 wif->dynamic_wds = TruthValue_true; 1393 break; 1394 case IEEE80211_IOC_POWERSAVE: 1395 if (val == 0) 1396 wif->power_save = TruthValue_false; 1397 else 1398 wif->power_save = TruthValue_true; 1399 break; 1400 case IEEE80211_IOC_APBRIDGE: 1401 if (val == 0) 1402 wif->ap_bridge = TruthValue_false; 1403 else 1404 wif->ap_bridge = TruthValue_true; 1405 break; 1406 case IEEE80211_IOC_BEACON_INTERVAL: 1407 wif->beacon_interval = val; 1408 break; 1409 case IEEE80211_IOC_DTIM_PERIOD: 1410 wif->dtim_period = val; 1411 break; 1412 case IEEE80211_IOC_HIDESSID: 1413 if (val == 0) 1414 wif->hide_ssid = TruthValue_false; 1415 else 1416 wif->hide_ssid = TruthValue_true; 1417 break; 1418 case IEEE80211_IOC_INACTIVITY: 1419 if (val == 0) 1420 wif->inact_process = TruthValue_false; 1421 else 1422 wif->inact_process = TruthValue_true; 1423 break; 1424 case IEEE80211_IOC_PROTMODE: 1425 switch (val) { 1426 case IEEE80211_PROTMODE_CTS: 1427 wif->do11g_protect = wlanIfaceDot11gProtMode_cts; 1428 break; 1429 case IEEE80211_PROTMODE_RTSCTS: 1430 wif->do11g_protect = wlanIfaceDot11gProtMode_rtscts; 1431 break; 1432 case IEEE80211_PROTMODE_OFF: 1433 /* FALLTHROUGH */ 1434 default: 1435 wif->do11g_protect = wlanIfaceDot11gProtMode_off; 1436 break; 1437 } 1438 break; 1439 case IEEE80211_IOC_PUREG: 1440 if (val == 0) 1441 wif->dot11g_pure = TruthValue_false; 1442 else 1443 wif->dot11g_pure = TruthValue_true; 1444 break; 1445 case IEEE80211_IOC_PUREN: 1446 if (val == 0) 1447 wif->dot11n_pure = TruthValue_false; 1448 else 1449 wif->dot11n_pure = TruthValue_true; 1450 break; 1451 case IEEE80211_IOC_AMPDU: 1452 switch (val) { 1453 case 0: 1454 wif->ampdu = WlanIfaceDot11nPduType_disabled; 1455 break; 1456 case 1: 1457 wif->ampdu = WlanIfaceDot11nPduType_txOnly; 1458 break; 1459 case 2: 1460 wif->ampdu = WlanIfaceDot11nPduType_rxOnly; 1461 break; 1462 case 3: 1463 /* FALLTHROUGH */ 1464 default: 1465 wif->ampdu = WlanIfaceDot11nPduType_txAndRx; 1466 break; 1467 } 1468 break; 1469 case IEEE80211_IOC_AMPDU_DENSITY: 1470 switch (val) { 1471 case IEEE80211_HTCAP_MPDUDENSITY_025: 1472 wif->ampdu_density = 25; 1473 break; 1474 case IEEE80211_HTCAP_MPDUDENSITY_05: 1475 wif->ampdu_density = 50; 1476 break; 1477 case IEEE80211_HTCAP_MPDUDENSITY_1: 1478 wif->ampdu_density = 100; 1479 break; 1480 case IEEE80211_HTCAP_MPDUDENSITY_2: 1481 wif->ampdu_density = 200; 1482 break; 1483 case IEEE80211_HTCAP_MPDUDENSITY_4: 1484 wif->ampdu_density = 400; 1485 break; 1486 case IEEE80211_HTCAP_MPDUDENSITY_8: 1487 wif->ampdu_density = 800; 1488 break; 1489 case IEEE80211_HTCAP_MPDUDENSITY_16: 1490 wif->ampdu_density = 1600; 1491 break; 1492 case IEEE80211_HTCAP_MPDUDENSITY_NA: 1493 default: 1494 wif->ampdu_density = 0; 1495 break; 1496 } 1497 break; 1498 case IEEE80211_IOC_AMPDU_LIMIT: 1499 switch (val) { 1500 case IEEE80211_HTCAP_MAXRXAMPDU_8K: 1501 wif->ampdu_limit = 8192; 1502 break; 1503 case IEEE80211_HTCAP_MAXRXAMPDU_16K: 1504 wif->ampdu_limit = 16384; 1505 break; 1506 case IEEE80211_HTCAP_MAXRXAMPDU_32K: 1507 wif->ampdu_limit = 32768; 1508 break; 1509 case IEEE80211_HTCAP_MAXRXAMPDU_64K: 1510 default: 1511 wif->ampdu_limit = 65536; 1512 break; 1513 } 1514 break; 1515 case IEEE80211_IOC_AMSDU: 1516 switch (val) { 1517 case 0: 1518 wif->amsdu = WlanIfaceDot11nPduType_disabled; 1519 break; 1520 case 1: 1521 wif->amsdu = WlanIfaceDot11nPduType_txOnly; 1522 break; 1523 case 3: 1524 wif->amsdu = WlanIfaceDot11nPduType_txAndRx; 1525 break; 1526 case 2: 1527 default: 1528 /* FALLTHROUGH */ 1529 wif->amsdu = WlanIfaceDot11nPduType_rxOnly; 1530 break; 1531 } 1532 break; 1533 case IEEE80211_IOC_AMSDU_LIMIT: 1534 wif->amsdu_limit = val; 1535 break; 1536 case IEEE80211_IOC_HTCONF: 1537 if (val == 0) /* XXX */ 1538 wif->ht_enabled = TruthValue_false; 1539 else 1540 wif->ht_enabled = TruthValue_true; 1541 break; 1542 case IEEE80211_IOC_HTCOMPAT: 1543 if (val == 0) 1544 wif->ht_compatible = TruthValue_false; 1545 else 1546 wif->ht_compatible = TruthValue_true; 1547 break; 1548 case IEEE80211_IOC_HTPROTMODE: 1549 if (val == IEEE80211_PROTMODE_RTSCTS) 1550 wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_rts; 1551 else 1552 wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_off; 1553 break; 1554 case IEEE80211_IOC_RIFS: 1555 if (val == 0) 1556 wif->rifs = TruthValue_false; 1557 else 1558 wif->rifs = TruthValue_true; 1559 break; 1560 case IEEE80211_IOC_SHORTGI: 1561 if (val == 0) 1562 wif->short_gi = TruthValue_false; 1563 else 1564 wif->short_gi = TruthValue_true; 1565 break; 1566 case IEEE80211_IOC_SMPS: 1567 switch (val) { 1568 case IEEE80211_HTCAP_SMPS_DYNAMIC: 1569 wif->smps_mode = wlanIfaceDot11nSMPSMode_dynamic; 1570 break; 1571 case IEEE80211_HTCAP_SMPS_ENA: 1572 wif->smps_mode = wlanIfaceDot11nSMPSMode_static; 1573 break; 1574 case IEEE80211_HTCAP_SMPS_OFF: 1575 /* FALLTHROUGH */ 1576 default: 1577 wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled; 1578 break; 1579 } 1580 break; 1581 case IEEE80211_IOC_TDMA_SLOT: 1582 wif->tdma_slot = val; 1583 break; 1584 case IEEE80211_IOC_TDMA_SLOTCNT: 1585 wif->tdma_slot_count = val; 1586 break; 1587 case IEEE80211_IOC_TDMA_SLOTLEN: 1588 wif->tdma_slot_length = val; 1589 break; 1590 case IEEE80211_IOC_TDMA_BINTERVAL: 1591 wif->tdma_binterval = val; 1592 break; 1593 default: 1594 break; 1595 } 1596 } 1597 1598 /* 1599 * Convert an SNMP value to the kernel equivalent and also do sanity check 1600 * for each specific type. 1601 */ 1602 static int 1603 wlan_config_snmp2value(int which, int sval, int *value) 1604 { 1605 *value = 0; 1606 1607 switch (which) { 1608 case IEEE80211_IOC_BURST: 1609 case IEEE80211_IOC_DFS: 1610 case IEEE80211_IOC_FF: 1611 case IEEE80211_IOC_TURBOP: 1612 case IEEE80211_IOC_WPS: 1613 case IEEE80211_IOC_BGSCAN: 1614 case IEEE80211_IOC_DOTD: 1615 case IEEE80211_IOC_DOTH: 1616 case IEEE80211_IOC_DWDS: 1617 case IEEE80211_IOC_POWERSAVE: 1618 case IEEE80211_IOC_APBRIDGE: 1619 case IEEE80211_IOC_HIDESSID: 1620 case IEEE80211_IOC_INACTIVITY: 1621 case IEEE80211_IOC_PUREG: 1622 case IEEE80211_IOC_PUREN: 1623 case IEEE80211_IOC_HTCONF: 1624 case IEEE80211_IOC_HTCOMPAT: 1625 case IEEE80211_IOC_RIFS: 1626 if (sval == TruthValue_true) 1627 *value = 1; 1628 else if (sval != TruthValue_false) 1629 return (SNMP_ERR_INCONS_VALUE); 1630 break; 1631 case IEEE80211_IOC_REGDOMAIN: 1632 break; 1633 case IEEE80211_IOC_SSID: 1634 break; 1635 case IEEE80211_IOC_CURCHAN: 1636 break; 1637 case IEEE80211_IOC_TXPOWER: 1638 *value = sval * 2; 1639 break; 1640 case IEEE80211_IOC_FRAGTHRESHOLD: 1641 if (sval < IEEE80211_FRAG_MIN || sval > IEEE80211_FRAG_MAX) 1642 return (SNMP_ERR_INCONS_VALUE); 1643 *value = sval; 1644 break; 1645 case IEEE80211_IOC_RTSTHRESHOLD: 1646 if (sval < IEEE80211_RTS_MIN || sval > IEEE80211_RTS_MAX) 1647 return (SNMP_ERR_INCONS_VALUE); 1648 *value = sval; 1649 break; 1650 case IEEE80211_IOC_BGSCAN_IDLE: 1651 if (sval < WLAN_BGSCAN_IDLE_MIN) 1652 return (SNMP_ERR_INCONS_VALUE); 1653 *value = sval; 1654 break; 1655 case IEEE80211_IOC_BGSCAN_INTERVAL: 1656 if (sval < WLAN_SCAN_VALID_MIN) 1657 return (SNMP_ERR_INCONS_VALUE); 1658 *value = sval; 1659 break; 1660 case IEEE80211_IOC_BMISSTHRESHOLD: 1661 if (sval < IEEE80211_HWBMISS_MIN || sval > IEEE80211_HWBMISS_MAX) 1662 return (SNMP_ERR_INCONS_VALUE); 1663 *value = sval; 1664 break; 1665 case IEEE80211_IOC_BSSID: 1666 break; 1667 case IEEE80211_IOC_ROAMING: 1668 switch (sval) { 1669 case wlanIfaceRoamingMode_device: 1670 *value = IEEE80211_ROAMING_DEVICE; 1671 break; 1672 case wlanIfaceRoamingMode_manual: 1673 *value = IEEE80211_ROAMING_MANUAL; 1674 break; 1675 case wlanIfaceRoamingMode_auto: 1676 *value = IEEE80211_ROAMING_AUTO; 1677 break; 1678 default: 1679 return (SNMP_ERR_INCONS_VALUE); 1680 } 1681 break; 1682 case IEEE80211_IOC_BEACON_INTERVAL: 1683 if (sval < IEEE80211_BINTVAL_MIN || sval > IEEE80211_BINTVAL_MAX) 1684 return (SNMP_ERR_INCONS_VALUE); 1685 *value = sval; 1686 break; 1687 case IEEE80211_IOC_DTIM_PERIOD: 1688 if (sval < IEEE80211_DTIM_MIN || sval > IEEE80211_DTIM_MAX) 1689 return (SNMP_ERR_INCONS_VALUE); 1690 *value = sval; 1691 break; 1692 case IEEE80211_IOC_PROTMODE: 1693 switch (sval) { 1694 case wlanIfaceDot11gProtMode_cts: 1695 *value = IEEE80211_PROTMODE_CTS; 1696 break; 1697 case wlanIfaceDot11gProtMode_rtscts: 1698 *value = IEEE80211_PROTMODE_RTSCTS; 1699 break; 1700 case wlanIfaceDot11gProtMode_off: 1701 *value = IEEE80211_PROTMODE_OFF; 1702 break; 1703 default: 1704 return (SNMP_ERR_INCONS_VALUE); 1705 } 1706 break; 1707 case IEEE80211_IOC_AMPDU: 1708 switch (sval) { 1709 case WlanIfaceDot11nPduType_disabled: 1710 break; 1711 case WlanIfaceDot11nPduType_txOnly: 1712 *value = 1; 1713 break; 1714 case WlanIfaceDot11nPduType_rxOnly: 1715 *value = 2; 1716 break; 1717 case WlanIfaceDot11nPduType_txAndRx: 1718 *value = 3; 1719 break; 1720 default: 1721 return (SNMP_ERR_INCONS_VALUE); 1722 } 1723 break; 1724 case IEEE80211_IOC_AMPDU_DENSITY: 1725 switch (sval) { 1726 case 0: 1727 *value = IEEE80211_HTCAP_MPDUDENSITY_NA; 1728 break; 1729 case 25: 1730 *value = IEEE80211_HTCAP_MPDUDENSITY_025; 1731 break; 1732 case 50: 1733 *value = IEEE80211_HTCAP_MPDUDENSITY_05; 1734 break; 1735 case 100: 1736 *value = IEEE80211_HTCAP_MPDUDENSITY_1; 1737 break; 1738 case 200: 1739 *value = IEEE80211_HTCAP_MPDUDENSITY_2; 1740 break; 1741 case 400: 1742 *value = IEEE80211_HTCAP_MPDUDENSITY_4; 1743 break; 1744 case 800: 1745 *value = IEEE80211_HTCAP_MPDUDENSITY_8; 1746 break; 1747 case 1600: 1748 *value = IEEE80211_HTCAP_MPDUDENSITY_16; 1749 break; 1750 default: 1751 return (SNMP_ERR_INCONS_VALUE); 1752 } 1753 break; 1754 case IEEE80211_IOC_AMPDU_LIMIT: 1755 switch (sval) { 1756 case 8192: 1757 *value = IEEE80211_HTCAP_MAXRXAMPDU_8K; 1758 break; 1759 case 16384: 1760 *value = IEEE80211_HTCAP_MAXRXAMPDU_16K; 1761 break; 1762 case 32768: 1763 *value = IEEE80211_HTCAP_MAXRXAMPDU_32K; 1764 break; 1765 case 65536: 1766 *value = IEEE80211_HTCAP_MAXRXAMPDU_64K; 1767 break; 1768 default: 1769 return (SNMP_ERR_INCONS_VALUE); 1770 } 1771 break; 1772 case IEEE80211_IOC_AMSDU: 1773 switch (sval) { 1774 case WlanIfaceDot11nPduType_disabled: 1775 break; 1776 case WlanIfaceDot11nPduType_txOnly: 1777 *value = 1; 1778 break; 1779 case WlanIfaceDot11nPduType_rxOnly: 1780 *value = 2; 1781 break; 1782 case WlanIfaceDot11nPduType_txAndRx: 1783 *value = 3; 1784 break; 1785 default: 1786 return (SNMP_ERR_INCONS_VALUE); 1787 } 1788 break; 1789 case IEEE80211_IOC_AMSDU_LIMIT: 1790 if (sval == 3839 || sval == 0) 1791 *value = IEEE80211_HTCAP_MAXAMSDU_3839; 1792 else if (sval == 7935) 1793 *value = IEEE80211_HTCAP_MAXAMSDU_7935; 1794 else 1795 return (SNMP_ERR_INCONS_VALUE); 1796 break; 1797 case IEEE80211_IOC_HTPROTMODE: 1798 switch (sval) { 1799 case wlanIfaceDot11nHTProtMode_rts: 1800 *value = IEEE80211_PROTMODE_RTSCTS; 1801 break; 1802 case wlanIfaceDot11nHTProtMode_off: 1803 break; 1804 default: 1805 return (SNMP_ERR_INCONS_VALUE); 1806 } 1807 break; 1808 case IEEE80211_IOC_SHORTGI: 1809 if (sval == TruthValue_true) 1810 *value = IEEE80211_HTCAP_SHORTGI20 | 1811 IEEE80211_HTCAP_SHORTGI40; 1812 else if (sval != TruthValue_false) 1813 return (SNMP_ERR_INCONS_VALUE); 1814 break; 1815 case IEEE80211_IOC_SMPS: 1816 switch (sval) { 1817 case wlanIfaceDot11nSMPSMode_disabled: 1818 *value = IEEE80211_HTCAP_SMPS_OFF; 1819 break; 1820 case wlanIfaceDot11nSMPSMode_static: 1821 *value = IEEE80211_HTCAP_SMPS_ENA; 1822 break; 1823 case wlanIfaceDot11nSMPSMode_dynamic: 1824 *value = IEEE80211_HTCAP_SMPS_DYNAMIC; 1825 break; 1826 default: 1827 return (SNMP_ERR_INCONS_VALUE); 1828 } 1829 break; 1830 case IEEE80211_IOC_TDMA_SLOT: 1831 if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */ 1832 return (SNMP_ERR_INCONS_VALUE); 1833 *value = sval; 1834 break; 1835 case IEEE80211_IOC_TDMA_SLOTCNT: 1836 if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */ 1837 return (SNMP_ERR_INCONS_VALUE); 1838 *value = sval; 1839 break; 1840 case IEEE80211_IOC_TDMA_SLOTLEN: 1841 if (sval < 2*100 || sval > 0xfffff) /* XXX */ 1842 return (SNMP_ERR_INCONS_VALUE); 1843 *value = sval; 1844 break; 1845 case IEEE80211_IOC_TDMA_BINTERVAL: 1846 if (sval < 1) /* XXX */ 1847 return (SNMP_ERR_INCONS_VALUE); 1848 *value = sval; 1849 break; 1850 default: 1851 return (SNMP_ERR_INCONS_VALUE); 1852 } 1853 1854 return (SNMP_ERR_NOERROR); 1855 } 1856 1857 /* 1858 * Sanity checks for the wlanIfaceConfigTable. 1859 */ 1860 static int 1861 wlan_config_check(struct wlan_iface *wif, int op) 1862 { 1863 switch (op) { 1864 case IEEE80211_IOC_BURST: 1865 if ((wif->drivercaps & (0x1 << WlanDriverCaps_burst)) == 0) { 1866 wif->packet_burst = TruthValue_false; 1867 return (-1); 1868 } 1869 break; 1870 case IEEE80211_IOC_DFS: 1871 if ((wif->drivercaps & (0x1 << WlanDriverCaps_dfs)) == 0) { 1872 wif->dyn_frequency = TruthValue_false; 1873 return (-1); 1874 } 1875 break; 1876 case IEEE80211_IOC_FF: 1877 if ((wif->drivercaps & (0x1 << WlanDriverCaps_athFastFrames)) 1878 == 0) { 1879 wif->fast_frames = TruthValue_false; 1880 return (-1); 1881 } 1882 break; 1883 case IEEE80211_IOC_TURBOP: 1884 if ((wif->drivercaps & (0x1 << WlanDriverCaps_athTurbo)) == 0) { 1885 wif->dturbo = TruthValue_false; 1886 return (-1); 1887 } 1888 break; 1889 case IEEE80211_IOC_TXPOWER: 1890 if ((wif->drivercaps & (0x1 << WlanDriverCaps_txPmgt)) == 0) { 1891 wif->tx_power = 0; 1892 return (-1); 1893 } 1894 break; 1895 case IEEE80211_IOC_FRAGTHRESHOLD: 1896 if ((wif->drivercaps & (0x1 << WlanDriverCaps_txFrag)) == 0) { 1897 wif->frag_threshold = IEEE80211_FRAG_MAX; 1898 return (-1); 1899 } 1900 break; 1901 case IEEE80211_IOC_DWDS: 1902 if ((wif->drivercaps & (0x1 << WlanDriverCaps_wds)) == 0) { 1903 wif->dynamic_wds = TruthValue_false; 1904 return (-1); 1905 } 1906 break; 1907 case IEEE80211_IOC_POWERSAVE: 1908 if ((wif->drivercaps & (0x1 << WlanDriverCaps_pmgt)) == 0) { 1909 wif->power_save = TruthValue_false; 1910 return (-1); 1911 } 1912 break; 1913 case IEEE80211_IOC_BEACON_INTERVAL: 1914 if (wif->mode != WlanIfaceOperatingModeType_hostAp && 1915 wif->mode != WlanIfaceOperatingModeType_meshPoint && 1916 wif->mode != WlanIfaceOperatingModeType_ibss) { 1917 wif->beacon_interval = 100; /* XXX */ 1918 return (-1); 1919 } 1920 break; 1921 case IEEE80211_IOC_DTIM_PERIOD: 1922 if (wif->mode != WlanIfaceOperatingModeType_hostAp && 1923 wif->mode != WlanIfaceOperatingModeType_meshPoint && 1924 wif->mode != WlanIfaceOperatingModeType_ibss) { 1925 wif->dtim_period = 1; /* XXX */ 1926 return (-1); 1927 } 1928 break; 1929 case IEEE80211_IOC_PUREN: 1930 if ((wif->htcaps & (0x1 << WlanHTCaps_htcHt)) == 0) { 1931 wif->dot11n_pure = TruthValue_false; 1932 return (-1); 1933 } 1934 break; 1935 case IEEE80211_IOC_AMPDU: 1936 if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmpdu)) == 0) { 1937 wif->ampdu = WlanIfaceDot11nPduType_disabled; 1938 return (-1); 1939 } 1940 break; 1941 case IEEE80211_IOC_AMSDU: 1942 if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmsdu)) == 0) { 1943 wif->amsdu = WlanIfaceDot11nPduType_disabled; 1944 return (-1); 1945 } 1946 break; 1947 case IEEE80211_IOC_RIFS: 1948 if ((wif->htcaps & (0x1 << WlanHTCaps_htcRifs)) == 0) { 1949 wif->rifs = TruthValue_false; 1950 return (-1); 1951 } 1952 break; 1953 case IEEE80211_IOC_SHORTGI: 1954 if ((wif->htcaps & (0x1 << WlanHTCaps_shortGi20 | 1955 0x1 << WlanHTCaps_shortGi40)) == 0) { 1956 wif->short_gi = TruthValue_false; 1957 return (-1); 1958 } 1959 break; 1960 case IEEE80211_IOC_SMPS: 1961 if ((wif->htcaps & (0x1 << WlanHTCaps_htcSmps)) == 0) { 1962 wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled; 1963 return (-1); 1964 } 1965 break; 1966 case IEEE80211_IOC_TDMA_SLOT: 1967 if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1968 wif->tdma_slot = 0; 1969 return (-1); 1970 } 1971 break; 1972 case IEEE80211_IOC_TDMA_SLOTCNT: 1973 if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1974 wif->tdma_slot_count = 0; 1975 return (-1); 1976 } 1977 break; 1978 case IEEE80211_IOC_TDMA_SLOTLEN: 1979 if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1980 wif->tdma_slot_length = 0; 1981 return (-1); 1982 } 1983 break; 1984 case IEEE80211_IOC_TDMA_BINTERVAL: 1985 if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) { 1986 wif->tdma_binterval = 0; 1987 return (-1); 1988 } 1989 break; 1990 default: 1991 break; 1992 } 1993 1994 return (0); 1995 } 1996 1997 static int 1998 wlan_config_get_intval(struct wlan_iface *wif, int op) 1999 { 2000 int val = 0; 2001 size_t argsize = 0; 2002 2003 if (wlan_config_check(wif, op) < 0) 2004 return (0); 2005 if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0) 2006 return (-1); 2007 wlan_config_set_snmp_intval(wif, op, val); 2008 2009 return (0); 2010 } 2011 2012 static int 2013 wlan_config_set_intval(struct wlan_iface *wif, int op, int sval) 2014 { 2015 size_t argsize = 0; 2016 int val; 2017 2018 if (wlan_config_check(wif, op) < 0) 2019 return (-1); 2020 if (wlan_config_snmp2value(op, sval, &val) != SNMP_ERR_NOERROR) 2021 return (-1); 2022 if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0) 2023 return (-1); 2024 wlan_config_set_snmp_intval(wif, op, val); 2025 2026 return (0); 2027 } 2028 2029 int 2030 wlan_config_get_ioctl(struct wlan_iface *wif, int which) 2031 { 2032 int op; 2033 2034 switch (which) { 2035 case LEAF_wlanIfaceCountryCode: 2036 /* FALLTHROUGH */ 2037 case LEAF_wlanIfaceRegDomain: 2038 return (wlan_config_get_country(wif)); 2039 case LEAF_wlanIfaceDesiredSsid: 2040 return (wlan_config_get_dssid(wif)); 2041 case LEAF_wlanIfaceDesiredChannel: 2042 return (wlan_config_get_dchannel(wif)); 2043 case LEAF_wlanIfaceDesiredBssid: 2044 return (wlan_config_get_bssid(wif)); 2045 default: 2046 op = wlan_config_snmp2ioctl(which); 2047 return (wlan_config_get_intval(wif, op)); 2048 } 2049 2050 return (-1); 2051 } 2052 2053 int 2054 wlan_config_set_ioctl(struct wlan_iface *wif, int which, int val, 2055 char *strval, int len) 2056 { 2057 int op; 2058 2059 switch (which) { 2060 case LEAF_wlanIfaceCountryCode: 2061 return (wlan_config_set_country(wif, strval, 2062 wif->reg_domain)); 2063 case LEAF_wlanIfaceRegDomain: 2064 return (wlan_config_set_country(wif, wif->country_code, 2065 val)); 2066 case LEAF_wlanIfaceDesiredSsid: 2067 return (wlan_config_set_dssid(wif, strval, len)); 2068 case LEAF_wlanIfaceDesiredChannel: 2069 return (wlan_config_set_dchannel(wif, val)); 2070 case LEAF_wlanIfaceDesiredBssid: 2071 return (wlan_config_set_bssid(wif, strval)); 2072 default: 2073 op = wlan_config_snmp2ioctl(which); 2074 return (wlan_config_set_intval(wif, op, val)); 2075 } 2076 2077 return (-1); 2078 } 2079 2080 static uint32_t 2081 wlan_snmp_to_scan_flags(int flags) 2082 { 2083 int sr_flags = 0; 2084 2085 if ((flags & (0x1 << WlanScanFlagsType_noSelection)) != 0) 2086 sr_flags |= IEEE80211_IOC_SCAN_NOPICK; 2087 if ((flags & (0x1 << WlanScanFlagsType_activeScan)) != 0) 2088 sr_flags |= IEEE80211_IOC_SCAN_ACTIVE; 2089 if ((flags & (0x1 << WlanScanFlagsType_pickFirst)) != 0) 2090 sr_flags |= IEEE80211_IOC_SCAN_PICK1ST; 2091 if ((flags & (0x1 << WlanScanFlagsType_backgroundScan)) != 0) 2092 sr_flags |= IEEE80211_IOC_SCAN_BGSCAN; 2093 if ((flags & (0x1 << WlanScanFlagsType_once)) != 0) 2094 sr_flags |= IEEE80211_IOC_SCAN_ONCE; 2095 if ((flags & (0x1 << WlanScanFlagsType_noBroadcast)) != 0) 2096 sr_flags |= IEEE80211_IOC_SCAN_NOBCAST; 2097 if ((flags & (0x1 << WlanScanFlagsType_noAutoSequencing)) != 0) 2098 sr_flags |= IEEE80211_IOC_SCAN_NOJOIN; 2099 if ((flags & (0x1 << WlanScanFlagsType_flushCashe)) != 0) 2100 sr_flags |= IEEE80211_IOC_SCAN_FLUSH; 2101 if ((flags & (0x1 << WlanScanFlagsType_chechCashe)) != 0) 2102 sr_flags |= IEEE80211_IOC_SCAN_CHECK; 2103 2104 return (sr_flags); 2105 } 2106 2107 int 2108 wlan_set_scan_config(struct wlan_iface *wif) 2109 { 2110 int val = 0; 2111 size_t argsize; 2112 struct ieee80211_scan_req sr; 2113 2114 2115 memset(&sr, 0, sizeof(sr)); 2116 argsize = sizeof(struct ieee80211_scan_req); 2117 sr.sr_flags = wlan_snmp_to_scan_flags(wif->scan_flags); 2118 sr.sr_flags |= IEEE80211_IOC_SCAN_BGSCAN; 2119 sr.sr_duration = wif->scan_duration; 2120 sr.sr_mindwell = wif->scan_mindwell; 2121 sr.sr_maxdwell = wif->scan_maxdwell; 2122 sr.sr_nssid = 0; 2123 2124 if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_REQ, 2125 &val, &sr, &argsize, 1) < 0) 2126 return (-1); 2127 2128 wif->scan_status = wlanScanConfigStatus_running; 2129 return (0); 2130 } 2131 2132 static uint32_t 2133 wlan_peercaps_to_snmp(uint32_t pcaps) 2134 { 2135 uint32_t scaps = 0; 2136 2137 if ((pcaps & IEEE80211_CAPINFO_ESS) != 0) 2138 scaps |= (0x1 << WlanPeerCapabilityFlags_ess); 2139 if ((pcaps & IEEE80211_CAPINFO_IBSS) != 0) 2140 scaps |= (0x1 << WlanPeerCapabilityFlags_ibss); 2141 if ((pcaps & IEEE80211_CAPINFO_CF_POLLABLE) != 0) 2142 scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollable); 2143 if ((pcaps & IEEE80211_CAPINFO_CF_POLLREQ) != 0) 2144 scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollRequest); 2145 if ((pcaps & IEEE80211_CAPINFO_PRIVACY) != 0) 2146 scaps |= (0x1 << WlanPeerCapabilityFlags_privacy); 2147 if ((pcaps & IEEE80211_CAPINFO_SHORT_PREAMBLE) != 0) 2148 scaps |= (0x1 << WlanPeerCapabilityFlags_shortPreamble); 2149 if ((pcaps & IEEE80211_CAPINFO_PBCC) != 0) 2150 scaps |= (0x1 << WlanPeerCapabilityFlags_pbcc); 2151 if ((pcaps & IEEE80211_CAPINFO_CHNL_AGILITY) != 0) 2152 scaps |= (0x1 << WlanPeerCapabilityFlags_channelAgility); 2153 if ((pcaps & IEEE80211_CAPINFO_SHORT_SLOTTIME) != 0) 2154 scaps |= (0x1 << WlanPeerCapabilityFlags_shortSlotTime); 2155 if ((pcaps & IEEE80211_CAPINFO_RSN) != 0) 2156 scaps |= (0x1 << WlanPeerCapabilityFlags_rsn); 2157 if ((pcaps & IEEE80211_CAPINFO_DSSSOFDM) != 0) 2158 scaps |= (0x1 << WlanPeerCapabilityFlags_dsssofdm); 2159 2160 return (scaps); 2161 } 2162 2163 static int 2164 wlan_add_new_scan_result(struct wlan_iface *wif, 2165 const struct ieee80211req_scan_result *isr, uint8_t *ssid) 2166 { 2167 struct wlan_scan_result *sr; 2168 2169 if ((sr = wlan_scan_new_result(ssid, isr->isr_bssid)) == NULL) 2170 return (-1); 2171 2172 sr->opchannel = wlan_channel_flags_to_snmp_phy(isr->isr_flags); 2173 sr->rssi = isr->isr_rssi; 2174 sr->frequency = isr->isr_freq; 2175 sr->noise = isr->isr_noise; 2176 sr->bintval = isr->isr_intval; 2177 sr->capinfo = wlan_peercaps_to_snmp(isr->isr_capinfo); 2178 2179 if (wlan_scan_add_result(wif, sr) < 0) { 2180 wlan_scan_free_result(sr); 2181 return (-1); 2182 } 2183 2184 return (0); 2185 } 2186 2187 int 2188 wlan_get_scan_results(struct wlan_iface *wif) 2189 { 2190 int ssidlen, val = 0; 2191 uint8_t buf[24 * 1024]; 2192 size_t argsize; 2193 const uint8_t *cp, *idp; 2194 uint8_t ssid[IEEE80211_NWID_LEN + 1]; 2195 struct ieee80211req_scan_result isr; 2196 2197 argsize = sizeof(buf); 2198 if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_RESULTS, &val, &buf, 2199 &argsize, 0) < 0) 2200 return (-1); 2201 2202 if (argsize < sizeof(struct ieee80211req_scan_result)) 2203 return (0); 2204 2205 cp = buf; 2206 do { 2207 memcpy(&isr, cp, sizeof(struct ieee80211req_scan_result)); 2208 memset(ssid, 0, IEEE80211_NWID_LEN + 1); 2209 2210 if (isr.isr_meshid_len) { 2211 idp = cp + isr.isr_ie_off + isr.isr_ssid_len; 2212 ssidlen = isr.isr_meshid_len; 2213 } else { 2214 idp = cp + isr.isr_ie_off; 2215 ssidlen = isr.isr_ssid_len; 2216 } 2217 if (ssidlen > IEEE80211_NWID_LEN) 2218 ssidlen = IEEE80211_NWID_LEN; 2219 memcpy(ssid, idp, ssidlen); 2220 ssid[IEEE80211_NWID_LEN] = '\0'; 2221 (void)wlan_add_new_scan_result(wif, &isr, ssid); 2222 cp += isr.isr_len; 2223 argsize -= isr.isr_len; 2224 } while (argsize >= sizeof(struct ieee80211req_scan_result)); 2225 2226 return (0); 2227 } 2228 2229 int 2230 wlan_get_stats(struct wlan_iface *wif) 2231 { 2232 struct ifreq ifr; 2233 2234 memset(&ifr, 0, sizeof(struct ifreq)); 2235 strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ); 2236 2237 ifr.ifr_data = (caddr_t) &wif->stats; 2238 2239 if (ioctl(sock, SIOCG80211STATS, &ifr) < 0) { 2240 syslog(LOG_ERR, "iface %s - ioctl(SIOCG80211STATS) failed: %s", 2241 wif->wname, strerror(errno)); 2242 return (-1); 2243 } 2244 2245 return (0); 2246 } 2247 2248 int 2249 wlan_get_wepmode(struct wlan_iface *wif) 2250 { 2251 int val = 0; 2252 size_t argsize = 0; 2253 2254 if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL, 2255 &argsize, 0) < 0 || val == IEEE80211_WEP_NOSUP) { 2256 wif->wepsupported = 0; /* XXX */ 2257 wif->wepmode = wlanWepMode_off; 2258 wif->weptxkey = 0; 2259 return (-1); 2260 } 2261 2262 wif->wepsupported = 1; 2263 2264 switch (val) { 2265 case IEEE80211_WEP_ON: 2266 wif->wepmode = wlanWepMode_on; 2267 break; 2268 case IEEE80211_WEP_MIXED: 2269 wif->wepmode = wlanWepMode_mixed; 2270 break; 2271 case IEEE80211_WEP_OFF: 2272 /* FALLTHROUGH */ 2273 default: 2274 wif->wepmode = wlanWepMode_off; 2275 break; 2276 } 2277 2278 return (0); 2279 } 2280 2281 int 2282 wlan_set_wepmode(struct wlan_iface *wif) 2283 { 2284 int val; 2285 size_t argsize = 0; 2286 2287 if (!wif->wepsupported) 2288 return (-1); 2289 2290 switch (wif->wepmode) { 2291 case wlanWepMode_off: 2292 val = IEEE80211_WEP_OFF; 2293 break; 2294 case wlanWepMode_on: 2295 val = IEEE80211_WEP_ON; 2296 break; 2297 case wlanWepMode_mixed: 2298 val = IEEE80211_WEP_MIXED; 2299 break; 2300 default: 2301 return (-1); 2302 } 2303 2304 if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL, 2305 &argsize, 1) < 0) 2306 return (-1); 2307 2308 return (0); 2309 } 2310 2311 int 2312 wlan_get_weptxkey(struct wlan_iface *wif) 2313 { 2314 int val; 2315 size_t argsize = 0; 2316 2317 if (!wif->wepsupported) 2318 return (0); 2319 2320 if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL, 2321 &argsize, 0) < 0) 2322 return (-1); 2323 2324 if (val == IEEE80211_KEYIX_NONE) 2325 wif->weptxkey = 0; 2326 else 2327 wif->weptxkey = val + 1; 2328 2329 return (0); 2330 } 2331 2332 int 2333 wlan_set_weptxkey(struct wlan_iface *wif) 2334 { 2335 int val; 2336 size_t argsize = 0; 2337 2338 if (!wif->wepsupported) 2339 return (0); 2340 2341 if (wif->weptxkey >= IEEE80211_WEP_NKID) 2342 return (-1); 2343 2344 if (wif->weptxkey == 0) 2345 val = IEEE80211_KEYIX_NONE; 2346 else 2347 val = wif->weptxkey - 1; 2348 if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL, 2349 &argsize, 1) < 0) 2350 return (-1); 2351 2352 return (0); 2353 } 2354 2355 int 2356 wlan_get_wepkeys(struct wlan_iface *wif __unused) 2357 { 2358 /* XXX: should they be visible via SNMP */ 2359 return (0); 2360 } 2361 2362 int 2363 wlan_set_wepkeys(struct wlan_iface *wif __unused) 2364 { 2365 /* XXX: should they be configurable via SNMP */ 2366 return (0); 2367 } 2368 2369 int 2370 wlan_get_mac_policy(struct wlan_iface *wif) 2371 { 2372 int val = IEEE80211_MACCMD_POLICY; 2373 size_t argsize = 0; 2374 struct ieee80211req ireq; 2375 2376 memset(&ireq, 0, sizeof(struct ieee80211req)); 2377 strlcpy(ireq.i_name, wif->wname, IFNAMSIZ); 2378 ireq.i_type = IEEE80211_IOC_MACCMD; 2379 ireq.i_val = IEEE80211_MACCMD_POLICY; 2380 2381 if (ioctl(sock, SIOCG80211, &ireq) < 0) { 2382 if (errno != EINVAL) { 2383 syslog(LOG_ERR, "iface %s - get param: ioctl(%d) " 2384 "failed: %s", wif->wname, ireq.i_type, 2385 strerror(errno)); 2386 wif->macsupported = 0; 2387 return (-1); 2388 } else { 2389 wif->macsupported = 1; 2390 wif->mac_policy = wlanMACAccessControlPolicy_open; 2391 return (0); 2392 } 2393 2394 } 2395 2396 wif->macsupported = 1; 2397 2398 switch (val) { 2399 case IEEE80211_MACCMD_POLICY_ALLOW: 2400 wif->mac_policy = wlanMACAccessControlPolicy_allow; 2401 break; 2402 case IEEE80211_MACCMD_POLICY_DENY: 2403 wif->mac_policy = wlanMACAccessControlPolicy_deny; 2404 break; 2405 case IEEE80211_MACCMD_POLICY_RADIUS: 2406 wif->mac_policy = wlanMACAccessControlPolicy_radius; 2407 break; 2408 case IEEE80211_MACCMD_POLICY_OPEN: 2409 /* FALLTHROUGH */ 2410 default: 2411 wif->mac_policy = wlanMACAccessControlPolicy_open; 2412 break; 2413 } 2414 2415 argsize = 0; 2416 val = IEEE80211_MACCMD_LIST; 2417 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, 2418 &argsize, 0) < 0) 2419 return (-1); 2420 2421 wif->mac_nacls = argsize / sizeof(struct ieee80211req_maclist *); 2422 return (0); 2423 } 2424 2425 int 2426 wlan_set_mac_policy(struct wlan_iface *wif) 2427 { 2428 int val; 2429 size_t argsize = 0; 2430 2431 if (!wif->macsupported) 2432 return (-1); 2433 2434 switch (wif->mac_policy) { 2435 case wlanMACAccessControlPolicy_allow: 2436 val = IEEE80211_MACCMD_POLICY_ALLOW; 2437 break; 2438 case wlanMACAccessControlPolicy_deny: 2439 val = IEEE80211_MACCMD_POLICY_DENY; 2440 break; 2441 case wlanMACAccessControlPolicy_radius: 2442 val = IEEE80211_MACCMD_POLICY_RADIUS; 2443 break; 2444 case wlanMACAccessControlPolicy_open: 2445 val = IEEE80211_MACCMD_POLICY_OPEN; 2446 break; 2447 default: 2448 return (-1); 2449 } 2450 2451 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, 2452 &argsize, 1) < 0) 2453 return (-1); 2454 2455 return (0); 2456 } 2457 2458 int 2459 wlan_flush_mac_mac(struct wlan_iface *wif) 2460 { 2461 int val = IEEE80211_MACCMD_FLUSH; 2462 size_t argsize = 0; 2463 2464 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL, 2465 &argsize, 1) < 0) 2466 return (-1); 2467 2468 return (0); 2469 } 2470 2471 static int 2472 wlan_add_mac_macinfo(struct wlan_iface *wif, 2473 const struct ieee80211req_maclist *ml) 2474 { 2475 struct wlan_mac_mac *mmac; 2476 2477 if ((mmac = wlan_mac_new_mac(ml->ml_macaddr)) == NULL) 2478 return (-1); 2479 2480 mmac->mac_status = RowStatus_active; 2481 if (wlan_mac_add_mac(wif, mmac) < 0) { 2482 wlan_mac_free_mac(mmac); 2483 return (-1); 2484 } 2485 2486 return (0); 2487 } 2488 2489 int 2490 wlan_get_mac_acl_macs(struct wlan_iface *wif) 2491 { 2492 int i, nacls, val = IEEE80211_MACCMD_LIST; 2493 size_t argsize = 0; 2494 uint8_t *data; 2495 struct ieee80211req ireq; 2496 const struct ieee80211req_maclist *acllist; 2497 2498 if (wif->mac_policy == wlanMACAccessControlPolicy_radius) { 2499 wif->mac_nacls = 0; 2500 return (0); 2501 } 2502 2503 memset(&ireq, 0, sizeof(struct ieee80211req)); 2504 strlcpy(ireq.i_name, wif->wname, IFNAMSIZ); 2505 ireq.i_type = IEEE80211_IOC_MACCMD; 2506 ireq.i_val = IEEE80211_MACCMD_LIST; 2507 2508 2509 if (ioctl(sock, SIOCG80211, &ireq) < 0) { 2510 if (errno != EINVAL) { 2511 syslog(LOG_ERR, "iface %s - get param: ioctl(%d) " 2512 "failed: %s", wif->wname, ireq.i_type, 2513 strerror(errno)); 2514 wif->macsupported = 0; 2515 return (-1); 2516 } 2517 } 2518 2519 if (argsize == 0) { 2520 wif->mac_nacls = 0; 2521 return (0); 2522 } 2523 2524 if ((data = (uint8_t *)malloc(argsize)) == NULL) 2525 return (-1); 2526 2527 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, data, 2528 &argsize, 0) < 0) 2529 return (-1); 2530 2531 nacls = argsize / sizeof(*acllist); 2532 acllist = (struct ieee80211req_maclist *) data; 2533 for (i = 0; i < nacls; i++) 2534 (void)wlan_add_mac_macinfo(wif, acllist + i); 2535 2536 wif->mac_nacls = nacls; 2537 return (0); 2538 } 2539 2540 int 2541 wlan_add_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac) 2542 { 2543 int val = 0; 2544 size_t argsize = IEEE80211_ADDR_LEN; 2545 struct ieee80211req_mlme mlme; 2546 2547 if (wlan_ioctl(wif->wname, IEEE80211_IOC_ADDMAC, &val, 2548 mmac->mac, &argsize, 1) < 0) 2549 return (-1); 2550 2551 mmac->mac_status = RowStatus_active; 2552 2553 /* If policy is deny, try to kick the station just in case. */ 2554 if (wif->mac_policy != wlanMACAccessControlPolicy_deny) 2555 return (0); 2556 2557 memset(&mlme, 0, sizeof(mlme)); 2558 mlme.im_op = IEEE80211_MLME_DEAUTH; 2559 mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; 2560 memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN); 2561 argsize = sizeof(struct ieee80211req_mlme); 2562 2563 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme, 2564 &argsize, 1) < 0 && errno != ENOENT) 2565 return (-1); 2566 2567 return (0); 2568 } 2569 2570 int 2571 wlan_del_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac) 2572 { 2573 int val = 0; 2574 size_t argsize = IEEE80211_ADDR_LEN; 2575 struct ieee80211req_mlme mlme; 2576 2577 if (wlan_ioctl(wif->wname, IEEE80211_IOC_DELMAC, &val, 2578 mmac->mac, &argsize, 1) < 0) 2579 return (-1); 2580 2581 mmac->mac_status = RowStatus_active; 2582 2583 /* If policy is allow, try to kick the station just in case. */ 2584 if (wif->mac_policy != wlanMACAccessControlPolicy_allow) 2585 return (0); 2586 2587 memset(&mlme, 0, sizeof(mlme)); 2588 mlme.im_op = IEEE80211_MLME_DEAUTH; 2589 mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; 2590 memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN); 2591 argsize = sizeof(struct ieee80211req_mlme); 2592 2593 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme, 2594 &argsize, 1) < 0 && errno != ENOENT) 2595 return (-1); 2596 2597 return (0); 2598 } 2599 2600 int 2601 wlan_peer_set_vlan(struct wlan_iface *wif, struct wlan_peer *wip, int vlan) 2602 { 2603 int val = 0; 2604 size_t argsize; 2605 struct ieee80211req_sta_vlan vreq; 2606 2607 memcpy(vreq.sv_macaddr, wip->pmac, IEEE80211_ADDR_LEN); 2608 vreq.sv_vlan = vlan; 2609 argsize = sizeof(struct ieee80211req_sta_vlan); 2610 2611 if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_VLAN, 2612 &val, &vreq, &argsize, 1) < 0) 2613 return (-1); 2614 2615 wip->vlan = vlan; 2616 2617 return (0); 2618 } 2619 2620 /* XXX */ 2621 #ifndef IEEE80211_NODE_AUTH 2622 #define IEEE80211_NODE_AUTH 0x000001 /* authorized for data */ 2623 #define IEEE80211_NODE_QOS 0x000002 /* QoS enabled */ 2624 #define IEEE80211_NODE_ERP 0x000004 /* ERP enabled */ 2625 #define IEEE80211_NODE_PWR_MGT 0x000010 /* power save mode enabled */ 2626 #define IEEE80211_NODE_AREF 0x000020 /* authentication ref held */ 2627 #define IEEE80211_NODE_HT 0x000040 /* HT enabled */ 2628 #define IEEE80211_NODE_HTCOMPAT 0x000080 /* HT setup w/ vendor OUI's */ 2629 #define IEEE80211_NODE_WPS 0x000100 /* WPS association */ 2630 #define IEEE80211_NODE_TSN 0x000200 /* TSN association */ 2631 #define IEEE80211_NODE_AMPDU_RX 0x000400 /* AMPDU rx enabled */ 2632 #define IEEE80211_NODE_AMPDU_TX 0x000800 /* AMPDU tx enabled */ 2633 #define IEEE80211_NODE_MIMO_PS 0x001000 /* MIMO power save enabled */ 2634 #define IEEE80211_NODE_MIMO_RTS 0x002000 /* send RTS in MIMO PS */ 2635 #define IEEE80211_NODE_RIFS 0x004000 /* RIFS enabled */ 2636 #define IEEE80211_NODE_SGI20 0x008000 /* Short GI in HT20 enabled */ 2637 #define IEEE80211_NODE_SGI40 0x010000 /* Short GI in HT40 enabled */ 2638 #define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */ 2639 #define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */ 2640 #define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */ 2641 #endif 2642 2643 static uint32_t 2644 wlan_peerstate_to_snmp(uint32_t pstate) 2645 { 2646 uint32_t sstate = 0; 2647 2648 if ((pstate & IEEE80211_NODE_AUTH) != 0) 2649 sstate |= (0x1 << WlanIfacePeerFlagsType_authorizedForData); 2650 if ((pstate & IEEE80211_NODE_QOS) != 0) 2651 sstate |= (0x1 << WlanIfacePeerFlagsType_qosEnabled); 2652 if ((pstate & IEEE80211_NODE_ERP) != 0) 2653 sstate |= (0x1 << WlanIfacePeerFlagsType_erpEnabled); 2654 if ((pstate & IEEE80211_NODE_PWR_MGT) != 0) 2655 sstate |= (0x1 << WlanIfacePeerFlagsType_powerSaveMode); 2656 if ((pstate & IEEE80211_NODE_AREF) != 0) 2657 sstate |= (0x1 << WlanIfacePeerFlagsType_authRefHeld); 2658 if ((pstate & IEEE80211_NODE_HT) != 0) 2659 sstate |= (0x1 << WlanIfacePeerFlagsType_htEnabled); 2660 if ((pstate & IEEE80211_NODE_HTCOMPAT) != 0) 2661 sstate |= (0x1 << WlanIfacePeerFlagsType_htCompat); 2662 if ((pstate & IEEE80211_NODE_WPS) != 0) 2663 sstate |= (0x1 << WlanIfacePeerFlagsType_wpsAssoc); 2664 if ((pstate & IEEE80211_NODE_TSN) != 0) 2665 sstate |= (0x1 << WlanIfacePeerFlagsType_tsnAssoc); 2666 if ((pstate & IEEE80211_NODE_AMPDU_RX) != 0) 2667 sstate |= (0x1 << WlanIfacePeerFlagsType_ampduRx); 2668 if ((pstate & IEEE80211_NODE_AMPDU_TX) != 0) 2669 sstate |= (0x1 << WlanIfacePeerFlagsType_ampduTx); 2670 if ((pstate & IEEE80211_NODE_MIMO_PS) != 0) 2671 sstate |= (0x1 << WlanIfacePeerFlagsType_mimoPowerSave); 2672 if ((pstate & IEEE80211_NODE_MIMO_RTS) != 0) 2673 sstate |= (0x1 << WlanIfacePeerFlagsType_sendRts); 2674 if ((pstate & IEEE80211_NODE_RIFS) != 0) 2675 sstate |= (0x1 << WlanIfacePeerFlagsType_rifs); 2676 if ((pstate & IEEE80211_NODE_SGI20) != 0) 2677 sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT20); 2678 if ((pstate & IEEE80211_NODE_SGI40) != 0) 2679 sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT40); 2680 if ((pstate & IEEE80211_NODE_AMSDU_RX) != 0) 2681 sstate |= (0x1 << WlanIfacePeerFlagsType_amsduRx); 2682 if ((pstate & IEEE80211_NODE_AMSDU_TX) != 0) 2683 sstate |= (0x1 << WlanIfacePeerFlagsType_amsduTx); 2684 2685 return (sstate); 2686 } 2687 2688 static struct wlan_peer * 2689 wlan_add_peerinfo(const struct ieee80211req_sta_info *si) 2690 { 2691 struct wlan_peer *wip; 2692 2693 if ((wip = wlan_new_peer(si->isi_macaddr))== NULL) 2694 return (NULL); 2695 2696 wip->associd = IEEE80211_AID(si->isi_associd); 2697 wip->vlan = si->isi_vlan; 2698 wip->frequency = si->isi_freq; 2699 wip->fflags = si->isi_flags; 2700 wip->txrate = si->isi_txrate; 2701 wip->rssi = si->isi_rssi; 2702 wip->idle = si->isi_inact; 2703 wip->txseqs = si->isi_txseqs[0]; /* XXX */ 2704 wip->rxseqs = si->isi_rxseqs[0]; /* XXX */ 2705 wip->txpower = si->isi_txpower; 2706 wip->capinfo = wlan_peercaps_to_snmp(si->isi_capinfo); 2707 wip->state = wlan_peerstate_to_snmp(si->isi_state); 2708 wip->local_id = si->isi_localid; 2709 wip->peer_id = si->isi_peerid; 2710 2711 return (wip); 2712 } 2713 2714 int 2715 wlan_get_peerinfo(struct wlan_iface *wif) 2716 { 2717 union { 2718 struct ieee80211req_sta_req req; 2719 uint8_t buf[24 * 1024]; 2720 } u; 2721 const uint8_t *cp; 2722 int val = 0; 2723 size_t len; 2724 struct ieee80211req_sta_info si; 2725 struct wlan_peer *wip; 2726 2727 /* Get all stations - broadcast address */ 2728 (void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN); 2729 len = sizeof(u); 2730 2731 if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_INFO, 2732 & val, &u, &len, 0) < 0) 2733 return (-1); 2734 2735 if (len < sizeof(struct ieee80211req_sta_info)) 2736 return (-1); 2737 2738 cp = (const uint8_t *) u.req.info; 2739 do { 2740 memcpy(&si, cp, sizeof(struct ieee80211req_sta_info)); 2741 if ((wip = wlan_add_peerinfo(&si)) != NULL && 2742 wlan_add_peer(wif, wip) < 0) 2743 wlan_free_peer(wip); 2744 cp += si.isi_len, len -= si.isi_len; 2745 } while (len >= sizeof(struct ieee80211req_sta_info)); 2746 2747 return (0); 2748 } 2749 2750 /************************************************************************ 2751 * Wireless MESH & HWMP sysctl config. 2752 */ 2753 const char wlan_sysctl_name[] = "net.wlan."; 2754 2755 static const char *wlan_sysctl[] = { 2756 "mesh.retrytimeout", 2757 "mesh.holdingtimeout", 2758 "mesh.confirmtimeout", 2759 "mesh.maxretries", 2760 "hwmp.targetonly", 2761 "hwmp.replyforward", 2762 "hwmp.pathlifetime", 2763 "hwmp.roottimeout", 2764 "hwmp.rootint", 2765 "hwmp.rannint", 2766 "hwmp.inact", 2767 }; 2768 2769 int32_t 2770 wlan_do_sysctl(struct wlan_config *cfg, enum wlan_syscl which, int set) 2771 { 2772 char mib_name[100]; 2773 int val, sval; 2774 size_t len, vlen; 2775 2776 if (set) { 2777 vlen = sizeof(sval); 2778 switch (which) { 2779 case WLAN_MESH_RETRY_TO: 2780 sval = cfg->mesh_retryto; 2781 break; 2782 case WLAN_MESH_HOLDING_TO: 2783 sval = cfg->mesh_holdingto; 2784 break; 2785 case WLAN_MESH_CONFIRM_TO: 2786 sval = cfg->mesh_confirmto; 2787 break; 2788 case WLAN_MESH_MAX_RETRIES: 2789 sval = cfg->mesh_maxretries; 2790 break; 2791 case WLAN_HWMP_TARGET_ONLY: 2792 sval = cfg->hwmp_targetonly; 2793 break; 2794 case WLAN_HWMP_REPLY_FORWARD: 2795 sval = cfg->hwmp_replyforward; 2796 break; 2797 case WLAN_HWMP_PATH_LIFETIME: 2798 sval = cfg->hwmp_pathlifetime; 2799 break; 2800 case WLAN_HWMP_ROOT_TO: 2801 sval = cfg->hwmp_roottimeout; 2802 break; 2803 case WLAN_HWMP_ROOT_INT: 2804 sval = cfg->hwmp_rootint; 2805 break; 2806 case WLAN_HWMP_RANN_INT: 2807 sval = cfg->hwmp_rannint; 2808 break; 2809 case WLAN_HWMP_INACTIVITY_TO: 2810 sval = cfg->hwmp_inact; 2811 break; 2812 default: 2813 return (-1); 2814 } 2815 } else { 2816 if (which >= WLAN_SYSCTL_MAX) 2817 return (-1); 2818 vlen = 0; 2819 } 2820 2821 strlcpy(mib_name, wlan_sysctl_name, sizeof(mib_name)); 2822 strlcat(mib_name, wlan_sysctl[which], sizeof(mib_name)); 2823 len = sizeof (val); 2824 2825 if (sysctlbyname(mib_name, &val, &len, (set? &sval : NULL), vlen) < 0) { 2826 syslog(LOG_ERR, "sysctl(%s) failed - %s", mib_name, 2827 strerror(errno)); 2828 return (-1); 2829 } 2830 2831 switch (which) { 2832 case WLAN_MESH_RETRY_TO: 2833 cfg->mesh_retryto = val; 2834 break; 2835 case WLAN_MESH_HOLDING_TO: 2836 cfg->mesh_holdingto = val; 2837 break; 2838 case WLAN_MESH_CONFIRM_TO: 2839 cfg->mesh_confirmto = val; 2840 break; 2841 case WLAN_MESH_MAX_RETRIES: 2842 cfg->mesh_maxretries = val; 2843 break; 2844 case WLAN_HWMP_TARGET_ONLY: 2845 cfg->hwmp_targetonly = val; 2846 break; 2847 case WLAN_HWMP_REPLY_FORWARD: 2848 cfg->hwmp_replyforward = val; 2849 break; 2850 case WLAN_HWMP_PATH_LIFETIME: 2851 cfg->hwmp_pathlifetime = val; 2852 break; 2853 case WLAN_HWMP_ROOT_TO: 2854 cfg->hwmp_roottimeout = val; 2855 break; 2856 case WLAN_HWMP_ROOT_INT: 2857 cfg->hwmp_rootint = val; 2858 break; 2859 case WLAN_HWMP_RANN_INT: 2860 cfg->hwmp_rannint = val; 2861 break; 2862 case WLAN_HWMP_INACTIVITY_TO: 2863 cfg->hwmp_inact = val; 2864 break; 2865 default: 2866 /* NOTREACHED */ 2867 abort(); 2868 } 2869 2870 return (0); 2871 } 2872 2873 int 2874 wlan_mesh_config_get(struct wlan_iface *wif, int which) 2875 { 2876 int op, val = 0; 2877 size_t argsize = 0; 2878 uint8_t data[32], *pd = NULL; 2879 2880 switch (which) { 2881 case LEAF_wlanMeshTTL: 2882 op = IEEE80211_IOC_MESH_TTL; 2883 break; 2884 case LEAF_wlanMeshPeeringEnabled: 2885 op = IEEE80211_IOC_MESH_AP; 2886 break; 2887 case LEAF_wlanMeshForwardingEnabled: 2888 op = IEEE80211_IOC_MESH_FWRD; 2889 break; 2890 case LEAF_wlanMeshMetric: 2891 op = IEEE80211_IOC_MESH_PR_METRIC; 2892 pd = data; 2893 argsize = sizeof(data); 2894 break; 2895 case LEAF_wlanMeshPath: 2896 op = IEEE80211_IOC_MESH_PR_PATH; 2897 pd = data; 2898 argsize = sizeof(data); 2899 break; 2900 case LEAF_wlanMeshRoutesFlush: 2901 return (0); 2902 default: 2903 return (-1); 2904 } 2905 2906 if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 0) < 0) 2907 return (-1); 2908 2909 switch (which) { 2910 case LEAF_wlanMeshTTL: 2911 wif->mesh_ttl = val; 2912 break; 2913 case LEAF_wlanMeshPeeringEnabled: 2914 if (val) 2915 wif->mesh_peering = wlanMeshPeeringEnabled_true; 2916 else 2917 wif->mesh_peering = wlanMeshPeeringEnabled_false; 2918 break; 2919 case LEAF_wlanMeshForwardingEnabled: 2920 if (val) 2921 wif->mesh_forwarding = wlanMeshForwardingEnabled_true; 2922 else 2923 wif->mesh_forwarding = wlanMeshForwardingEnabled_false; 2924 break; 2925 case LEAF_wlanMeshMetric: 2926 data[argsize] = '\0'; 2927 if (strcmp(data, "AIRTIME") == 0) 2928 wif->mesh_metric = wlanMeshMetric_airtime; 2929 else 2930 wif->mesh_metric = wlanMeshMetric_unknown; 2931 break; 2932 case LEAF_wlanMeshPath: 2933 data[argsize] = '\0'; 2934 if (strcmp(data, "HWMP") == 0) 2935 wif->mesh_path = wlanMeshPath_hwmp; 2936 else 2937 wif->mesh_path = wlanMeshPath_unknown; 2938 } 2939 2940 return (0); 2941 } 2942 2943 int 2944 wlan_mesh_config_set(struct wlan_iface *wif, int which) 2945 { 2946 int op, val = 0; 2947 size_t argsize = 0; 2948 uint8_t data[32], *pd = NULL; 2949 2950 switch (which) { 2951 case LEAF_wlanMeshTTL: 2952 op = IEEE80211_IOC_MESH_TTL; 2953 val = wif->mesh_ttl; 2954 break; 2955 case LEAF_wlanMeshPeeringEnabled: 2956 op = IEEE80211_IOC_MESH_AP; 2957 if (wif->mesh_peering == wlanMeshPeeringEnabled_true) 2958 val = 1; 2959 break; 2960 case LEAF_wlanMeshForwardingEnabled: 2961 if (wif->mesh_forwarding == wlanMeshForwardingEnabled_true) 2962 val = 1; 2963 op = IEEE80211_IOC_MESH_FWRD; 2964 break; 2965 case LEAF_wlanMeshMetric: 2966 op = IEEE80211_IOC_MESH_PR_METRIC; 2967 if (wif->mesh_metric == wlanMeshMetric_airtime) 2968 strcpy(data, "AIRTIME"); 2969 else 2970 return (-1); 2971 pd = data; 2972 argsize = sizeof(data); 2973 break; 2974 case LEAF_wlanMeshPath: 2975 op = IEEE80211_IOC_MESH_PR_PATH; 2976 if (wif->mesh_path == wlanMeshPath_hwmp) 2977 strcpy(data, "HWMP"); 2978 else 2979 return (-1); 2980 pd = data; 2981 argsize = sizeof(data); 2982 break; 2983 default: 2984 return (-1); 2985 } 2986 2987 if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 1) < 0) 2988 return (-1); 2989 2990 return(0); 2991 } 2992 2993 int 2994 wlan_mesh_flush_routes(struct wlan_iface *wif) 2995 { 2996 int val = IEEE80211_MESH_RTCMD_FLUSH; 2997 size_t argsize = 0; 2998 2999 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, NULL, 3000 &argsize, 1) < 0) 3001 return (-1); 3002 3003 return (0); 3004 } 3005 3006 int 3007 wlan_mesh_add_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr) 3008 { 3009 int val = IEEE80211_MESH_RTCMD_ADD; 3010 size_t argsize = IEEE80211_ADDR_LEN; 3011 3012 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, 3013 wmr->imroute.imr_dest, &argsize, 1) < 0) 3014 return (-1); 3015 3016 wmr->mroute_status = RowStatus_active; 3017 3018 return (0); 3019 } 3020 3021 int 3022 wlan_mesh_del_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr) 3023 { 3024 int val = IEEE80211_MESH_RTCMD_DELETE; 3025 size_t argsize = IEEE80211_ADDR_LEN; 3026 3027 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, 3028 wmr->imroute.imr_dest, &argsize, 1) < 0) 3029 return (-1); 3030 3031 wmr->mroute_status = RowStatus_destroy; 3032 3033 return (0); 3034 } 3035 3036 int 3037 wlan_mesh_get_routelist(struct wlan_iface *wif) 3038 { 3039 int i, nroutes, val = IEEE80211_MESH_RTCMD_LIST; 3040 size_t argsize; 3041 struct ieee80211req_mesh_route routes[128]; 3042 struct ieee80211req_mesh_route *rt; 3043 struct wlan_mesh_route *wmr; 3044 3045 argsize = sizeof(routes); 3046 if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, routes, 3047 &argsize, 0) < 0) /* XXX: ENOMEM? */ 3048 return (-1); 3049 3050 nroutes = argsize / sizeof(*rt); 3051 for (i = 0; i < nroutes; i++) { 3052 rt = routes + i; 3053 if ((wmr = wlan_mesh_new_route(rt->imr_dest)) == NULL) 3054 return (-1); 3055 memcpy(&wmr->imroute, rt, sizeof(*rt)); 3056 wmr->mroute_status = RowStatus_active; 3057 if (wlan_mesh_add_rtentry(wif, wmr) < 0) 3058 wlan_mesh_free_route(wmr); 3059 } 3060 3061 return (0); 3062 } 3063 3064 int 3065 wlan_hwmp_config_get(struct wlan_iface *wif, int which) 3066 { 3067 int op, val = 0; 3068 size_t argsize = 0; 3069 3070 switch (which) { 3071 case LEAF_wlanHWMPRootMode: 3072 op = IEEE80211_IOC_HWMP_ROOTMODE; 3073 break; 3074 case LEAF_wlanHWMPMaxHops: 3075 op = IEEE80211_IOC_HWMP_MAXHOPS; 3076 break; 3077 default: 3078 return (-1); 3079 } 3080 3081 if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0) 3082 return (-1); 3083 3084 switch (which) { 3085 case LEAF_wlanHWMPRootMode: 3086 switch (val) { 3087 case IEEE80211_HWMP_ROOTMODE_NORMAL: 3088 wif->hwmp_root_mode = wlanHWMPRootMode_normal; 3089 break; 3090 case IEEE80211_HWMP_ROOTMODE_PROACTIVE: 3091 wif->hwmp_root_mode = wlanHWMPRootMode_proactive; 3092 break; 3093 case IEEE80211_HWMP_ROOTMODE_RANN: 3094 wif->hwmp_root_mode = wlanHWMPRootMode_rann; 3095 break; 3096 case IEEE80211_HWMP_ROOTMODE_DISABLED: 3097 default: 3098 wif->hwmp_root_mode = wlanHWMPRootMode_disabled; 3099 break; 3100 } 3101 break; 3102 case LEAF_wlanHWMPMaxHops: 3103 wif->hwmp_max_hops = val; 3104 break; 3105 } 3106 3107 return (0); 3108 } 3109 3110 int 3111 wlan_hwmp_config_set(struct wlan_iface *wif, int which) 3112 { 3113 int op, val = 0; 3114 size_t argsize = 0; 3115 3116 switch (which) { 3117 case LEAF_wlanHWMPRootMode: 3118 op = IEEE80211_IOC_HWMP_ROOTMODE; 3119 switch (wif->hwmp_root_mode) { 3120 case wlanHWMPRootMode_disabled: 3121 val = IEEE80211_HWMP_ROOTMODE_DISABLED; 3122 break; 3123 case wlanHWMPRootMode_normal: 3124 val = IEEE80211_HWMP_ROOTMODE_NORMAL; 3125 break; 3126 case wlanHWMPRootMode_proactive: 3127 val = IEEE80211_HWMP_ROOTMODE_PROACTIVE; 3128 break; 3129 case wlanHWMPRootMode_rann: 3130 val = IEEE80211_HWMP_ROOTMODE_RANN; 3131 break; 3132 default: 3133 return (-1); 3134 } 3135 break; 3136 case LEAF_wlanHWMPMaxHops: 3137 op = IEEE80211_IOC_HWMP_MAXHOPS; 3138 val = wif->hwmp_max_hops; 3139 break; 3140 default: 3141 return (-1); 3142 } 3143 3144 if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0) 3145 return (-1); 3146 3147 return (0); 3148 } 3149