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