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/queue.h> 35 #include <sys/socket.h> 36 #include <sys/types.h> 37 38 #include <net/if.h> 39 #include <net/if_media.h> 40 #include <net/if_mib.h> 41 #include <net/if_types.h> 42 #include <net80211/ieee80211.h> 43 #include <net80211/ieee80211_ioctl.h> 44 45 #include <errno.h> 46 #include <stdarg.h> 47 #include <stdlib.h> 48 #include <stdio.h> 49 #include <string.h> 50 #include <syslog.h> 51 52 #include <bsnmp/snmpmod.h> 53 #include <bsnmp/snmp_mibII.h> 54 55 #define SNMPTREE_TYPES 56 #include "wlan_tree.h" 57 #include "wlan_snmp.h" 58 #include "wlan_oid.h" 59 60 static struct lmodule *wlan_module; 61 62 /* For the registration. */ 63 static const struct asn_oid oid_wlan = OIDX_begemotWlan; 64 /* The registration. */ 65 static uint reg_wlan; 66 67 /* Periodic timer for polling the module's data. */ 68 static void *wlan_data_timer; 69 70 /* 71 * Poll data from kernel every 15 minutes unless explicitly requested by an 72 * SNMP client. 73 * XXX: make that configurable. 74 */ 75 static int wlan_poll_ticks = (15 * 60) * 100; 76 77 /* The age of each table. */ 78 #define WLAN_LIST_MAXAGE 5 79 80 static time_t wlan_iflist_age; 81 static time_t wlan_peerlist_age; 82 static time_t wlan_chanlist_age; 83 static time_t wlan_roamlist_age; 84 static time_t wlan_tx_paramlist_age; 85 static time_t wlan_scanlist_age; 86 static time_t wlan_maclist_age; 87 static time_t wlan_mrlist_age; 88 89 /* 90 * The list of all virtual wireless interfaces - sorted by name. 91 */ 92 SLIST_HEAD(wlan_ifaces, wlan_iface); 93 static struct wlan_ifaces wlan_ifaces = SLIST_HEAD_INITIALIZER(wlan_ifaces); 94 95 static struct wlan_config wlan_config; 96 97 /* Forward declarations */ 98 static int bits_get(struct snmp_value *, const u_char *, ssize_t); 99 100 static int wlan_add_wif(struct wlan_iface *); 101 static void wlan_delete_wif(struct wlan_iface *); 102 static int wlan_attach_newif(struct mibif *); 103 static int wlan_iface_create(struct wlan_iface *); 104 static int wlan_iface_destroy(struct wlan_iface *); 105 static struct wlan_iface * wlan_new_wif(char *); 106 107 static void wlan_free_interface(struct wlan_iface *); 108 static void wlan_free_iflist(void); 109 static void wlan_free_peerlist(struct wlan_iface *); 110 static void wlan_scan_free_results(struct wlan_iface *); 111 static void wlan_mac_free_maclist(struct wlan_iface *); 112 static void wlan_mesh_free_routes(struct wlan_iface *); 113 114 static int wlan_update_interface(struct wlan_iface *); 115 static void wlan_update_interface_list(void); 116 static void wlan_update_peers(void); 117 static void wlan_update_channels(void); 118 static void wlan_update_roam_params(void); 119 static void wlan_update_tx_params(void); 120 static void wlan_scan_update_results(void); 121 static void wlan_mac_update_aclmacs(void); 122 static void wlan_mesh_update_routes(void); 123 124 static struct wlan_iface * wlan_find_interface(const char *); 125 static struct wlan_peer * wlan_find_peer(struct wlan_iface *, uint8_t *); 126 static struct ieee80211_channel* wlan_find_channel(struct wlan_iface *, 127 uint32_t); 128 static struct wlan_scan_result * wlan_scan_find_result(struct wlan_iface *, 129 uint8_t *, uint8_t *); 130 static struct wlan_mac_mac * wlan_mac_find_mac(struct wlan_iface *, 131 uint8_t *); 132 static struct wlan_mesh_route * wlan_mesh_find_route(struct wlan_iface *, 133 uint8_t *); 134 135 static struct wlan_iface * wlan_first_interface(void); 136 static struct wlan_iface * wlan_next_interface(struct wlan_iface *); 137 static struct wlan_iface * wlan_mesh_first_interface(void); 138 static struct wlan_iface * wlan_mesh_next_interface(struct wlan_iface *); 139 140 static struct wlan_iface * wlan_get_interface(const struct asn_oid *, uint); 141 static struct wlan_iface * wlan_get_snmp_interface(const struct asn_oid *, 142 uint); 143 static struct wlan_peer * wlan_get_peer(const struct asn_oid *, uint, 144 struct wlan_iface **); 145 static struct ieee80211_channel *wlan_get_channel(const struct asn_oid *, uint, 146 struct wlan_iface **); 147 static struct ieee80211_roamparam *wlan_get_roam_param(const struct asn_oid *, 148 uint, struct wlan_iface **); 149 static struct ieee80211_txparam *wlan_get_tx_param(const struct asn_oid *, 150 uint, struct wlan_iface **, uint32_t *); 151 static struct wlan_scan_result *wlan_get_scanr(const struct asn_oid *, uint, 152 struct wlan_iface **); 153 static struct wlan_mac_mac * wlan_get_acl_mac(const struct asn_oid *, 154 uint, struct wlan_iface **); 155 static struct wlan_iface * wlan_mesh_get_iface(const struct asn_oid *, uint); 156 static struct wlan_peer * wlan_mesh_get_peer(const struct asn_oid *, uint, 157 struct wlan_iface **); 158 static struct wlan_mesh_route * wlan_mesh_get_route(const struct asn_oid *, 159 uint, struct wlan_iface **); 160 161 static struct wlan_iface * wlan_get_next_interface(const struct asn_oid *, 162 uint); 163 static struct wlan_iface * wlan_get_next_snmp_interface(const struct 164 asn_oid *, uint); 165 static struct wlan_peer * wlan_get_next_peer(const struct asn_oid *, uint, 166 struct wlan_iface **); 167 static struct ieee80211_channel *wlan_get_next_channel(const struct asn_oid *, 168 uint, struct wlan_iface **); 169 static struct ieee80211_roamparam *wlan_get_next_roam_param(const struct 170 asn_oid *, uint sub, struct wlan_iface **, uint32_t *); 171 static struct ieee80211_txparam *wlan_get_next_tx_param(const struct asn_oid *, 172 uint, struct wlan_iface **, uint32_t *); 173 static struct wlan_scan_result *wlan_get_next_scanr(const struct asn_oid *, 174 uint , struct wlan_iface **); 175 static struct wlan_mac_mac * wlan_get_next_acl_mac(const struct asn_oid *, 176 uint, struct wlan_iface **); 177 static struct wlan_iface * wlan_mesh_get_next_iface(const struct asn_oid *, 178 uint); 179 static struct wlan_peer * wlan_mesh_get_next_peer(const struct asn_oid *, 180 uint, struct wlan_iface **); 181 static struct wlan_mesh_route * wlan_mesh_get_next_route(const struct asn_oid *, 182 uint sub, struct wlan_iface **); 183 184 static uint8_t *wlan_get_ifname(const struct asn_oid *, uint, uint8_t *); 185 static int wlan_mac_index_decode(const struct asn_oid *, uint, char *, 186 uint8_t *); 187 static int wlan_channel_index_decode(const struct asn_oid *, uint, 188 char *, uint32_t *); 189 static int wlan_phy_index_decode(const struct asn_oid *, uint, char *, 190 uint32_t *); 191 static int wlan_scanr_index_decode(const struct asn_oid *oid, uint sub, 192 char *wname, uint8_t *ssid, uint8_t *bssid); 193 194 static void wlan_append_ifindex(struct asn_oid *, uint, 195 const struct wlan_iface *); 196 static void wlan_append_mac_index(struct asn_oid *, uint, char *, uint8_t *); 197 static void wlan_append_channel_index(struct asn_oid *, uint, 198 const struct wlan_iface *, const struct ieee80211_channel *); 199 static void wlan_append_phy_index(struct asn_oid *, uint, char *, uint32_t); 200 static void wlan_append_scanr_index(struct asn_oid *, uint, char *, 201 uint8_t *, uint8_t *); 202 203 static int wlan_acl_mac_set_status(struct snmp_context *, 204 struct snmp_value *, uint); 205 static int wlan_mesh_route_set_status(struct snmp_context *, 206 struct snmp_value *, uint); 207 208 static int32_t wlan_get_channel_type(struct ieee80211_channel *); 209 static int wlan_scan_compare_result(struct wlan_scan_result *, 210 struct wlan_scan_result *); 211 static int wlan_mac_delete_mac(struct wlan_iface *, struct wlan_mac_mac *); 212 static int wlan_mesh_delete_route(struct wlan_iface *, 213 struct wlan_mesh_route *); 214 215 /* 216 * The module's GET/SET data hooks per each table or group of objects as 217 * required by bsnmpd(1). 218 */ 219 int 220 op_wlan_iface(struct snmp_context *ctx, struct snmp_value *val, uint32_t sub, 221 uint32_t iidx __unused, enum snmp_op op) 222 { 223 int rc; 224 char wname[IFNAMSIZ]; 225 struct wlan_iface *wif; 226 227 wlan_update_interface_list(); 228 229 switch (op) { 230 case SNMP_OP_GET: 231 if ((wif = wlan_get_snmp_interface(&val->var, sub)) == NULL) 232 return (SNMP_ERR_NOSUCHNAME); 233 break; 234 235 case SNMP_OP_GETNEXT: 236 if ((wif = wlan_get_next_snmp_interface(&val->var, sub)) == NULL) 237 return (SNMP_ERR_NOSUCHNAME); 238 wlan_append_ifindex(&val->var, sub, wif); 239 break; 240 241 case SNMP_OP_SET: 242 if ((wif = wlan_get_snmp_interface(&val->var, sub)) == NULL) { 243 if (val->var.subs[sub - 1] != LEAF_wlanIfaceName) 244 return (SNMP_ERR_NOSUCHNAME); 245 if (wlan_get_ifname(&val->var, sub, wname) == NULL) 246 return (SNMP_ERR_INCONS_VALUE); 247 if ((wif = wlan_new_wif(wname)) == NULL) 248 return (SNMP_ERR_GENERR); 249 wif->internal = 1; 250 } 251 if (wif->status == RowStatus_active && 252 val->var.subs[sub - 1] != LEAF_wlanIfaceStatus && 253 val->var.subs[sub - 1] != LEAF_wlanIfaceState) 254 return (SNMP_ERR_INCONS_VALUE); 255 256 switch (val->var.subs[sub - 1]) { 257 case LEAF_wlanIfaceIndex: 258 return (SNMP_ERR_NOT_WRITEABLE); 259 260 case LEAF_wlanIfaceName: 261 if (val->v.octetstring.len >= IFNAMSIZ) 262 return (SNMP_ERR_INCONS_VALUE); 263 if ((ctx->scratch->ptr1 = malloc(IFNAMSIZ)) == NULL) 264 return (SNMP_ERR_GENERR); 265 strlcpy(ctx->scratch->ptr1, wif->wname, IFNAMSIZ); 266 memcpy(wif->wname, val->v.octetstring.octets, 267 val->v.octetstring.len); 268 wif->wname[val->v.octetstring.len] = '\0'; 269 return (SNMP_ERR_NOERROR); 270 271 case LEAF_wlanParentIfName: 272 if (val->v.octetstring.len >= IFNAMSIZ) 273 return (SNMP_ERR_INCONS_VALUE); 274 if ((ctx->scratch->ptr1 = malloc(IFNAMSIZ)) == NULL) 275 return (SNMP_ERR_GENERR); 276 strlcpy(ctx->scratch->ptr1, wif->pname, IFNAMSIZ); 277 memcpy(wif->pname, val->v.octetstring.octets, 278 val->v.octetstring.len); 279 wif->pname[val->v.octetstring.len] = '\0'; 280 return (SNMP_ERR_NOERROR); 281 282 case LEAF_wlanIfaceOperatingMode: 283 ctx->scratch->int1 = wif->mode; 284 wif->mode = val->v.integer; 285 return (SNMP_ERR_NOERROR); 286 287 case LEAF_wlanIfaceFlags: 288 if (val->v.octetstring.len > sizeof(wif->flags)) 289 return (SNMP_ERR_INCONS_VALUE); 290 ctx->scratch->ptr1 = malloc(sizeof(wif->flags)); 291 if (ctx->scratch->ptr1 == NULL) 292 return (SNMP_ERR_GENERR); 293 memcpy(ctx->scratch->ptr1, (uint8_t *)&wif->flags, 294 sizeof(wif->flags)); 295 memcpy((uint8_t *)&wif->flags, val->v.octetstring.octets, 296 sizeof(wif->flags)); 297 return (SNMP_ERR_NOERROR); 298 299 case LEAF_wlanIfaceBssid: 300 if (val->v.octetstring.len != IEEE80211_ADDR_LEN) 301 return (SNMP_ERR_INCONS_VALUE); 302 ctx->scratch->ptr1 = malloc(IEEE80211_ADDR_LEN); 303 if (ctx->scratch->ptr1 == NULL) 304 return (SNMP_ERR_GENERR); 305 memcpy(ctx->scratch->ptr1, wif->dbssid, 306 IEEE80211_ADDR_LEN); 307 memcpy(wif->dbssid, val->v.octetstring.octets, 308 IEEE80211_ADDR_LEN); 309 return (SNMP_ERR_NOERROR); 310 311 case LEAF_wlanIfaceLocalAddress: 312 if (val->v.octetstring.len != IEEE80211_ADDR_LEN) 313 return (SNMP_ERR_INCONS_VALUE); 314 ctx->scratch->ptr1 = malloc(IEEE80211_ADDR_LEN); 315 if (ctx->scratch->ptr1 == NULL) 316 return (SNMP_ERR_GENERR); 317 memcpy(ctx->scratch->ptr1, wif->dlmac, 318 IEEE80211_ADDR_LEN); 319 memcpy(wif->dlmac, val->v.octetstring.octets, 320 IEEE80211_ADDR_LEN); 321 return (SNMP_ERR_NOERROR); 322 323 case LEAF_wlanIfaceStatus: 324 ctx->scratch->int1 = wif->status; 325 wif->status = val->v.integer; 326 if (wif->status == RowStatus_active) { 327 rc = wlan_iface_create(wif); /* XXX */ 328 if (rc != SNMP_ERR_NOERROR) { 329 wif->status = ctx->scratch->int1; 330 return (rc); 331 } 332 } else if (wif->status == RowStatus_destroy) 333 return (wlan_iface_destroy(wif)); 334 else 335 wif->status = RowStatus_notReady; 336 return (SNMP_ERR_NOERROR); 337 338 case LEAF_wlanIfaceState: 339 ctx->scratch->int1 = wif->state; 340 wif->state = val->v.integer; 341 if (wif->status == RowStatus_active) 342 if (wlan_config_state(wif, 1) < 0) 343 return (SNMP_ERR_GENERR); 344 return (SNMP_ERR_NOERROR); 345 } 346 abort(); 347 348 case SNMP_OP_ROLLBACK: 349 if ((wif = wlan_get_snmp_interface(&val->var, sub)) == NULL) 350 return (SNMP_ERR_NOSUCHNAME); 351 switch (val->var.subs[sub - 1]) { 352 case LEAF_wlanIfaceName: 353 strlcpy(wif->wname, ctx->scratch->ptr1, IFNAMSIZ); 354 free(ctx->scratch->ptr1); 355 break; 356 357 case LEAF_wlanParentIfName: 358 strlcpy(wif->pname, ctx->scratch->ptr1, IFNAMSIZ); 359 free(ctx->scratch->ptr1); 360 break; 361 362 case LEAF_wlanIfaceOperatingMode: 363 wif->mode = ctx->scratch->int1; 364 break; 365 366 case LEAF_wlanIfaceFlags: 367 memcpy((uint8_t *)&wif->flags, ctx->scratch->ptr1, 368 sizeof(wif->flags)); 369 free(ctx->scratch->ptr1); 370 break; 371 372 case LEAF_wlanIfaceBssid: 373 memcpy(wif->dbssid, ctx->scratch->ptr1, 374 IEEE80211_ADDR_LEN); 375 free(ctx->scratch->ptr1); 376 break; 377 378 case LEAF_wlanIfaceLocalAddress: 379 memcpy(wif->dlmac, ctx->scratch->ptr1, 380 IEEE80211_ADDR_LEN); 381 free(ctx->scratch->ptr1); 382 break; 383 384 case LEAF_wlanIfaceStatus: 385 wif->status = ctx->scratch->int1; 386 if (ctx->scratch->int1 == RowStatus_active) 387 return (SNMP_ERR_GENERR); /* XXX: FIXME */ 388 else if (wif->internal != 0) 389 return (wlan_iface_destroy(wif)); 390 break; 391 392 case LEAF_wlanIfaceState: 393 wif->state = ctx->scratch->int1; 394 if (wif->status == RowStatus_active) 395 if (wlan_config_state(wif, 1) < 0) 396 return (SNMP_ERR_GENERR); 397 break; 398 } 399 return (SNMP_ERR_NOERROR); 400 401 case SNMP_OP_COMMIT: 402 switch (val->var.subs[sub - 1]) { 403 case LEAF_wlanIfaceName: 404 case LEAF_wlanParentIfName: 405 case LEAF_wlanIfaceFlags: 406 case LEAF_wlanIfaceBssid: 407 case LEAF_wlanIfaceLocalAddress: 408 free(ctx->scratch->ptr1); 409 /* FALLTHROUGH */ 410 default: 411 return (SNMP_ERR_NOERROR); 412 } 413 default: 414 abort(); 415 } 416 417 switch (val->var.subs[sub - 1]) { 418 case LEAF_wlanIfaceIndex: 419 val->v.integer = wif->index; 420 return (SNMP_ERR_NOERROR); 421 case LEAF_wlanIfaceName: 422 return (string_get(val, wif->wname, -1)); 423 case LEAF_wlanParentIfName: 424 return (string_get(val, wif->pname, -1)); 425 case LEAF_wlanIfaceOperatingMode: 426 val->v.integer = wif->mode; 427 return (SNMP_ERR_NOERROR); 428 case LEAF_wlanIfaceFlags: 429 return (bits_get(val, (uint8_t *)&wif->flags, 430 sizeof(wif->flags))); 431 case LEAF_wlanIfaceBssid: 432 return (string_get(val, wif->dbssid, IEEE80211_ADDR_LEN)); 433 case LEAF_wlanIfaceLocalAddress: 434 return (string_get(val, wif->dlmac, IEEE80211_ADDR_LEN)); 435 case LEAF_wlanIfaceStatus: 436 val->v.integer = wif->status; 437 return (SNMP_ERR_NOERROR); 438 case LEAF_wlanIfaceState: 439 val->v.integer = wif->state; 440 return (SNMP_ERR_NOERROR); 441 } 442 443 abort(); 444 } 445 446 int 447 op_wlan_if_parent(struct snmp_context *ctx __unused, struct snmp_value *val, 448 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 449 { 450 struct wlan_iface *wif; 451 452 wlan_update_interface_list(); 453 454 switch (op) { 455 case SNMP_OP_GET: 456 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 457 return (SNMP_ERR_NOSUCHNAME); 458 break; 459 case SNMP_OP_GETNEXT: 460 if ((wif = wlan_get_next_interface(&val->var, sub)) == NULL) 461 return (SNMP_ERR_NOSUCHNAME); 462 wlan_append_ifindex(&val->var, sub, wif); 463 break; 464 case SNMP_OP_SET: 465 return (SNMP_ERR_NOT_WRITEABLE); 466 case SNMP_OP_COMMIT: 467 /* FALLTHROUGH */ 468 case SNMP_OP_ROLLBACK: 469 /* FALLTHROUGH */ 470 default: 471 abort(); 472 } 473 474 switch (val->var.subs[sub - 1]) { 475 case LEAF_wlanIfParentDriverCapabilities: 476 return (bits_get(val, (uint8_t *)&wif->drivercaps, 477 sizeof(wif->drivercaps))); 478 case LEAF_wlanIfParentCryptoCapabilities: 479 return (bits_get(val, (uint8_t *)&wif->cryptocaps, 480 sizeof(wif->cryptocaps))); 481 case LEAF_wlanIfParentHTCapabilities: 482 return (bits_get(val, (uint8_t *)&wif->htcaps, 483 sizeof(wif->htcaps))); 484 } 485 486 abort(); 487 } 488 489 int 490 op_wlan_iface_config(struct snmp_context *ctx, struct snmp_value *val, 491 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 492 { 493 int intval, vlen, rc; 494 char *strval; 495 struct wlan_iface *wif; 496 497 wlan_update_interface_list(); 498 499 switch (op) { 500 case SNMP_OP_GET: 501 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 502 return (SNMP_ERR_NOSUCHNAME); 503 goto get_config; 504 505 case SNMP_OP_GETNEXT: 506 if ((wif = wlan_get_next_interface(&val->var, sub)) == NULL) 507 return (SNMP_ERR_NOSUCHNAME); 508 wlan_append_ifindex(&val->var, sub, wif); 509 goto get_config; 510 511 case SNMP_OP_SET: 512 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 513 return (SNMP_ERR_NOSUCHNAME); 514 515 intval = val->v.integer; 516 strval = NULL; 517 vlen = 0; 518 519 /* Simple sanity checks & save old data. */ 520 switch (val->var.subs[sub - 1]) { 521 case LEAF_wlanIfaceCountryCode: 522 if (val->v.octetstring.len != WLAN_COUNTRY_CODE_SIZE) 523 return (SNMP_ERR_INCONS_VALUE); 524 break; 525 case LEAF_wlanIfaceDesiredSsid: 526 if (val->v.octetstring.len > IEEE80211_NWID_LEN) 527 return (SNMP_ERR_INCONS_VALUE); 528 break; 529 case LEAF_wlanIfaceDesiredBssid: 530 if (val->v.octetstring.len != IEEE80211_ADDR_LEN) 531 return (SNMP_ERR_INCONS_VALUE); 532 break; 533 case LEAF_wlanIfacePacketBurst: 534 ctx->scratch->int1 = wif->packet_burst; 535 break; 536 case LEAF_wlanIfaceRegDomain: 537 ctx->scratch->int1 = wif->reg_domain; 538 break; 539 case LEAF_wlanIfaceDesiredChannel: 540 ctx->scratch->int1 = wif->desired_channel; 541 break; 542 case LEAF_wlanIfaceDynamicFreqSelection: 543 ctx->scratch->int1 = wif->dyn_frequency; 544 break; 545 case LEAF_wlanIfaceFastFrames: 546 ctx->scratch->int1 = wif->fast_frames; 547 break; 548 case LEAF_wlanIfaceDturbo: 549 ctx->scratch->int1 = wif->dturbo; 550 break; 551 case LEAF_wlanIfaceTxPower: 552 ctx->scratch->int1 = wif->tx_power; 553 break; 554 case LEAF_wlanIfaceFragmentThreshold: 555 ctx->scratch->int1 = wif->frag_threshold; 556 break; 557 case LEAF_wlanIfaceRTSThreshold: 558 ctx->scratch->int1 = wif->rts_threshold; 559 break; 560 case LEAF_wlanIfaceWlanPrivacySubscribe: 561 ctx->scratch->int1 = wif->priv_subscribe; 562 break; 563 case LEAF_wlanIfaceBgScan: 564 ctx->scratch->int1 = wif->bg_scan; 565 break; 566 case LEAF_wlanIfaceBgScanIdle: 567 ctx->scratch->int1 = wif->bg_scan_idle; 568 break; 569 case LEAF_wlanIfaceBgScanInterval: 570 ctx->scratch->int1 = wif->bg_scan_interval; 571 break; 572 case LEAF_wlanIfaceBeaconMissedThreshold: 573 ctx->scratch->int1 = wif->beacons_missed; 574 break; 575 case LEAF_wlanIfaceRoamingMode: 576 ctx->scratch->int1 = wif->roam_mode; 577 break; 578 case LEAF_wlanIfaceDot11d: 579 ctx->scratch->int1 = wif->dot11d; 580 break; 581 case LEAF_wlanIfaceDot11h: 582 ctx->scratch->int1 = wif->dot11h; 583 break; 584 case LEAF_wlanIfaceDynamicWds: 585 ctx->scratch->int1 = wif->dynamic_wds; 586 break; 587 case LEAF_wlanIfacePowerSave: 588 ctx->scratch->int1 = wif->power_save; 589 break; 590 case LEAF_wlanIfaceApBridge: 591 ctx->scratch->int1 = wif->ap_bridge; 592 break; 593 case LEAF_wlanIfaceBeaconInterval: 594 ctx->scratch->int1 = wif->beacon_interval; 595 break; 596 case LEAF_wlanIfaceDtimPeriod: 597 ctx->scratch->int1 = wif->dtim_period; 598 break; 599 case LEAF_wlanIfaceHideSsid: 600 ctx->scratch->int1 = wif->hide_ssid; 601 break; 602 case LEAF_wlanIfaceInactivityProccess: 603 ctx->scratch->int1 = wif->inact_process; 604 break; 605 case LEAF_wlanIfaceDot11gProtMode: 606 ctx->scratch->int1 = wif->do11g_protect; 607 break; 608 case LEAF_wlanIfaceDot11gPureMode: 609 ctx->scratch->int1 = wif->dot11g_pure; 610 break; 611 case LEAF_wlanIfaceDot11nPureMode: 612 ctx->scratch->int1 = wif->dot11n_pure; 613 break; 614 case LEAF_wlanIfaceDot11nAmpdu: 615 ctx->scratch->int1 = wif->ampdu; 616 break; 617 case LEAF_wlanIfaceDot11nAmpduDensity: 618 ctx->scratch->int1 = wif->ampdu_density; 619 break; 620 case LEAF_wlanIfaceDot11nAmpduLimit: 621 ctx->scratch->int1 = wif->ampdu_limit; 622 break; 623 case LEAF_wlanIfaceDot11nAmsdu: 624 ctx->scratch->int1 = wif->amsdu; 625 break; 626 case LEAF_wlanIfaceDot11nAmsduLimit: 627 ctx->scratch->int1 = wif->amsdu_limit; 628 break; 629 case LEAF_wlanIfaceDot11nHighThroughput: 630 ctx->scratch->int1 = wif->ht_enabled; 631 break; 632 case LEAF_wlanIfaceDot11nHTCompatible: 633 ctx->scratch->int1 = wif->ht_compatible; 634 break; 635 case LEAF_wlanIfaceDot11nHTProtMode: 636 ctx->scratch->int1 = wif->ht_prot_mode; 637 break; 638 case LEAF_wlanIfaceDot11nRIFS: 639 ctx->scratch->int1 = wif->rifs; 640 break; 641 case LEAF_wlanIfaceDot11nShortGI: 642 ctx->scratch->int1 = wif->short_gi; 643 break; 644 case LEAF_wlanIfaceDot11nSMPSMode: 645 ctx->scratch->int1 = wif->smps_mode; 646 break; 647 case LEAF_wlanIfaceTdmaSlot: 648 ctx->scratch->int1 = wif->tdma_slot; 649 break; 650 case LEAF_wlanIfaceTdmaSlotCount: 651 ctx->scratch->int1 = wif->tdma_slot_count; 652 break; 653 case LEAF_wlanIfaceTdmaSlotLength: 654 ctx->scratch->int1 = wif->tdma_slot_length; 655 break; 656 case LEAF_wlanIfaceTdmaBeaconInterval: 657 ctx->scratch->int1 = wif->tdma_binterval; 658 break; 659 default: 660 abort(); 661 } 662 663 if (val->syntax != SNMP_SYNTAX_OCTETSTRING) 664 goto set_config; 665 666 ctx->scratch->int1 = val->v.octetstring.len; 667 ctx->scratch->ptr1 = malloc(val->v.octetstring.len + 1); 668 if (ctx->scratch->ptr1 == NULL) 669 return (SNMP_ERR_GENERR); /* XXX */ 670 if (val->var.subs[sub - 1] == LEAF_wlanIfaceDesiredSsid) 671 strlcpy(ctx->scratch->ptr1, val->v.octetstring.octets, 672 val->v.octetstring.len + 1); 673 else 674 memcpy(ctx->scratch->ptr1, val->v.octetstring.octets, 675 val->v.octetstring.len); 676 strval = val->v.octetstring.octets; 677 vlen = val->v.octetstring.len; 678 goto set_config; 679 680 case SNMP_OP_ROLLBACK: 681 intval = ctx->scratch->int1; 682 strval = NULL; 683 vlen = 0; 684 685 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 686 return (SNMP_ERR_NOSUCHNAME); 687 switch (val->var.subs[sub - 1]) { 688 case LEAF_wlanIfaceCountryCode: 689 case LEAF_wlanIfaceDesiredSsid: 690 case LEAF_wlanIfaceDesiredBssid: 691 strval = ctx->scratch->ptr1; 692 vlen = ctx->scratch->int1; 693 break; 694 default: 695 break; 696 } 697 goto set_config; 698 699 case SNMP_OP_COMMIT: 700 switch (val->var.subs[sub - 1]) { 701 case LEAF_wlanIfaceCountryCode: 702 case LEAF_wlanIfaceDesiredSsid: 703 case LEAF_wlanIfaceDesiredBssid: 704 free(ctx->scratch->ptr1); 705 /* FALLTHROUGH */ 706 default: 707 return (SNMP_ERR_NOERROR); 708 } 709 } 710 abort(); 711 712 get_config: 713 714 if (wlan_config_get_ioctl(wif, val->var.subs[sub - 1]) < 0) 715 return (SNMP_ERR_GENERR); 716 717 switch (val->var.subs[sub - 1]) { 718 case LEAF_wlanIfacePacketBurst: 719 val->v.integer = wif->packet_burst; 720 break; 721 case LEAF_wlanIfaceCountryCode: 722 return (string_get(val, wif->country_code, 723 WLAN_COUNTRY_CODE_SIZE)); 724 case LEAF_wlanIfaceRegDomain: 725 val->v.integer = wif->reg_domain; 726 break; 727 case LEAF_wlanIfaceDesiredSsid: 728 return (string_get(val, wif->desired_ssid, -1)); 729 case LEAF_wlanIfaceDesiredChannel: 730 val->v.integer = wif->desired_channel; 731 break; 732 case LEAF_wlanIfaceDynamicFreqSelection: 733 val->v.integer = wif->dyn_frequency; 734 break; 735 case LEAF_wlanIfaceFastFrames: 736 val->v.integer = wif->fast_frames; 737 break; 738 case LEAF_wlanIfaceDturbo: 739 val->v.integer = wif->dturbo; 740 break; 741 case LEAF_wlanIfaceTxPower: 742 val->v.integer = wif->tx_power; 743 break; 744 case LEAF_wlanIfaceFragmentThreshold: 745 val->v.integer = wif->frag_threshold; 746 break; 747 case LEAF_wlanIfaceRTSThreshold: 748 val->v.integer = wif->rts_threshold; 749 break; 750 case LEAF_wlanIfaceWlanPrivacySubscribe: 751 val->v.integer = wif->priv_subscribe; 752 break; 753 case LEAF_wlanIfaceBgScan: 754 val->v.integer = wif->bg_scan; 755 break; 756 case LEAF_wlanIfaceBgScanIdle: 757 val->v.integer = wif->bg_scan_idle; 758 break; 759 case LEAF_wlanIfaceBgScanInterval: 760 val->v.integer = wif->bg_scan_interval; 761 break; 762 case LEAF_wlanIfaceBeaconMissedThreshold: 763 val->v.integer = wif->beacons_missed; 764 break; 765 case LEAF_wlanIfaceDesiredBssid: 766 return (string_get(val, wif->desired_bssid, 767 IEEE80211_ADDR_LEN)); 768 case LEAF_wlanIfaceRoamingMode: 769 val->v.integer = wif->roam_mode; 770 break; 771 case LEAF_wlanIfaceDot11d: 772 val->v.integer = wif->dot11d; 773 break; 774 case LEAF_wlanIfaceDot11h: 775 val->v.integer = wif->dot11h; 776 break; 777 case LEAF_wlanIfaceDynamicWds: 778 val->v.integer = wif->dynamic_wds; 779 break; 780 case LEAF_wlanIfacePowerSave: 781 val->v.integer = wif->power_save; 782 break; 783 case LEAF_wlanIfaceApBridge: 784 val->v.integer = wif->ap_bridge; 785 break; 786 case LEAF_wlanIfaceBeaconInterval: 787 val->v.integer = wif->beacon_interval; 788 break; 789 case LEAF_wlanIfaceDtimPeriod: 790 val->v.integer = wif->dtim_period; 791 break; 792 case LEAF_wlanIfaceHideSsid: 793 val->v.integer = wif->hide_ssid; 794 break; 795 case LEAF_wlanIfaceInactivityProccess: 796 val->v.integer = wif->inact_process; 797 break; 798 case LEAF_wlanIfaceDot11gProtMode: 799 val->v.integer = wif->do11g_protect; 800 break; 801 case LEAF_wlanIfaceDot11gPureMode: 802 val->v.integer = wif->dot11g_pure; 803 break; 804 case LEAF_wlanIfaceDot11nPureMode: 805 val->v.integer = wif->dot11n_pure; 806 break; 807 case LEAF_wlanIfaceDot11nAmpdu: 808 val->v.integer = wif->ampdu; 809 break; 810 case LEAF_wlanIfaceDot11nAmpduDensity: 811 val->v.integer = wif->ampdu_density; 812 break; 813 case LEAF_wlanIfaceDot11nAmpduLimit: 814 val->v.integer = wif->ampdu_limit; 815 break; 816 case LEAF_wlanIfaceDot11nAmsdu: 817 val->v.integer = wif->amsdu; 818 break; 819 case LEAF_wlanIfaceDot11nAmsduLimit: 820 val->v.integer = wif->amsdu_limit; 821 break; 822 case LEAF_wlanIfaceDot11nHighThroughput: 823 val->v.integer = wif->ht_enabled; 824 break; 825 case LEAF_wlanIfaceDot11nHTCompatible: 826 val->v.integer = wif->ht_compatible; 827 break; 828 case LEAF_wlanIfaceDot11nHTProtMode: 829 val->v.integer = wif->ht_prot_mode; 830 break; 831 case LEAF_wlanIfaceDot11nRIFS: 832 val->v.integer = wif->rifs; 833 break; 834 case LEAF_wlanIfaceDot11nShortGI: 835 val->v.integer = wif->short_gi; 836 break; 837 case LEAF_wlanIfaceDot11nSMPSMode: 838 val->v.integer = wif->smps_mode; 839 break; 840 case LEAF_wlanIfaceTdmaSlot: 841 val->v.integer = wif->tdma_slot; 842 break; 843 case LEAF_wlanIfaceTdmaSlotCount: 844 val->v.integer = wif->tdma_slot_count; 845 break; 846 case LEAF_wlanIfaceTdmaSlotLength: 847 val->v.integer = wif->tdma_slot_length; 848 break; 849 case LEAF_wlanIfaceTdmaBeaconInterval: 850 val->v.integer = wif->tdma_binterval; 851 break; 852 } 853 854 return (SNMP_ERR_NOERROR); 855 856 set_config: 857 rc = wlan_config_set_ioctl(wif, val->var.subs[sub - 1], intval, 858 strval, vlen); 859 860 if (op == SNMP_OP_ROLLBACK) { 861 switch (val->var.subs[sub - 1]) { 862 case LEAF_wlanIfaceCountryCode: 863 case LEAF_wlanIfaceDesiredSsid: 864 case LEAF_wlanIfaceDesiredBssid: 865 free(ctx->scratch->ptr1); 866 /* FALLTHROUGH */ 867 default: 868 break; 869 } 870 } 871 872 if (rc < 0) 873 return (SNMP_ERR_GENERR); 874 875 return (SNMP_ERR_NOERROR); 876 } 877 878 int 879 op_wlan_if_peer(struct snmp_context *ctx, struct snmp_value *val, uint32_t sub, 880 uint32_t iidx __unused, enum snmp_op op) 881 { 882 struct wlan_peer *wip; 883 struct wlan_iface *wif; 884 885 wlan_update_interface_list(); 886 wlan_update_peers(); 887 888 switch (op) { 889 case SNMP_OP_GET: 890 if ((wip = wlan_get_peer(&val->var, sub, &wif)) == NULL) 891 return (SNMP_ERR_NOSUCHNAME); 892 break; 893 case SNMP_OP_GETNEXT: 894 if ((wip = wlan_get_next_peer(&val->var, sub, &wif)) == NULL) 895 return (SNMP_ERR_NOSUCHNAME); 896 wlan_append_mac_index(&val->var, sub, wif->wname, wip->pmac); 897 break; 898 case SNMP_OP_SET: 899 if ((wip = wlan_get_peer(&val->var, sub, &wif)) == NULL) 900 return (SNMP_ERR_NOSUCHNAME); 901 if (val->var.subs[sub - 1] != LEAF_wlanIfacePeerVlanTag) 902 return (SNMP_ERR_GENERR); 903 ctx->scratch->int1 = wip->vlan; 904 if (wlan_peer_set_vlan(wif, wip, val->v.integer) < 0) 905 return (SNMP_ERR_GENERR); 906 return (SNMP_ERR_NOERROR); 907 case SNMP_OP_COMMIT: 908 return (SNMP_ERR_NOERROR); 909 case SNMP_OP_ROLLBACK: 910 if ((wip = wlan_get_peer(&val->var, sub, &wif)) == NULL) 911 return (SNMP_ERR_NOSUCHNAME); 912 if (val->var.subs[sub - 1] != LEAF_wlanIfacePeerVlanTag) 913 return (SNMP_ERR_GENERR); 914 if (wlan_peer_set_vlan(wif, wip, ctx->scratch->int1) < 0) 915 return (SNMP_ERR_GENERR); 916 return (SNMP_ERR_NOERROR); 917 default: 918 abort(); 919 } 920 921 switch (val->var.subs[sub - 1]) { 922 case LEAF_wlanIfacePeerAddress: 923 return (string_get(val, wip->pmac, IEEE80211_ADDR_LEN)); 924 case LEAF_wlanIfacePeerAssociationId: 925 val->v.integer = wip->associd; 926 break; 927 case LEAF_wlanIfacePeerVlanTag: 928 val->v.integer = wip->vlan; 929 break; 930 case LEAF_wlanIfacePeerFrequency: 931 val->v.integer = wip->frequency; 932 break; 933 case LEAF_wlanIfacePeerCurrentTXRate: 934 val->v.integer = wip->txrate; 935 break; 936 case LEAF_wlanIfacePeerRxSignalStrength: 937 val->v.integer = wip->rssi; 938 break; 939 case LEAF_wlanIfacePeerIdleTimer: 940 val->v.integer = wip->idle; 941 break; 942 case LEAF_wlanIfacePeerTxSequenceNo: 943 val->v.integer = wip->txseqs; 944 break; 945 case LEAF_wlanIfacePeerRxSequenceNo: 946 val->v.integer = wip->rxseqs; 947 break; 948 case LEAF_wlanIfacePeerTxPower: 949 val->v.integer = wip->txpower; 950 break; 951 case LEAF_wlanIfacePeerCapabilities: 952 return (bits_get(val, (uint8_t *)&wip->capinfo, 953 sizeof(wip->capinfo))); 954 case LEAF_wlanIfacePeerFlags: 955 return (bits_get(val, (uint8_t *)&wip->state, 956 sizeof(wip->state))); 957 default: 958 abort(); 959 } 960 961 return (SNMP_ERR_NOERROR); 962 } 963 964 int 965 op_wlan_channels(struct snmp_context *ctx __unused, struct snmp_value *val, 966 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 967 { 968 int32_t bits; 969 struct ieee80211_channel *channel; 970 struct wlan_iface *wif; 971 972 wlan_update_interface_list(); 973 wlan_update_channels(); 974 975 switch (op) { 976 case SNMP_OP_GET: 977 if ((channel = wlan_get_channel(&val->var, sub, &wif)) == NULL) 978 return (SNMP_ERR_NOSUCHNAME); 979 break; 980 case SNMP_OP_GETNEXT: 981 channel = wlan_get_next_channel(&val->var, sub, &wif); 982 if (channel == NULL || wif == NULL) 983 return (SNMP_ERR_NOSUCHNAME); 984 wlan_append_channel_index(&val->var, sub, wif, channel); 985 break; 986 case SNMP_OP_SET: 987 return (SNMP_ERR_NOT_WRITEABLE); 988 case SNMP_OP_COMMIT: 989 /* FALLTHROUGH */ 990 case SNMP_OP_ROLLBACK: 991 /* FALLTHROUGH */ 992 default: 993 abort(); 994 } 995 996 switch (val->var.subs[sub - 1]) { 997 case LEAF_wlanIfaceChannelIeeeId: 998 val->v.integer = channel->ic_ieee; 999 break; 1000 case LEAF_wlanIfaceChannelType: 1001 val->v.integer = wlan_get_channel_type(channel); 1002 break; 1003 case LEAF_wlanIfaceChannelFlags: 1004 bits = wlan_channel_flags_to_snmp(channel->ic_flags); 1005 return (bits_get(val, (uint8_t *)&bits, sizeof(bits))); 1006 case LEAF_wlanIfaceChannelFrequency: 1007 val->v.integer = channel->ic_freq; 1008 break; 1009 case LEAF_wlanIfaceChannelMaxRegPower: 1010 val->v.integer = channel->ic_maxregpower; 1011 break; 1012 case LEAF_wlanIfaceChannelMaxTxPower: 1013 val->v.integer = channel->ic_maxpower; 1014 break; 1015 case LEAF_wlanIfaceChannelMinTxPower: 1016 val->v.integer = channel->ic_minpower; 1017 break; 1018 case LEAF_wlanIfaceChannelState: 1019 bits = wlan_channel_state_to_snmp(channel->ic_state); 1020 return (bits_get(val, (uint8_t *)&bits, sizeof(bits))); 1021 case LEAF_wlanIfaceChannelHTExtension: 1022 val->v.integer = channel->ic_extieee; 1023 break; 1024 case LEAF_wlanIfaceChannelMaxAntennaGain: 1025 val->v.integer = channel->ic_maxantgain; 1026 break; 1027 } 1028 1029 return (SNMP_ERR_NOERROR); 1030 } 1031 1032 int 1033 op_wlan_roam_params(struct snmp_context *ctx __unused, struct snmp_value *val, 1034 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1035 { 1036 uint32_t phy; 1037 struct ieee80211_roamparam *rparam; 1038 struct wlan_iface *wif; 1039 1040 wlan_update_interface_list(); 1041 wlan_update_roam_params(); 1042 1043 switch (op) { 1044 case SNMP_OP_GET: 1045 rparam = wlan_get_roam_param(&val->var, sub, &wif); 1046 if (rparam == NULL) 1047 return (SNMP_ERR_NOSUCHNAME); 1048 break; 1049 case SNMP_OP_GETNEXT: 1050 rparam = wlan_get_next_roam_param(&val->var, sub, &wif, &phy); 1051 if (rparam == NULL || wif == NULL) 1052 return (SNMP_ERR_NOSUCHNAME); 1053 wlan_append_phy_index(&val->var, sub, wif->wname, phy); 1054 break; 1055 case SNMP_OP_SET: 1056 return (SNMP_ERR_NOT_WRITEABLE); 1057 case SNMP_OP_COMMIT: 1058 /* FALLTHROUGH */ 1059 case SNMP_OP_ROLLBACK: 1060 /* FALLTHROUGH */ 1061 default: 1062 abort(); 1063 } 1064 1065 switch (val->var.subs[sub - 1]) { 1066 case LEAF_wlanIfRoamRxSignalStrength: 1067 val->v.integer = rparam->rssi/2; 1068 break; 1069 case LEAF_wlanIfRoamTxRateThreshold: 1070 val->v.integer = rparam->rate/2; 1071 break; 1072 default: 1073 abort(); 1074 } 1075 1076 return (SNMP_ERR_NOERROR); 1077 } 1078 1079 int 1080 op_wlan_tx_params(struct snmp_context *ctx, struct snmp_value *val, 1081 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1082 { 1083 uint32_t phy; 1084 struct ieee80211_txparam *txparam; 1085 struct wlan_iface *wif; 1086 1087 wlan_update_interface_list(); 1088 wlan_update_tx_params(); 1089 1090 switch (op) { 1091 case SNMP_OP_GET: 1092 txparam = wlan_get_tx_param(&val->var, sub, &wif, &phy); 1093 if (txparam == NULL) 1094 return (SNMP_ERR_NOSUCHNAME); 1095 goto get_txparams; 1096 1097 case SNMP_OP_GETNEXT: 1098 txparam = wlan_get_next_tx_param(&val->var, sub, &wif, &phy); 1099 if (txparam == NULL || wif == NULL) 1100 return (SNMP_ERR_NOSUCHNAME); 1101 wlan_append_phy_index(&val->var, sub, wif->wname, phy); 1102 goto get_txparams; 1103 1104 case SNMP_OP_SET: 1105 txparam = wlan_get_tx_param(&val->var, sub, &wif, &phy); 1106 if (txparam == NULL || wif == NULL) 1107 return (SNMP_ERR_NOSUCHNAME); 1108 switch (val->var.subs[sub - 1]) { 1109 case LEAF_wlanIfTxUnicastRate: 1110 ctx->scratch->int1 = txparam->ucastrate; 1111 txparam->ucastrate = val->v.integer * 2; 1112 break; 1113 case LEAF_wlanIfTxMcastRate: 1114 ctx->scratch->int1 = txparam->mcastrate; 1115 txparam->mcastrate = val->v.integer * 2; 1116 break; 1117 case LEAF_wlanIfTxMgmtRate: 1118 ctx->scratch->int1 = txparam->mgmtrate; 1119 txparam->mgmtrate = val->v.integer * 2; 1120 break; 1121 case LEAF_wlanIfTxMaxRetryCount: 1122 ctx->scratch->int1 = txparam->maxretry; 1123 txparam->maxretry = val->v.integer; 1124 break; 1125 default: 1126 abort(); 1127 } 1128 if (wlan_set_tx_params(wif, phy) < 0) 1129 return (SNMP_ERR_GENERR); 1130 return (SNMP_ERR_NOERROR); 1131 1132 case SNMP_OP_COMMIT: 1133 return (SNMP_ERR_NOERROR); 1134 1135 case SNMP_OP_ROLLBACK: 1136 txparam = wlan_get_tx_param(&val->var, sub, &wif, &phy); 1137 if (txparam == NULL || wif == NULL) 1138 return (SNMP_ERR_NOSUCHNAME); 1139 switch (val->var.subs[sub - 1]) { 1140 case LEAF_wlanIfTxUnicastRate: 1141 txparam->ucastrate = ctx->scratch->int1; 1142 break; 1143 case LEAF_wlanIfTxMcastRate: 1144 txparam->mcastrate = ctx->scratch->int1; 1145 break; 1146 case LEAF_wlanIfTxMgmtRate: 1147 txparam->mgmtrate = ctx->scratch->int1; 1148 break; 1149 case LEAF_wlanIfTxMaxRetryCount: 1150 txparam->maxretry = ctx->scratch->int1; 1151 break; 1152 default: 1153 abort(); 1154 } 1155 if (wlan_set_tx_params(wif, phy) < 0) 1156 return (SNMP_ERR_GENERR); 1157 return (SNMP_ERR_NOERROR); 1158 default: 1159 abort(); 1160 } 1161 1162 get_txparams: 1163 switch (val->var.subs[sub - 1]) { 1164 case LEAF_wlanIfTxUnicastRate: 1165 val->v.integer = txparam->ucastrate / 2; 1166 break; 1167 case LEAF_wlanIfTxMcastRate: 1168 val->v.integer = txparam->mcastrate / 2; 1169 break; 1170 case LEAF_wlanIfTxMgmtRate: 1171 val->v.integer = txparam->mgmtrate / 2; 1172 break; 1173 case LEAF_wlanIfTxMaxRetryCount: 1174 val->v.integer = txparam->maxretry; 1175 break; 1176 default: 1177 abort(); 1178 } 1179 1180 return (SNMP_ERR_NOERROR); 1181 } 1182 1183 int 1184 op_wlan_scan_config(struct snmp_context *ctx, struct snmp_value *val, 1185 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1186 { 1187 struct wlan_iface *wif; 1188 1189 wlan_update_interface_list(); 1190 1191 switch (op) { 1192 case SNMP_OP_GET: 1193 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1194 return (SNMP_ERR_NOSUCHNAME); 1195 break; 1196 1197 case SNMP_OP_GETNEXT: 1198 if ((wif = wlan_get_next_interface(&val->var, sub)) == NULL) 1199 return (SNMP_ERR_NOSUCHNAME); 1200 wlan_append_ifindex(&val->var, sub, wif); 1201 break; 1202 1203 case SNMP_OP_SET: 1204 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1205 return (SNMP_ERR_NOSUCHNAME); 1206 if (wif->scan_status == wlanScanConfigStatus_running 1207 && val->var.subs[sub - 1] != LEAF_wlanScanConfigStatus) 1208 return (SNMP_ERR_INCONS_VALUE); 1209 switch (val->var.subs[sub - 1]) { 1210 case LEAF_wlanScanFlags: 1211 ctx->scratch->int1 = wif->scan_flags; 1212 wif->scan_flags = val->v.integer; 1213 break; 1214 case LEAF_wlanScanDuration: 1215 ctx->scratch->int1 = wif->scan_duration; 1216 wif->scan_duration = val->v.integer; 1217 break; 1218 case LEAF_wlanScanMinChannelDwellTime: 1219 ctx->scratch->int1 = wif->scan_mindwell; 1220 wif->scan_mindwell = val->v.integer; 1221 break; 1222 case LEAF_wlanScanMaxChannelDwellTime: 1223 ctx->scratch->int1 = wif->scan_maxdwell; 1224 wif->scan_maxdwell = val->v.integer; 1225 break; 1226 case LEAF_wlanScanConfigStatus: 1227 if (val->v.integer == wlanScanConfigStatus_running || 1228 val->v.integer == wlanScanConfigStatus_cancel) { 1229 ctx->scratch->int1 = wif->scan_status; 1230 wif->scan_status = val->v.integer; 1231 break; 1232 } 1233 return (SNMP_ERR_INCONS_VALUE); 1234 } 1235 return (SNMP_ERR_NOERROR); 1236 1237 case SNMP_OP_COMMIT: 1238 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1239 return (SNMP_ERR_NOSUCHNAME); 1240 if (val->var.subs[sub - 1] == LEAF_wlanScanConfigStatus) 1241 if (wif->scan_status == wlanScanConfigStatus_running) 1242 (void)wlan_set_scan_config(wif); /* XXX */ 1243 return (SNMP_ERR_NOERROR); 1244 1245 case SNMP_OP_ROLLBACK: 1246 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1247 return (SNMP_ERR_NOSUCHNAME); 1248 switch (val->var.subs[sub - 1]) { 1249 case LEAF_wlanScanFlags: 1250 wif->scan_flags = ctx->scratch->int1; 1251 break; 1252 case LEAF_wlanScanDuration: 1253 wif->scan_duration = ctx->scratch->int1; 1254 break; 1255 case LEAF_wlanScanMinChannelDwellTime: 1256 wif->scan_mindwell = ctx->scratch->int1; 1257 break; 1258 case LEAF_wlanScanMaxChannelDwellTime: 1259 wif->scan_maxdwell = ctx->scratch->int1; 1260 break; 1261 case LEAF_wlanScanConfigStatus: 1262 wif->scan_status = ctx->scratch->int1; 1263 break; 1264 } 1265 return (SNMP_ERR_NOERROR); 1266 default: 1267 abort(); 1268 } 1269 1270 switch (val->var.subs[sub - 1]) { 1271 case LEAF_wlanScanFlags: 1272 val->v.integer = wif->scan_flags; 1273 break; 1274 case LEAF_wlanScanDuration: 1275 val->v.integer = wif->scan_duration; 1276 break; 1277 case LEAF_wlanScanMinChannelDwellTime: 1278 val->v.integer = wif->scan_mindwell; 1279 break; 1280 case LEAF_wlanScanMaxChannelDwellTime: 1281 val->v.integer = wif->scan_maxdwell; 1282 break; 1283 case LEAF_wlanScanConfigStatus: 1284 val->v.integer = wif->scan_status; 1285 break; 1286 } 1287 1288 return (SNMP_ERR_NOERROR); 1289 } 1290 1291 int 1292 op_wlan_scan_results(struct snmp_context *ctx __unused, struct snmp_value *val, 1293 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1294 { 1295 struct wlan_scan_result *sr; 1296 struct wlan_iface *wif; 1297 1298 wlan_update_interface_list(); 1299 wlan_scan_update_results(); 1300 1301 switch (op) { 1302 case SNMP_OP_GET: 1303 if ((sr = wlan_get_scanr(&val->var, sub, &wif)) == NULL) 1304 return (SNMP_ERR_NOSUCHNAME); 1305 break; 1306 1307 case SNMP_OP_GETNEXT: 1308 if ((sr = wlan_get_next_scanr(&val->var, sub, &wif)) == NULL) 1309 return (SNMP_ERR_NOSUCHNAME); 1310 wlan_append_scanr_index(&val->var, sub, wif->wname, sr->ssid, 1311 sr->bssid); 1312 break; 1313 1314 case SNMP_OP_SET: 1315 return (SNMP_ERR_NOT_WRITEABLE); 1316 case SNMP_OP_COMMIT: 1317 /* FALLTHROUGH */ 1318 case SNMP_OP_ROLLBACK: 1319 /* FALLTHROUGH */ 1320 default: 1321 abort(); 1322 } 1323 1324 switch (val->var.subs[sub - 1]) { 1325 case LEAF_wlanScanResultID: 1326 return (string_get(val, sr->ssid, -1)); 1327 case LEAF_wlanScanResultBssid: 1328 return (string_get(val, sr->bssid, IEEE80211_ADDR_LEN)); 1329 case LEAF_wlanScanResultChannel: 1330 val->v.integer = sr->opchannel; /* XXX */ 1331 break; 1332 case LEAF_wlanScanResultRate: 1333 val->v.integer = sr->rssi; 1334 break; 1335 case LEAF_wlanScanResultNoise: 1336 val->v.integer = sr->noise; 1337 break; 1338 case LEAF_wlanScanResultBeaconInterval: 1339 val->v.integer = sr->bintval; 1340 break; 1341 case LEAF_wlanScanResultCapabilities: 1342 return (bits_get(val, &sr->capinfo, sizeof(sr->capinfo))); 1343 default: 1344 abort(); 1345 } 1346 1347 return (SNMP_ERR_NOERROR); 1348 } 1349 1350 int 1351 op_wlan_iface_stats(struct snmp_context *ctx __unused, struct snmp_value *val, 1352 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1353 { 1354 struct wlan_iface *wif; 1355 1356 wlan_update_interface_list(); 1357 1358 switch (op) { 1359 case SNMP_OP_GET: 1360 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1361 return (SNMP_ERR_NOSUCHNAME); 1362 break; 1363 case SNMP_OP_GETNEXT: 1364 if ((wif = wlan_get_next_interface(&val->var, sub)) == NULL) 1365 return (SNMP_ERR_NOSUCHNAME); 1366 wlan_append_ifindex(&val->var, sub, wif); 1367 break; 1368 case SNMP_OP_SET: 1369 /* XXX: LEAF_wlanStatsReset */ 1370 return (SNMP_ERR_NOT_WRITEABLE); 1371 case SNMP_OP_COMMIT: 1372 /* FALLTHROUGH */ 1373 case SNMP_OP_ROLLBACK: 1374 /* FALLTHROUGH */ 1375 default: 1376 abort(); 1377 } 1378 1379 if (wlan_get_stats(wif) < 0) 1380 return (SNMP_ERR_GENERR); 1381 1382 switch (val->var.subs[sub - 1]) { 1383 case LEAF_wlanStatsRxBadVersion: 1384 val->v.uint32 = wif->stats.is_rx_badversion; 1385 break; 1386 case LEAF_wlanStatsRxTooShort: 1387 val->v.uint32 = wif->stats.is_rx_tooshort; 1388 break; 1389 case LEAF_wlanStatsRxWrongBssid: 1390 val->v.uint32 = wif->stats.is_rx_wrongbss; 1391 break; 1392 case LEAF_wlanStatsRxDiscardedDups: 1393 val->v.uint32 = wif->stats.is_rx_dup; 1394 break; 1395 case LEAF_wlanStatsRxWrongDir: 1396 val->v.uint32 = wif->stats.is_rx_wrongdir; 1397 break; 1398 case LEAF_wlanStatsRxDiscardMcastEcho: 1399 val->v.uint32 = wif->stats.is_rx_mcastecho; 1400 break; 1401 case LEAF_wlanStatsRxDiscardNoAssoc: 1402 val->v.uint32 = wif->stats.is_rx_notassoc; 1403 break; 1404 case LEAF_wlanStatsRxWepNoPrivacy: 1405 val->v.uint32 = wif->stats.is_rx_noprivacy; 1406 break; 1407 case LEAF_wlanStatsRxWepUnencrypted: 1408 val->v.uint32 = wif->stats.is_rx_unencrypted; 1409 break; 1410 case LEAF_wlanStatsRxWepFailed: 1411 val->v.uint32 = wif->stats.is_rx_wepfail; 1412 break; 1413 case LEAF_wlanStatsRxDecapsulationFailed: 1414 val->v.uint32 = wif->stats.is_rx_decap; 1415 break; 1416 case LEAF_wlanStatsRxDiscardMgmt: 1417 val->v.uint32 = wif->stats.is_rx_mgtdiscard; 1418 break; 1419 case LEAF_wlanStatsRxControl: 1420 val->v.uint32 = wif->stats.is_rx_ctl; 1421 break; 1422 case LEAF_wlanStatsRxBeacon: 1423 val->v.uint32 = wif->stats.is_rx_beacon; 1424 break; 1425 case LEAF_wlanStatsRxRateSetTooBig: 1426 val->v.uint32 = wif->stats.is_rx_rstoobig; 1427 break; 1428 case LEAF_wlanStatsRxElemMissing: 1429 val->v.uint32 = wif->stats.is_rx_elem_missing; 1430 break; 1431 case LEAF_wlanStatsRxElemTooBig: 1432 val->v.uint32 = wif->stats.is_rx_elem_toobig; 1433 break; 1434 case LEAF_wlanStatsRxElemTooSmall: 1435 val->v.uint32 = wif->stats.is_rx_elem_toosmall; 1436 break; 1437 case LEAF_wlanStatsRxElemUnknown: 1438 val->v.uint32 = wif->stats.is_rx_elem_unknown; 1439 break; 1440 case LEAF_wlanStatsRxChannelMismatch: 1441 val->v.uint32 = wif->stats.is_rx_chanmismatch; 1442 break; 1443 case LEAF_wlanStatsRxDropped: 1444 val->v.uint32 = wif->stats.is_rx_nodealloc; 1445 break; 1446 case LEAF_wlanStatsRxSsidMismatch: 1447 val->v.uint32 = wif->stats.is_rx_ssidmismatch; 1448 break; 1449 case LEAF_wlanStatsRxAuthNotSupported: 1450 val->v.uint32 = wif->stats.is_rx_auth_unsupported; 1451 break; 1452 case LEAF_wlanStatsRxAuthFailed: 1453 val->v.uint32 = wif->stats.is_rx_auth_fail; 1454 break; 1455 case LEAF_wlanStatsRxAuthCM: 1456 val->v.uint32 = wif->stats.is_rx_auth_countermeasures; 1457 break; 1458 case LEAF_wlanStatsRxAssocWrongBssid: 1459 val->v.uint32 = wif->stats.is_rx_assoc_bss; 1460 break; 1461 case LEAF_wlanStatsRxAssocNoAuth: 1462 val->v.uint32 = wif->stats.is_rx_assoc_notauth; 1463 break; 1464 case LEAF_wlanStatsRxAssocCapMismatch: 1465 val->v.uint32 = wif->stats.is_rx_assoc_capmismatch; 1466 break; 1467 case LEAF_wlanStatsRxAssocNoRateMatch: 1468 val->v.uint32 = wif->stats.is_rx_assoc_norate; 1469 break; 1470 case LEAF_wlanStatsRxBadWpaIE: 1471 val->v.uint32 = wif->stats.is_rx_assoc_badwpaie; 1472 break; 1473 case LEAF_wlanStatsRxDeauthenticate: 1474 val->v.uint32 = wif->stats.is_rx_deauth; 1475 break; 1476 case LEAF_wlanStatsRxDisassociate: 1477 val->v.uint32 = wif->stats.is_rx_disassoc; 1478 break; 1479 case LEAF_wlanStatsRxUnknownSubtype: 1480 val->v.uint32 = wif->stats.is_rx_badsubtype; 1481 break; 1482 case LEAF_wlanStatsRxFailedNoBuf: 1483 val->v.uint32 = wif->stats.is_rx_nobuf; 1484 break; 1485 case LEAF_wlanStatsRxBadAuthRequest: 1486 val->v.uint32 = wif->stats.is_rx_bad_auth; 1487 break; 1488 case LEAF_wlanStatsRxUnAuthorized: 1489 val->v.uint32 = wif->stats.is_rx_unauth; 1490 break; 1491 case LEAF_wlanStatsRxBadKeyId: 1492 val->v.uint32 = wif->stats.is_rx_badkeyid; 1493 break; 1494 case LEAF_wlanStatsRxCCMPSeqViolation: 1495 val->v.uint32 = wif->stats.is_rx_ccmpreplay; 1496 break; 1497 case LEAF_wlanStatsRxCCMPBadFormat: 1498 val->v.uint32 = wif->stats.is_rx_ccmpformat; 1499 break; 1500 case LEAF_wlanStatsRxCCMPFailedMIC: 1501 val->v.uint32 = wif->stats.is_rx_ccmpmic; 1502 break; 1503 case LEAF_wlanStatsRxTKIPSeqViolation: 1504 val->v.uint32 = wif->stats.is_rx_tkipreplay; 1505 break; 1506 case LEAF_wlanStatsRxTKIPBadFormat: 1507 val->v.uint32 = wif->stats.is_rx_tkipformat; 1508 break; 1509 case LEAF_wlanStatsRxTKIPFailedMIC: 1510 val->v.uint32 = wif->stats.is_rx_tkipmic; 1511 break; 1512 case LEAF_wlanStatsRxTKIPFailedICV: 1513 val->v.uint32 = wif->stats.is_rx_tkipicv; 1514 break; 1515 case LEAF_wlanStatsRxDiscardACL: 1516 val->v.uint32 = wif->stats.is_rx_acl; 1517 break; 1518 case LEAF_wlanStatsTxFailedNoBuf: 1519 val->v.uint32 = wif->stats.is_tx_nobuf; 1520 break; 1521 case LEAF_wlanStatsTxFailedNoNode: 1522 val->v.uint32 = wif->stats.is_tx_nonode; 1523 break; 1524 case LEAF_wlanStatsTxUnknownMgmt: 1525 val->v.uint32 = wif->stats.is_tx_unknownmgt; 1526 break; 1527 case LEAF_wlanStatsTxBadCipher: 1528 val->v.uint32 = wif->stats.is_tx_badcipher; 1529 break; 1530 case LEAF_wlanStatsTxNoDefKey: 1531 val->v.uint32 = wif->stats.is_tx_nodefkey; 1532 break; 1533 case LEAF_wlanStatsTxFragmented: 1534 val->v.uint32 = wif->stats.is_tx_fragframes; 1535 break; 1536 case LEAF_wlanStatsTxFragmentsCreated: 1537 val->v.uint32 = wif->stats.is_tx_frags; 1538 break; 1539 case LEAF_wlanStatsActiveScans: 1540 val->v.uint32 = wif->stats.is_scan_active; 1541 break; 1542 case LEAF_wlanStatsPassiveScans: 1543 val->v.uint32 = wif->stats.is_scan_passive; 1544 break; 1545 case LEAF_wlanStatsTimeoutInactivity: 1546 val->v.uint32 = wif->stats.is_node_timeout; 1547 break; 1548 case LEAF_wlanStatsCryptoNoMem: 1549 val->v.uint32 = wif->stats.is_crypto_nomem; 1550 break; 1551 case LEAF_wlanStatsSwCryptoTKIP: 1552 val->v.uint32 = wif->stats.is_crypto_tkip; 1553 break; 1554 case LEAF_wlanStatsSwCryptoTKIPEnMIC: 1555 val->v.uint32 = wif->stats.is_crypto_tkipenmic; 1556 break; 1557 case LEAF_wlanStatsSwCryptoTKIPDeMIC: 1558 val->v.uint32 = wif->stats.is_crypto_tkipdemic; 1559 break; 1560 case LEAF_wlanStatsCryptoTKIPCM: 1561 val->v.uint32 = wif->stats.is_crypto_tkipcm; 1562 break; 1563 case LEAF_wlanStatsSwCryptoCCMP: 1564 val->v.uint32 = wif->stats.is_crypto_ccmp; 1565 break; 1566 case LEAF_wlanStatsSwCryptoWEP: 1567 val->v.uint32 = wif->stats.is_crypto_wep; 1568 break; 1569 case LEAF_wlanStatsCryptoCipherKeyRejected: 1570 val->v.uint32 = wif->stats.is_crypto_setkey_cipher; 1571 break; 1572 case LEAF_wlanStatsCryptoNoKey: 1573 val->v.uint32 = wif->stats.is_crypto_setkey_nokey; 1574 break; 1575 case LEAF_wlanStatsCryptoDeleteKeyFailed: 1576 val->v.uint32 = wif->stats.is_crypto_delkey; 1577 break; 1578 case LEAF_wlanStatsCryptoUnknownCipher: 1579 val->v.uint32 = wif->stats.is_crypto_badcipher; 1580 break; 1581 case LEAF_wlanStatsCryptoAttachFailed: 1582 val->v.uint32 = wif->stats.is_crypto_attachfail; 1583 break; 1584 case LEAF_wlanStatsCryptoKeyFailed: 1585 val->v.uint32 = wif->stats.is_crypto_keyfail; 1586 break; 1587 case LEAF_wlanStatsCryptoEnMICFailed: 1588 val->v.uint32 = wif->stats.is_crypto_enmicfail; 1589 break; 1590 case LEAF_wlanStatsIBSSCapMismatch: 1591 val->v.uint32 = wif->stats.is_ibss_capmismatch; 1592 break; 1593 case LEAF_wlanStatsUnassocStaPSPoll: 1594 val->v.uint32 = wif->stats.is_ps_unassoc; 1595 break; 1596 case LEAF_wlanStatsBadAidPSPoll: 1597 val->v.uint32 = wif->stats.is_ps_badaid; 1598 break; 1599 case LEAF_wlanStatsEmptyPSPoll: 1600 val->v.uint32 = wif->stats.is_ps_qempty; 1601 break; 1602 case LEAF_wlanStatsRxFFBadHdr: 1603 val->v.uint32 = wif->stats.is_ff_badhdr; 1604 break; 1605 case LEAF_wlanStatsRxFFTooShort: 1606 val->v.uint32 = wif->stats.is_ff_tooshort; 1607 break; 1608 case LEAF_wlanStatsRxFFSplitError: 1609 val->v.uint32 = wif->stats.is_ff_split; 1610 break; 1611 case LEAF_wlanStatsRxFFDecap: 1612 val->v.uint32 = wif->stats.is_ff_decap; 1613 break; 1614 case LEAF_wlanStatsTxFFEncap: 1615 val->v.uint32 = wif->stats.is_ff_encap; 1616 break; 1617 case LEAF_wlanStatsRxBadBintval: 1618 val->v.uint32 = wif->stats.is_rx_badbintval; 1619 break; 1620 case LEAF_wlanStatsRxDemicFailed: 1621 val->v.uint32 = wif->stats.is_rx_demicfail; 1622 break; 1623 case LEAF_wlanStatsRxDefragFailed: 1624 val->v.uint32 = wif->stats.is_rx_defrag; 1625 break; 1626 case LEAF_wlanStatsRxMgmt: 1627 val->v.uint32 = wif->stats.is_rx_mgmt; 1628 break; 1629 case LEAF_wlanStatsRxActionMgmt: 1630 val->v.uint32 = wif->stats.is_rx_action; 1631 break; 1632 case LEAF_wlanStatsRxAMSDUTooShort: 1633 val->v.uint32 = wif->stats.is_amsdu_tooshort; 1634 break; 1635 case LEAF_wlanStatsRxAMSDUSplitError: 1636 val->v.uint32 = wif->stats.is_amsdu_split; 1637 break; 1638 case LEAF_wlanStatsRxAMSDUDecap: 1639 val->v.uint32 = wif->stats.is_amsdu_decap; 1640 break; 1641 case LEAF_wlanStatsTxAMSDUEncap: 1642 val->v.uint32 = wif->stats.is_amsdu_encap; 1643 break; 1644 case LEAF_wlanStatsAMPDUBadBAR: 1645 val->v.uint32 = wif->stats.is_ampdu_bar_bad; 1646 break; 1647 case LEAF_wlanStatsAMPDUOowBar: 1648 val->v.uint32 = wif->stats.is_ampdu_bar_oow; 1649 break; 1650 case LEAF_wlanStatsAMPDUMovedBAR: 1651 val->v.uint32 = wif->stats.is_ampdu_bar_move; 1652 break; 1653 case LEAF_wlanStatsAMPDURxBAR: 1654 val->v.uint32 = wif->stats.is_ampdu_bar_rx; 1655 break; 1656 case LEAF_wlanStatsAMPDURxOor: 1657 val->v.uint32 = wif->stats.is_ampdu_rx_oor; 1658 break; 1659 case LEAF_wlanStatsAMPDURxCopied: 1660 val->v.uint32 = wif->stats.is_ampdu_rx_copy; 1661 break; 1662 case LEAF_wlanStatsAMPDURxDropped: 1663 val->v.uint32 = wif->stats.is_ampdu_rx_drop; 1664 break; 1665 case LEAF_wlanStatsTxDiscardBadState: 1666 val->v.uint32 = wif->stats.is_tx_badstate; 1667 break; 1668 case LEAF_wlanStatsTxFailedNoAssoc: 1669 val->v.uint32 = wif->stats.is_tx_notassoc; 1670 break; 1671 case LEAF_wlanStatsTxClassifyFailed: 1672 val->v.uint32 = wif->stats.is_tx_classify; 1673 break; 1674 case LEAF_wlanStatsDwdsMcastDiscard: 1675 val->v.uint32 = wif->stats.is_dwds_mcast; 1676 break; 1677 case LEAF_wlanStatsHTAssocRejectNoHT: 1678 val->v.uint32 = wif->stats.is_ht_assoc_nohtcap; 1679 break; 1680 case LEAF_wlanStatsHTAssocDowngrade: 1681 val->v.uint32 = wif->stats.is_ht_assoc_downgrade; 1682 break; 1683 case LEAF_wlanStatsHTAssocRateMismatch: 1684 val->v.uint32 = wif->stats.is_ht_assoc_norate; 1685 break; 1686 case LEAF_wlanStatsAMPDURxAge: 1687 val->v.uint32 = wif->stats.is_ampdu_rx_age; 1688 break; 1689 case LEAF_wlanStatsAMPDUMoved: 1690 val->v.uint32 = wif->stats.is_ampdu_rx_move; 1691 break; 1692 case LEAF_wlanStatsADDBADisabledReject: 1693 val->v.uint32 = wif->stats.is_addba_reject; 1694 break; 1695 case LEAF_wlanStatsADDBANoRequest: 1696 val->v.uint32 = wif->stats.is_addba_norequest; 1697 break; 1698 case LEAF_wlanStatsADDBABadToken: 1699 val->v.uint32 = wif->stats.is_addba_badtoken; 1700 break; 1701 case LEAF_wlanStatsADDBABadPolicy: 1702 val->v.uint32 = wif->stats.is_addba_badpolicy; 1703 break; 1704 case LEAF_wlanStatsAMPDUStopped: 1705 val->v.uint32 = wif->stats.is_ampdu_stop; 1706 break; 1707 case LEAF_wlanStatsAMPDUStopFailed: 1708 val->v.uint32 = wif->stats.is_ampdu_stop_failed; 1709 break; 1710 case LEAF_wlanStatsAMPDURxReorder: 1711 val->v.uint32 = wif->stats.is_ampdu_rx_reorder; 1712 break; 1713 case LEAF_wlanStatsScansBackground: 1714 val->v.uint32 = wif->stats.is_scan_bg; 1715 break; 1716 case LEAF_wlanLastDeauthReason: 1717 val->v.uint32 = wif->stats.is_rx_deauth_code; 1718 break; 1719 case LEAF_wlanLastDissasocReason: 1720 val->v.uint32 = wif->stats.is_rx_disassoc_code; 1721 break; 1722 case LEAF_wlanLastAuthFailReason: 1723 val->v.uint32 = wif->stats.is_rx_authfail_code; 1724 break; 1725 case LEAF_wlanStatsBeaconMissedEvents: 1726 val->v.uint32 = wif->stats.is_beacon_miss; 1727 break; 1728 case LEAF_wlanStatsRxDiscardBadStates: 1729 val->v.uint32 = wif->stats.is_rx_badstate; 1730 break; 1731 case LEAF_wlanStatsFFFlushed: 1732 val->v.uint32 = wif->stats.is_ff_flush; 1733 break; 1734 case LEAF_wlanStatsTxControlFrames: 1735 val->v.uint32 = wif->stats.is_tx_ctl; 1736 break; 1737 case LEAF_wlanStatsAMPDURexmt: 1738 val->v.uint32 = wif->stats.is_ampdu_rexmt; 1739 break; 1740 case LEAF_wlanStatsAMPDURexmtFailed: 1741 val->v.uint32 = wif->stats.is_ampdu_rexmt_fail; 1742 break; 1743 case LEAF_wlanStatsReset: 1744 val->v.uint32 = wlanStatsReset_no_op; 1745 break; 1746 default: 1747 abort(); 1748 } 1749 1750 return (SNMP_ERR_NOERROR); 1751 } 1752 1753 int 1754 op_wlan_wep_iface(struct snmp_context *ctx, struct snmp_value *val, 1755 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1756 { 1757 struct wlan_iface *wif; 1758 1759 wlan_update_interface_list(); 1760 1761 switch (op) { 1762 case SNMP_OP_GET: 1763 if ((wif = wlan_get_interface(&val->var, sub)) == NULL || 1764 !wif->wepsupported) 1765 return (SNMP_ERR_NOSUCHNAME); 1766 break; 1767 1768 case SNMP_OP_GETNEXT: 1769 /* XXX: filter wif->wepsupported */ 1770 if ((wif = wlan_get_next_interface(&val->var, sub)) == NULL) 1771 return (SNMP_ERR_NOSUCHNAME); 1772 wlan_append_ifindex(&val->var, sub, wif); 1773 break; 1774 1775 case SNMP_OP_SET: 1776 if ((wif = wlan_get_interface(&val->var, sub)) == NULL || 1777 !wif->wepsupported) 1778 return (SNMP_ERR_NOSUCHNAME); 1779 switch (val->var.subs[sub - 1]) { 1780 case LEAF_wlanWepMode: 1781 if (val->v.integer < wlanWepMode_off || 1782 val->v.integer > wlanWepMode_mixed) 1783 return (SNMP_ERR_INCONS_VALUE); 1784 ctx->scratch->int1 = wif->wepmode; 1785 wif->wepmode = val->v.integer; 1786 if (wlan_set_wepmode(wif) < 0) { 1787 wif->wepmode = ctx->scratch->int1; 1788 return (SNMP_ERR_GENERR); 1789 } 1790 break; 1791 case LEAF_wlanWepDefTxKey: 1792 if (val->v.integer < 0 || 1793 val->v.integer > IEEE80211_WEP_NKID) 1794 return (SNMP_ERR_INCONS_VALUE); 1795 ctx->scratch->int1 = wif->weptxkey; 1796 wif->weptxkey = val->v.integer; 1797 if (wlan_set_weptxkey(wif) < 0) { 1798 wif->weptxkey = ctx->scratch->int1; 1799 return (SNMP_ERR_GENERR); 1800 } 1801 break; 1802 default: 1803 abort(); 1804 } 1805 return (SNMP_ERR_NOERROR); 1806 1807 case SNMP_OP_COMMIT: 1808 return (SNMP_ERR_NOERROR); 1809 1810 case SNMP_OP_ROLLBACK: 1811 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1812 return (SNMP_ERR_NOSUCHNAME); 1813 switch (val->var.subs[sub - 1]) { 1814 case LEAF_wlanWepMode: 1815 wif->wepmode = ctx->scratch->int1; 1816 if (wlan_set_wepmode(wif) < 0) 1817 return (SNMP_ERR_GENERR); 1818 break; 1819 case LEAF_wlanWepDefTxKey: 1820 wif->weptxkey = ctx->scratch->int1; 1821 if (wlan_set_weptxkey(wif) < 0) 1822 return (SNMP_ERR_GENERR); 1823 break; 1824 default: 1825 abort(); 1826 } 1827 return (SNMP_ERR_NOERROR); 1828 1829 default: 1830 abort(); 1831 } 1832 1833 switch (val->var.subs[sub - 1]) { 1834 case LEAF_wlanWepMode: 1835 if (wlan_get_wepmode(wif) < 0) 1836 return (SNMP_ERR_GENERR); 1837 val->v.integer = wif->wepmode; 1838 break; 1839 case LEAF_wlanWepDefTxKey: 1840 if (wlan_get_weptxkey(wif) < 0) 1841 return (SNMP_ERR_GENERR); 1842 val->v.integer = wif->weptxkey; 1843 break; 1844 default: 1845 abort(); 1846 } 1847 1848 return (SNMP_ERR_NOERROR); 1849 } 1850 1851 int 1852 op_wlan_wep_key(struct snmp_context *ctx __unused, 1853 struct snmp_value *val __unused, uint32_t sub __unused, 1854 uint32_t iidx __unused, enum snmp_op op __unused) 1855 { 1856 return (SNMP_ERR_NOSUCHNAME); 1857 } 1858 1859 int 1860 op_wlan_mac_access_control(struct snmp_context *ctx, struct snmp_value *val, 1861 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1862 { 1863 struct wlan_iface *wif; 1864 1865 wlan_update_interface_list(); 1866 1867 switch (op) { 1868 case SNMP_OP_GET: 1869 if ((wif = wlan_get_interface(&val->var, sub)) == NULL || 1870 !wif->macsupported) 1871 return (SNMP_ERR_NOSUCHNAME); 1872 break; 1873 1874 case SNMP_OP_GETNEXT: 1875 /* XXX: filter wif->macsupported */ 1876 if ((wif = wlan_get_next_interface(&val->var, sub)) == NULL) 1877 return (SNMP_ERR_NOSUCHNAME); 1878 wlan_append_ifindex(&val->var, sub, wif); 1879 break; 1880 1881 case SNMP_OP_SET: 1882 if ((wif = wlan_get_interface(&val->var, sub)) == NULL || 1883 !wif->macsupported) 1884 return (SNMP_ERR_NOSUCHNAME); 1885 switch (val->var.subs[sub - 1]) { 1886 case LEAF_wlanMACAccessControlPolicy: 1887 ctx->scratch->int1 = wif->mac_policy; 1888 wif->mac_policy = val->v.integer; 1889 break; 1890 case LEAF_wlanMACAccessControlNacl: 1891 return (SNMP_ERR_NOT_WRITEABLE); 1892 case LEAF_wlanMACAccessControlFlush: 1893 break; 1894 default: 1895 abort(); 1896 } 1897 return (SNMP_ERR_NOERROR); 1898 1899 case SNMP_OP_COMMIT: 1900 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1901 return (SNMP_ERR_NOSUCHNAME); 1902 switch (val->var.subs[sub - 1]) { 1903 case LEAF_wlanMACAccessControlPolicy: 1904 if (wlan_set_mac_policy(wif) < 0) { 1905 wif->mac_policy = ctx->scratch->int1; 1906 return (SNMP_ERR_GENERR); 1907 } 1908 break; 1909 case LEAF_wlanMACAccessControlFlush: 1910 if (wlan_flush_mac_mac(wif) < 0) 1911 return (SNMP_ERR_GENERR); 1912 break; 1913 default: 1914 abort(); 1915 } 1916 return (SNMP_ERR_NOERROR); 1917 1918 case SNMP_OP_ROLLBACK: 1919 if ((wif = wlan_get_interface(&val->var, sub)) == NULL) 1920 return (SNMP_ERR_NOSUCHNAME); 1921 if (val->var.subs[sub - 1] == LEAF_wlanMACAccessControlPolicy) 1922 wif->mac_policy = ctx->scratch->int1; 1923 return (SNMP_ERR_NOERROR); 1924 1925 default: 1926 abort(); 1927 } 1928 1929 if (wlan_get_mac_policy(wif) < 0) 1930 return (SNMP_ERR_GENERR); 1931 1932 switch (val->var.subs[sub - 1]) { 1933 case LEAF_wlanMACAccessControlPolicy: 1934 val->v.integer = wif->mac_policy; 1935 break; 1936 case LEAF_wlanMACAccessControlNacl: 1937 val->v.integer = wif->mac_nacls; 1938 break; 1939 case LEAF_wlanMACAccessControlFlush: 1940 val->v.integer = wlanMACAccessControlFlush_no_op; 1941 break; 1942 default: 1943 abort(); 1944 } 1945 1946 return (SNMP_ERR_NOERROR); 1947 } 1948 1949 int 1950 op_wlan_mac_acl_mac(struct snmp_context *ctx, struct snmp_value *val, 1951 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 1952 { 1953 struct wlan_iface *wif; 1954 struct wlan_mac_mac *macl; 1955 1956 wlan_update_interface_list(); 1957 wlan_mac_update_aclmacs(); 1958 1959 switch (op) { 1960 case SNMP_OP_GET: 1961 if ((macl = wlan_get_acl_mac(&val->var, sub, &wif)) == NULL) 1962 return (SNMP_ERR_NOSUCHNAME); 1963 break; 1964 1965 case SNMP_OP_GETNEXT: 1966 if ((macl = wlan_get_next_acl_mac(&val->var, sub, &wif)) 1967 == NULL) 1968 return (SNMP_ERR_NOSUCHNAME); 1969 wlan_append_mac_index(&val->var, sub, wif->wname, macl->mac); 1970 break; 1971 1972 case SNMP_OP_SET: 1973 switch (val->var.subs[sub - 1]) { 1974 case LEAF_wlanMACAccessControlMAC: 1975 return (SNMP_ERR_INCONS_NAME); 1976 case LEAF_wlanMACAccessControlMACStatus: 1977 return(wlan_acl_mac_set_status(ctx, val, sub)); 1978 default: 1979 abort(); 1980 } 1981 1982 case SNMP_OP_COMMIT: 1983 if ((macl = wlan_get_acl_mac(&val->var, sub, &wif)) == NULL) 1984 return (SNMP_ERR_NOSUCHNAME); 1985 if (val->v.integer == RowStatus_destroy && 1986 wlan_mac_delete_mac(wif, macl) < 0) 1987 return (SNMP_ERR_GENERR); 1988 return (SNMP_ERR_NOERROR); 1989 1990 case SNMP_OP_ROLLBACK: 1991 if ((macl = wlan_get_acl_mac(&val->var, sub, &wif)) == NULL) 1992 return (SNMP_ERR_NOSUCHNAME); 1993 if (ctx->scratch->int1 == RowStatus_destroy && 1994 wlan_mac_delete_mac(wif, macl) < 0) 1995 return (SNMP_ERR_GENERR); 1996 return (SNMP_ERR_NOERROR); 1997 1998 default: 1999 abort(); 2000 } 2001 2002 switch (val->var.subs[sub - 1]) { 2003 case LEAF_wlanMACAccessControlMAC: 2004 return (string_get(val, macl->mac, IEEE80211_ADDR_LEN)); 2005 case LEAF_wlanMACAccessControlMACStatus: 2006 val->v.integer = macl->mac_status; 2007 break; 2008 default: 2009 abort(); 2010 } 2011 2012 return (SNMP_ERR_NOERROR); 2013 } 2014 2015 int 2016 op_wlan_mesh_config(struct snmp_context *ctx, struct snmp_value *val, 2017 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2018 { 2019 int which; 2020 2021 switch (val->var.subs[sub - 1]) { 2022 case LEAF_wlanMeshMaxRetries: 2023 which = WLAN_MESH_MAX_RETRIES; 2024 break; 2025 case LEAF_wlanMeshHoldingTimeout: 2026 which = WLAN_MESH_HOLDING_TO; 2027 break; 2028 case LEAF_wlanMeshConfirmTimeout: 2029 which = WLAN_MESH_CONFIRM_TO; 2030 break; 2031 case LEAF_wlanMeshRetryTimeout: 2032 which = WLAN_MESH_RETRY_TO; 2033 break; 2034 default: 2035 abort(); 2036 } 2037 2038 switch (op) { 2039 case SNMP_OP_GET: 2040 if (wlan_do_sysctl(&wlan_config, which, 0) < 0) 2041 return (SNMP_ERR_GENERR); 2042 break; 2043 2044 case SNMP_OP_GETNEXT: 2045 abort(); 2046 2047 case SNMP_OP_SET: 2048 switch (val->var.subs[sub - 1]) { 2049 case LEAF_wlanMeshRetryTimeout : 2050 ctx->scratch->int1 = wlan_config.mesh_retryto; 2051 wlan_config.mesh_retryto = val->v.integer; 2052 break; 2053 case LEAF_wlanMeshHoldingTimeout: 2054 ctx->scratch->int1 = wlan_config.mesh_holdingto; 2055 wlan_config.mesh_holdingto = val->v.integer; 2056 break; 2057 case LEAF_wlanMeshConfirmTimeout: 2058 ctx->scratch->int1 = wlan_config.mesh_confirmto; 2059 wlan_config.mesh_confirmto = val->v.integer; 2060 break; 2061 case LEAF_wlanMeshMaxRetries: 2062 ctx->scratch->int1 = wlan_config.mesh_maxretries; 2063 wlan_config.mesh_maxretries = val->v.integer; 2064 break; 2065 } 2066 if (wlan_do_sysctl(&wlan_config, which, 1) < 0) 2067 return (SNMP_ERR_GENERR); 2068 return (SNMP_ERR_NOERROR); 2069 2070 case SNMP_OP_COMMIT: 2071 return (SNMP_ERR_NOERROR); 2072 2073 case SNMP_OP_ROLLBACK: 2074 switch (val->var.subs[sub - 1]) { 2075 case LEAF_wlanMeshRetryTimeout: 2076 wlan_config.mesh_retryto = ctx->scratch->int1; 2077 break; 2078 case LEAF_wlanMeshConfirmTimeout: 2079 wlan_config.mesh_confirmto = ctx->scratch->int1; 2080 break; 2081 case LEAF_wlanMeshHoldingTimeout: 2082 wlan_config.mesh_holdingto= ctx->scratch->int1; 2083 break; 2084 case LEAF_wlanMeshMaxRetries: 2085 wlan_config.mesh_maxretries = ctx->scratch->int1; 2086 break; 2087 } 2088 if (wlan_do_sysctl(&wlan_config, which, 1) < 0) 2089 return (SNMP_ERR_GENERR); 2090 return (SNMP_ERR_NOERROR); 2091 2092 default: 2093 abort(); 2094 } 2095 2096 switch (val->var.subs[sub - 1]) { 2097 case LEAF_wlanMeshRetryTimeout: 2098 val->v.integer = wlan_config.mesh_retryto; 2099 break; 2100 case LEAF_wlanMeshHoldingTimeout: 2101 val->v.integer = wlan_config.mesh_holdingto; 2102 break; 2103 case LEAF_wlanMeshConfirmTimeout: 2104 val->v.integer = wlan_config.mesh_confirmto; 2105 break; 2106 case LEAF_wlanMeshMaxRetries: 2107 val->v.integer = wlan_config.mesh_maxretries; 2108 break; 2109 } 2110 2111 return (SNMP_ERR_NOERROR); 2112 } 2113 2114 int 2115 op_wlan_mesh_iface(struct snmp_context *ctx, struct snmp_value *val, 2116 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2117 { 2118 int rc; 2119 struct wlan_iface *wif; 2120 2121 wlan_update_interface_list(); 2122 2123 switch (op) { 2124 case SNMP_OP_GET: 2125 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2126 return (SNMP_ERR_NOSUCHNAME); 2127 break; 2128 2129 case SNMP_OP_GETNEXT: 2130 if ((wif = wlan_mesh_get_next_iface(&val->var, sub)) == NULL) 2131 return (SNMP_ERR_NOSUCHNAME); 2132 wlan_append_ifindex(&val->var, sub, wif); 2133 break; 2134 2135 case SNMP_OP_SET: 2136 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2137 return (SNMP_ERR_NOSUCHNAME); 2138 switch (val->var.subs[sub - 1]) { 2139 case LEAF_wlanMeshId: 2140 if (val->v.octetstring.len > IEEE80211_NWID_LEN) 2141 return (SNMP_ERR_INCONS_VALUE); 2142 ctx->scratch->ptr1 = malloc(val->v.octetstring.len + 1); 2143 if (ctx->scratch->ptr1 == NULL) 2144 return (SNMP_ERR_GENERR); 2145 strlcpy(ctx->scratch->ptr1, wif->desired_ssid, 2146 val->v.octetstring.len + 1); 2147 ctx->scratch->int1 = strlen(wif->desired_ssid); 2148 memcpy(wif->desired_ssid, val->v.octetstring.octets, 2149 val->v.octetstring.len); 2150 wif->desired_ssid[val->v.octetstring.len] = '\0'; 2151 break; 2152 case LEAF_wlanMeshTTL: 2153 ctx->scratch->int1 = wif->mesh_ttl; 2154 wif->mesh_ttl = val->v.integer; 2155 break; 2156 case LEAF_wlanMeshPeeringEnabled: 2157 ctx->scratch->int1 = wif->mesh_peering; 2158 wif->mesh_peering = val->v.integer; 2159 break; 2160 case LEAF_wlanMeshForwardingEnabled: 2161 ctx->scratch->int1 = wif->mesh_forwarding; 2162 wif->mesh_forwarding = val->v.integer; 2163 break; 2164 case LEAF_wlanMeshMetric: 2165 ctx->scratch->int1 = wif->mesh_metric; 2166 wif->mesh_metric = val->v.integer; 2167 break; 2168 case LEAF_wlanMeshPath: 2169 ctx->scratch->int1 = wif->mesh_path; 2170 wif->mesh_path = val->v.integer; 2171 break; 2172 case LEAF_wlanMeshRoutesFlush: 2173 if (val->v.integer != wlanMeshRoutesFlush_flush) 2174 return (SNMP_ERR_INCONS_VALUE); 2175 return (SNMP_ERR_NOERROR); 2176 default: 2177 abort(); 2178 } 2179 if (val->var.subs[sub - 1] == LEAF_wlanMeshId) 2180 rc = wlan_config_set_dssid(wif, 2181 val->v.octetstring.octets, val->v.octetstring.len); 2182 else 2183 rc = wlan_mesh_config_set(wif, val->var.subs[sub - 1]); 2184 if (rc < 0) 2185 return (SNMP_ERR_GENERR); 2186 return (SNMP_ERR_NOERROR); 2187 2188 case SNMP_OP_COMMIT: 2189 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2190 return (SNMP_ERR_NOSUCHNAME); 2191 if (val->var.subs[sub - 1] == LEAF_wlanMeshRoutesFlush && 2192 wlan_mesh_flush_routes(wif) < 0) 2193 return (SNMP_ERR_GENERR); 2194 if (val->var.subs[sub - 1] == LEAF_wlanMeshId) 2195 free(ctx->scratch->ptr1); 2196 return (SNMP_ERR_NOERROR); 2197 2198 case SNMP_OP_ROLLBACK: 2199 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2200 return (SNMP_ERR_NOSUCHNAME); 2201 switch (val->var.subs[sub - 1]) { 2202 case LEAF_wlanMeshId: 2203 strlcpy(wif->desired_ssid, ctx->scratch->ptr1, 2204 IEEE80211_NWID_LEN); 2205 free(ctx->scratch->ptr1); 2206 break; 2207 case LEAF_wlanMeshTTL: 2208 wif->mesh_ttl = ctx->scratch->int1; 2209 break; 2210 case LEAF_wlanMeshPeeringEnabled: 2211 wif->mesh_peering = ctx->scratch->int1; 2212 break; 2213 case LEAF_wlanMeshForwardingEnabled: 2214 wif->mesh_forwarding = ctx->scratch->int1; 2215 break; 2216 case LEAF_wlanMeshMetric: 2217 wif->mesh_metric = ctx->scratch->int1; 2218 break; 2219 case LEAF_wlanMeshPath: 2220 wif->mesh_path = ctx->scratch->int1; 2221 break; 2222 case LEAF_wlanMeshRoutesFlush: 2223 return (SNMP_ERR_NOERROR); 2224 default: 2225 abort(); 2226 } 2227 if (val->var.subs[sub - 1] == LEAF_wlanMeshId) 2228 rc = wlan_config_set_dssid(wif, wif->desired_ssid, 2229 strlen(wif->desired_ssid)); 2230 else 2231 rc = wlan_mesh_config_set(wif, val->var.subs[sub - 1]); 2232 if (rc < 0) 2233 return (SNMP_ERR_GENERR); 2234 return (SNMP_ERR_NOERROR); 2235 2236 default: 2237 abort(); 2238 } 2239 2240 if (val->var.subs[sub - 1] == LEAF_wlanMeshId) 2241 rc = wlan_config_get_dssid(wif); 2242 else 2243 rc = wlan_mesh_config_get(wif, val->var.subs[sub - 1]); 2244 if (rc < 0) 2245 return (SNMP_ERR_GENERR); 2246 2247 switch (val->var.subs[sub - 1]) { 2248 case LEAF_wlanMeshId: 2249 return (string_get(val, wif->desired_ssid, -1)); 2250 case LEAF_wlanMeshTTL: 2251 val->v.integer = wif->mesh_ttl; 2252 break; 2253 case LEAF_wlanMeshPeeringEnabled: 2254 val->v.integer = wif->mesh_peering; 2255 break; 2256 case LEAF_wlanMeshForwardingEnabled: 2257 val->v.integer = wif->mesh_forwarding; 2258 break; 2259 case LEAF_wlanMeshMetric: 2260 val->v.integer = wif->mesh_metric; 2261 break; 2262 case LEAF_wlanMeshPath: 2263 val->v.integer = wif->mesh_path; 2264 break; 2265 case LEAF_wlanMeshRoutesFlush: 2266 val->v.integer = wlanMeshRoutesFlush_no_op; 2267 break; 2268 default: 2269 abort(); 2270 } 2271 2272 return (SNMP_ERR_NOERROR); 2273 } 2274 2275 int 2276 op_wlan_mesh_neighbor(struct snmp_context *ctx __unused, struct snmp_value *val, 2277 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2278 { 2279 struct wlan_peer *wip; 2280 struct wlan_iface *wif; 2281 2282 wlan_update_interface_list(); 2283 wlan_update_peers(); 2284 2285 switch (op) { 2286 case SNMP_OP_GET: 2287 if ((wip = wlan_mesh_get_peer(&val->var, sub, &wif)) == NULL) 2288 return (SNMP_ERR_NOSUCHNAME); 2289 break; 2290 case SNMP_OP_GETNEXT: 2291 wip = wlan_mesh_get_next_peer(&val->var, sub, &wif); 2292 if (wip == NULL) 2293 return (SNMP_ERR_NOSUCHNAME); 2294 wlan_append_mac_index(&val->var, sub, wif->wname, 2295 wip->pmac); 2296 break; 2297 case SNMP_OP_SET: 2298 return (SNMP_ERR_NOT_WRITEABLE); 2299 case SNMP_OP_COMMIT: 2300 /* FALLTHROUGH */ 2301 case SNMP_OP_ROLLBACK: 2302 /* FALLTHROUGH */ 2303 default: 2304 abort(); 2305 } 2306 2307 switch (val->var.subs[sub - 1]) { 2308 case LEAF_wlanMeshNeighborAddress: 2309 return (string_get(val, wip->pmac, IEEE80211_ADDR_LEN)); 2310 case LEAF_wlanMeshNeighborFrequency: 2311 val->v.integer = wip->frequency; 2312 break; 2313 case LEAF_wlanMeshNeighborLocalId: 2314 val->v.integer = wip->local_id; 2315 break; 2316 case LEAF_wlanMeshNeighborPeerId: 2317 val->v.integer = wip->peer_id; 2318 break; 2319 case LEAF_wlanMeshNeighborPeerState: 2320 return (bits_get(val, (uint8_t *)&wip->state, 2321 sizeof(wip->state))); 2322 case LEAF_wlanMeshNeighborCurrentTXRate: 2323 val->v.integer = wip->txrate; 2324 break; 2325 case LEAF_wlanMeshNeighborRxSignalStrength: 2326 val->v.integer = wip->rssi; 2327 break; 2328 case LEAF_wlanMeshNeighborIdleTimer: 2329 val->v.integer = wip->idle; 2330 break; 2331 case LEAF_wlanMeshNeighborTxSequenceNo: 2332 val->v.integer = wip->txseqs; 2333 break; 2334 case LEAF_wlanMeshNeighborRxSequenceNo: 2335 val->v.integer = wip->rxseqs; 2336 break; 2337 default: 2338 abort(); 2339 } 2340 2341 return (SNMP_ERR_NOERROR); 2342 } 2343 2344 int 2345 op_wlan_mesh_route(struct snmp_context *ctx, struct snmp_value *val, 2346 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2347 { 2348 struct wlan_mesh_route *wmr; 2349 struct wlan_iface *wif; 2350 2351 wlan_update_interface_list(); 2352 wlan_mesh_update_routes(); 2353 2354 switch (op) { 2355 case SNMP_OP_GET: 2356 if ((wmr = wlan_mesh_get_route(&val->var, sub, &wif)) == NULL) 2357 return (SNMP_ERR_NOSUCHNAME); 2358 break; 2359 2360 case SNMP_OP_GETNEXT: 2361 wmr = wlan_mesh_get_next_route(&val->var, sub, &wif); 2362 if (wmr == NULL) 2363 return (SNMP_ERR_NOSUCHNAME); 2364 wlan_append_mac_index(&val->var, sub, wif->wname, 2365 wmr->imroute.imr_dest); 2366 break; 2367 2368 case SNMP_OP_SET: 2369 switch (val->var.subs[sub - 1]) { 2370 case LEAF_wlanMeshRouteDestination: 2371 return (SNMP_ERR_INCONS_NAME); 2372 case LEAF_wlanMeshRouteStatus: 2373 return(wlan_mesh_route_set_status(ctx, val, sub)); 2374 default: 2375 return (SNMP_ERR_NOT_WRITEABLE); 2376 } 2377 abort(); 2378 2379 case SNMP_OP_COMMIT: 2380 if ((wmr = wlan_mesh_get_route(&val->var, sub, &wif)) == NULL) 2381 return (SNMP_ERR_NOSUCHNAME); 2382 if (val->v.integer == RowStatus_destroy && 2383 wlan_mesh_delete_route(wif, wmr) < 0) 2384 return (SNMP_ERR_GENERR); 2385 return (SNMP_ERR_NOERROR); 2386 2387 case SNMP_OP_ROLLBACK: 2388 if ((wmr = wlan_mesh_get_route(&val->var, sub, &wif)) == NULL) 2389 return (SNMP_ERR_NOSUCHNAME); 2390 if (ctx->scratch->int1 == RowStatus_destroy && 2391 wlan_mesh_delete_route(wif, wmr) < 0) 2392 return (SNMP_ERR_GENERR); 2393 return (SNMP_ERR_NOERROR); 2394 2395 default: 2396 abort(); 2397 } 2398 2399 switch (val->var.subs[sub - 1]) { 2400 case LEAF_wlanMeshRouteDestination: 2401 return (string_get(val, wmr->imroute.imr_dest, 2402 IEEE80211_ADDR_LEN)); 2403 case LEAF_wlanMeshRouteNextHop: 2404 return (string_get(val, wmr->imroute.imr_nexthop, 2405 IEEE80211_ADDR_LEN)); 2406 case LEAF_wlanMeshRouteHops: 2407 val->v.integer = wmr->imroute.imr_nhops; 2408 break; 2409 case LEAF_wlanMeshRouteMetric: 2410 val->v.integer = wmr->imroute.imr_metric; 2411 break; 2412 case LEAF_wlanMeshRouteLifeTime: 2413 val->v.integer = wmr->imroute.imr_lifetime; 2414 break; 2415 case LEAF_wlanMeshRouteLastMseq: 2416 val->v.integer = wmr->imroute.imr_lastmseq; 2417 break; 2418 case LEAF_wlanMeshRouteFlags: 2419 val->v.integer = 0; 2420 if ((wmr->imroute.imr_flags & 2421 IEEE80211_MESHRT_FLAGS_VALID) != 0) 2422 val->v.integer |= (0x1 << wlanMeshRouteFlags_valid); 2423 if ((wmr->imroute.imr_flags & 2424 IEEE80211_MESHRT_FLAGS_PROXY) != 0) 2425 val->v.integer |= (0x1 << wlanMeshRouteFlags_proxy); 2426 return (bits_get(val, (uint8_t *)&val->v.integer, 2427 sizeof(val->v.integer))); 2428 case LEAF_wlanMeshRouteStatus: 2429 val->v.integer = wmr->mroute_status; 2430 break; 2431 } 2432 2433 return (SNMP_ERR_NOERROR); 2434 } 2435 2436 int 2437 op_wlan_mesh_stats(struct snmp_context *ctx __unused, struct snmp_value *val, 2438 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2439 { 2440 struct wlan_iface *wif; 2441 2442 wlan_update_interface_list(); 2443 2444 switch (op) { 2445 case SNMP_OP_GET: 2446 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2447 return (SNMP_ERR_NOSUCHNAME); 2448 break; 2449 case SNMP_OP_GETNEXT: 2450 if ((wif = wlan_mesh_get_next_iface(&val->var, sub)) == NULL) 2451 return (SNMP_ERR_NOSUCHNAME); 2452 wlan_append_ifindex(&val->var, sub, wif); 2453 break; 2454 case SNMP_OP_SET: 2455 return (SNMP_ERR_NOT_WRITEABLE); 2456 case SNMP_OP_COMMIT: 2457 /* FALLTHROUGH */ 2458 case SNMP_OP_ROLLBACK: 2459 /* FALLTHROUGH */ 2460 default: 2461 abort(); 2462 } 2463 2464 if (wlan_get_stats(wif) < 0) 2465 return (SNMP_ERR_GENERR); 2466 2467 switch (val->var.subs[sub - 1]) { 2468 case LEAF_wlanMeshDroppedBadSta: 2469 val->v.uint32 = wif->stats.is_mesh_wrongmesh; 2470 break; 2471 case LEAF_wlanMeshDroppedNoLink: 2472 val->v.uint32 = wif->stats.is_mesh_nolink; 2473 break; 2474 case LEAF_wlanMeshNoFwdTtl: 2475 val->v.uint32 = wif->stats.is_mesh_fwd_ttl; 2476 break; 2477 case LEAF_wlanMeshNoFwdBuf: 2478 val->v.uint32 = wif->stats.is_mesh_fwd_nobuf; 2479 break; 2480 case LEAF_wlanMeshNoFwdTooShort: 2481 val->v.uint32 = wif->stats.is_mesh_fwd_tooshort; 2482 break; 2483 case LEAF_wlanMeshNoFwdDisabled: 2484 val->v.uint32 = wif->stats.is_mesh_fwd_disabled; 2485 break; 2486 case LEAF_wlanMeshNoFwdPathUnknown: 2487 val->v.uint32 = wif->stats.is_mesh_fwd_nopath; 2488 break; 2489 case LEAF_wlanMeshDroppedBadAE: 2490 val->v.uint32 = wif->stats.is_mesh_badae; 2491 break; 2492 case LEAF_wlanMeshRouteAddFailed: 2493 val->v.uint32 = wif->stats.is_mesh_rtaddfailed; 2494 break; 2495 case LEAF_wlanMeshDroppedNoProxy: 2496 val->v.uint32 = wif->stats.is_mesh_notproxy; 2497 break; 2498 case LEAF_wlanMeshDroppedMisaligned: 2499 val->v.uint32 = wif->stats.is_rx_badalign; 2500 break; 2501 default: 2502 abort(); 2503 } 2504 2505 return (SNMP_ERR_NOERROR); 2506 } 2507 2508 int 2509 op_wlan_hwmp_config(struct snmp_context *ctx, struct snmp_value *val, 2510 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2511 { 2512 int which; 2513 2514 switch (val->var.subs[sub - 1]) { 2515 case LEAF_wlanHWMPRouteInactiveTimeout: 2516 which = WLAN_HWMP_INACTIVITY_TO; 2517 break; 2518 case LEAF_wlanHWMPRootAnnounceInterval: 2519 which = WLAN_HWMP_RANN_INT; 2520 break; 2521 case LEAF_wlanHWMPRootInterval: 2522 which = WLAN_HWMP_ROOT_INT; 2523 break; 2524 case LEAF_wlanHWMPRootTimeout: 2525 which = WLAN_HWMP_ROOT_TO; 2526 break; 2527 case LEAF_wlanHWMPPathLifetime: 2528 which = WLAN_HWMP_PATH_LIFETIME; 2529 break; 2530 case LEAF_wlanHWMPReplyForwardBit: 2531 which = WLAN_HWMP_REPLY_FORWARD; 2532 break; 2533 case LEAF_wlanHWMPTargetOnlyBit: 2534 which = WLAN_HWMP_TARGET_ONLY; 2535 break; 2536 default: 2537 abort(); 2538 } 2539 2540 switch (op) { 2541 case SNMP_OP_GET: 2542 if (wlan_do_sysctl(&wlan_config, which, 0) < 0) 2543 return (SNMP_ERR_GENERR); 2544 break; 2545 2546 case SNMP_OP_GETNEXT: 2547 abort(); 2548 2549 case SNMP_OP_SET: 2550 switch (val->var.subs[sub - 1]) { 2551 case LEAF_wlanHWMPRouteInactiveTimeout: 2552 ctx->scratch->int1 = wlan_config.hwmp_inact; 2553 wlan_config.hwmp_inact = val->v.integer; 2554 break; 2555 case LEAF_wlanHWMPRootAnnounceInterval: 2556 ctx->scratch->int1 = wlan_config.hwmp_rannint; 2557 wlan_config.hwmp_rannint = val->v.integer; 2558 break; 2559 case LEAF_wlanHWMPRootInterval: 2560 ctx->scratch->int1 = wlan_config.hwmp_rootint; 2561 wlan_config.hwmp_rootint = val->v.integer; 2562 break; 2563 case LEAF_wlanHWMPRootTimeout: 2564 ctx->scratch->int1 = wlan_config.hwmp_roottimeout; 2565 wlan_config.hwmp_roottimeout = val->v.integer; 2566 break; 2567 case LEAF_wlanHWMPPathLifetime: 2568 ctx->scratch->int1 = wlan_config.hwmp_pathlifetime; 2569 wlan_config.hwmp_pathlifetime = val->v.integer; 2570 break; 2571 case LEAF_wlanHWMPReplyForwardBit: 2572 ctx->scratch->int1 = wlan_config.hwmp_replyforward; 2573 wlan_config.hwmp_replyforward = val->v.integer; 2574 break; 2575 case LEAF_wlanHWMPTargetOnlyBit: 2576 ctx->scratch->int1 = wlan_config.hwmp_targetonly; 2577 wlan_config.hwmp_targetonly = val->v.integer; 2578 break; 2579 } 2580 if (wlan_do_sysctl(&wlan_config, which, 1) < 0) 2581 return (SNMP_ERR_GENERR); 2582 return (SNMP_ERR_NOERROR); 2583 2584 case SNMP_OP_COMMIT: 2585 return (SNMP_ERR_NOERROR); 2586 2587 case SNMP_OP_ROLLBACK: 2588 switch (val->var.subs[sub - 1]) { 2589 case LEAF_wlanHWMPRouteInactiveTimeout: 2590 wlan_config.hwmp_inact = ctx->scratch->int1; 2591 break; 2592 case LEAF_wlanHWMPRootAnnounceInterval: 2593 wlan_config.hwmp_rannint = ctx->scratch->int1; 2594 break; 2595 case LEAF_wlanHWMPRootInterval: 2596 wlan_config.hwmp_rootint = ctx->scratch->int1; 2597 break; 2598 case LEAF_wlanHWMPRootTimeout: 2599 wlan_config.hwmp_roottimeout = ctx->scratch->int1; 2600 break; 2601 case LEAF_wlanHWMPPathLifetime: 2602 wlan_config.hwmp_pathlifetime = ctx->scratch->int1; 2603 break; 2604 case LEAF_wlanHWMPReplyForwardBit: 2605 wlan_config.hwmp_replyforward = ctx->scratch->int1; 2606 break; 2607 case LEAF_wlanHWMPTargetOnlyBit: 2608 wlan_config.hwmp_targetonly = ctx->scratch->int1; 2609 break; 2610 } 2611 if (wlan_do_sysctl(&wlan_config, which, 1) < 0) 2612 return (SNMP_ERR_GENERR); 2613 return (SNMP_ERR_NOERROR); 2614 2615 default: 2616 abort(); 2617 } 2618 2619 switch (val->var.subs[sub - 1]) { 2620 case LEAF_wlanHWMPRouteInactiveTimeout: 2621 val->v.integer = wlan_config.hwmp_inact; 2622 break; 2623 case LEAF_wlanHWMPRootAnnounceInterval: 2624 val->v.integer = wlan_config.hwmp_rannint; 2625 break; 2626 case LEAF_wlanHWMPRootInterval: 2627 val->v.integer = wlan_config.hwmp_rootint; 2628 break; 2629 case LEAF_wlanHWMPRootTimeout: 2630 val->v.integer = wlan_config.hwmp_roottimeout; 2631 break; 2632 case LEAF_wlanHWMPPathLifetime: 2633 val->v.integer = wlan_config.hwmp_pathlifetime; 2634 break; 2635 case LEAF_wlanHWMPReplyForwardBit: 2636 val->v.integer = wlan_config.hwmp_replyforward; 2637 break; 2638 case LEAF_wlanHWMPTargetOnlyBit: 2639 val->v.integer = wlan_config.hwmp_targetonly; 2640 break; 2641 } 2642 2643 return (SNMP_ERR_NOERROR); 2644 } 2645 2646 int 2647 op_wlan_hwmp_iface(struct snmp_context *ctx, struct snmp_value *val, 2648 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2649 { 2650 struct wlan_iface *wif; 2651 2652 wlan_update_interface_list(); 2653 2654 switch (op) { 2655 case SNMP_OP_GET: 2656 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2657 return (SNMP_ERR_NOSUCHNAME); 2658 break; 2659 2660 case SNMP_OP_GETNEXT: 2661 if ((wif = wlan_mesh_get_next_iface(&val->var, sub)) == NULL) 2662 return (SNMP_ERR_NOSUCHNAME); 2663 wlan_append_ifindex(&val->var, sub, wif); 2664 break; 2665 2666 case SNMP_OP_SET: 2667 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2668 return (SNMP_ERR_NOSUCHNAME); 2669 switch (val->var.subs[sub - 1]) { 2670 case LEAF_wlanHWMPRootMode: 2671 ctx->scratch->int1 = wif->hwmp_root_mode; 2672 wif->hwmp_root_mode = val->v.integer; 2673 break; 2674 case LEAF_wlanHWMPMaxHops: 2675 ctx->scratch->int1 = wif->hwmp_max_hops; 2676 wif->hwmp_max_hops = val->v.integer; 2677 break; 2678 default: 2679 abort(); 2680 } 2681 if (wlan_hwmp_config_set(wif, val->var.subs[sub - 1]) < 0) 2682 return (SNMP_ERR_GENERR); 2683 return (SNMP_ERR_NOERROR); 2684 2685 case SNMP_OP_COMMIT: 2686 return (SNMP_ERR_NOERROR); 2687 2688 case SNMP_OP_ROLLBACK: 2689 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2690 return (SNMP_ERR_NOSUCHNAME); 2691 switch (val->var.subs[sub - 1]) { 2692 case LEAF_wlanHWMPRootMode: 2693 wif->hwmp_root_mode = ctx->scratch->int1; 2694 break; 2695 case LEAF_wlanHWMPMaxHops: 2696 wif->hwmp_max_hops = ctx->scratch->int1; 2697 break; 2698 default: 2699 abort(); 2700 } 2701 if (wlan_hwmp_config_set(wif, val->var.subs[sub - 1]) < 0) 2702 return (SNMP_ERR_GENERR); 2703 return (SNMP_ERR_NOERROR); 2704 2705 default: 2706 abort(); 2707 } 2708 2709 if (wlan_hwmp_config_get(wif, val->var.subs[sub - 1]) < 0) 2710 return (SNMP_ERR_GENERR); 2711 2712 switch (val->var.subs[sub - 1]) { 2713 case LEAF_wlanHWMPRootMode: 2714 val->v.integer = wif->hwmp_root_mode; 2715 break; 2716 case LEAF_wlanHWMPMaxHops: 2717 val->v.integer = wif->hwmp_max_hops; 2718 break; 2719 default: 2720 abort(); 2721 } 2722 2723 return (SNMP_ERR_NOERROR); 2724 } 2725 2726 int 2727 op_wlan_hwmp_stats(struct snmp_context *ctx __unused, struct snmp_value *val, 2728 uint32_t sub, uint32_t iidx __unused, enum snmp_op op) 2729 { 2730 struct wlan_iface *wif; 2731 2732 wlan_update_interface_list(); 2733 2734 switch (op) { 2735 case SNMP_OP_GET: 2736 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL) 2737 return (SNMP_ERR_NOSUCHNAME); 2738 break; 2739 case SNMP_OP_GETNEXT: 2740 if ((wif = wlan_mesh_get_next_iface(&val->var, sub)) == NULL) 2741 return (SNMP_ERR_NOSUCHNAME); 2742 wlan_append_ifindex(&val->var, sub, wif); 2743 break; 2744 case SNMP_OP_SET: 2745 return (SNMP_ERR_NOT_WRITEABLE); 2746 case SNMP_OP_COMMIT: 2747 /* FALLTHROUGH */ 2748 case SNMP_OP_ROLLBACK: 2749 /* FALLTHROUGH */ 2750 default: 2751 abort(); 2752 } 2753 2754 if (wlan_get_stats(wif) < 0) 2755 return (SNMP_ERR_GENERR); 2756 2757 switch (val->var.subs[sub - 1]) { 2758 case LEAF_wlanMeshHWMPWrongSeqNo: 2759 val->v.uint32 = wif->stats.is_hwmp_wrongseq; 2760 break; 2761 case LEAF_wlanMeshHWMPTxRootPREQ: 2762 val->v.uint32 = wif->stats.is_hwmp_rootreqs; 2763 break; 2764 case LEAF_wlanMeshHWMPTxRootRANN: 2765 val->v.uint32 = wif->stats.is_hwmp_rootrann; 2766 break; 2767 case LEAF_wlanMeshHWMPProxy: 2768 val->v.uint32 = wif->stats.is_hwmp_proxy; 2769 break; 2770 default: 2771 abort(); 2772 } 2773 2774 return (SNMP_ERR_NOERROR); 2775 } 2776 2777 /* 2778 * Encode BITS type for a response packet - XXX: this belongs to the snmp lib. 2779 */ 2780 static int 2781 bits_get(struct snmp_value *value, const u_char *ptr, ssize_t len) 2782 { 2783 int size; 2784 2785 if (ptr == NULL) { 2786 value->v.octetstring.len = 0; 2787 value->v.octetstring.octets = NULL; 2788 return (SNMP_ERR_NOERROR); 2789 } 2790 2791 /* Determine length - up to 8 octets supported so far. */ 2792 for (size = len; size > 0; size--) 2793 if (ptr[size - 1] != 0) 2794 break; 2795 if (size == 0) 2796 size = 1; 2797 2798 value->v.octetstring.len = (u_long)size; 2799 if ((value->v.octetstring.octets = malloc((size_t)size)) == NULL) 2800 return (SNMP_ERR_RES_UNAVAIL); 2801 memcpy(value->v.octetstring.octets, ptr, (size_t)size); 2802 return (SNMP_ERR_NOERROR); 2803 } 2804 2805 /* 2806 * Calls for adding/updating/freeing/etc of wireless interfaces. 2807 */ 2808 static void 2809 wlan_free_interface(struct wlan_iface *wif) 2810 { 2811 wlan_free_peerlist(wif); 2812 free(wif->chanlist); 2813 wlan_scan_free_results(wif); 2814 wlan_mac_free_maclist(wif); 2815 wlan_mesh_free_routes(wif); 2816 free(wif); 2817 } 2818 2819 static void 2820 wlan_free_iflist(void) 2821 { 2822 struct wlan_iface *w; 2823 2824 while ((w = SLIST_FIRST(&wlan_ifaces)) != NULL) { 2825 SLIST_REMOVE_HEAD(&wlan_ifaces, w_if); 2826 wlan_free_interface(w); 2827 } 2828 } 2829 2830 static struct wlan_iface * 2831 wlan_find_interface(const char *wname) 2832 { 2833 struct wlan_iface *wif; 2834 2835 SLIST_FOREACH(wif, &wlan_ifaces, w_if) 2836 if (strcmp(wif->wname, wname) == 0) { 2837 if (wif->status != RowStatus_active) 2838 return (NULL); 2839 break; 2840 } 2841 2842 return (wif); 2843 } 2844 2845 static struct wlan_iface * 2846 wlan_first_interface(void) 2847 { 2848 return (SLIST_FIRST(&wlan_ifaces)); 2849 } 2850 2851 static struct wlan_iface * 2852 wlan_next_interface(struct wlan_iface *wif) 2853 { 2854 if (wif == NULL) 2855 return (NULL); 2856 2857 return (SLIST_NEXT(wif, w_if)); 2858 } 2859 2860 /* 2861 * Add a new interface to the list - sorted by name. 2862 */ 2863 static int 2864 wlan_add_wif(struct wlan_iface *wif) 2865 { 2866 int cmp; 2867 struct wlan_iface *temp, *prev; 2868 2869 if ((prev = SLIST_FIRST(&wlan_ifaces)) == NULL || 2870 strcmp(wif->wname, prev->wname) < 0) { 2871 SLIST_INSERT_HEAD(&wlan_ifaces, wif, w_if); 2872 return (0); 2873 } 2874 2875 SLIST_FOREACH(temp, &wlan_ifaces, w_if) { 2876 if ((cmp = strcmp(wif->wname, temp->wname)) <= 0) 2877 break; 2878 prev = temp; 2879 } 2880 2881 if (temp == NULL) 2882 SLIST_INSERT_AFTER(prev, wif, w_if); 2883 else if (cmp > 0) 2884 SLIST_INSERT_AFTER(temp, wif, w_if); 2885 else { 2886 syslog(LOG_ERR, "Wlan iface %s already in list", wif->wname); 2887 return (-1); 2888 } 2889 2890 return (0); 2891 } 2892 2893 static struct wlan_iface * 2894 wlan_new_wif(char *wname) 2895 { 2896 struct wlan_iface *wif; 2897 2898 /* Make sure it's not in the list. */ 2899 for (wif = wlan_first_interface(); wif != NULL; 2900 wif = wlan_next_interface(wif)) 2901 if (strcmp(wname, wif->wname) == 0) { 2902 wif->internal = 0; 2903 return (wif); 2904 } 2905 2906 if ((wif = (struct wlan_iface *)malloc(sizeof(*wif))) == NULL) 2907 return (NULL); 2908 2909 memset(wif, 0, sizeof(struct wlan_iface)); 2910 strlcpy(wif->wname, wname, IFNAMSIZ); 2911 wif->status = RowStatus_notReady; 2912 wif->state = wlanIfaceState_down; 2913 wif->mode = WlanIfaceOperatingModeType_station; 2914 2915 if (wlan_add_wif(wif) < 0) { 2916 free(wif); 2917 return (NULL); 2918 } 2919 2920 return (wif); 2921 } 2922 2923 static void 2924 wlan_delete_wif(struct wlan_iface *wif) 2925 { 2926 SLIST_REMOVE(&wlan_ifaces, wif, wlan_iface, w_if); 2927 wlan_free_interface(wif); 2928 } 2929 2930 static int 2931 wlan_attach_newif(struct mibif *mif) 2932 { 2933 struct wlan_iface *wif; 2934 2935 if (mif->mib.ifmd_data.ifi_type != IFT_ETHER || 2936 wlan_check_media(mif->name) != IFM_IEEE80211) 2937 return (0); 2938 2939 if ((wif = wlan_new_wif(mif->name)) == NULL) 2940 return (-1); 2941 2942 (void)wlan_get_opmode(wif); 2943 wif->index = mif->index; 2944 wif->status = RowStatus_active; 2945 (void)wlan_update_interface(wif); 2946 2947 return (0); 2948 } 2949 2950 static int 2951 wlan_iface_create(struct wlan_iface *wif) 2952 { 2953 int rc; 2954 2955 if ((rc = wlan_clone_create(wif)) == SNMP_ERR_NOERROR) { 2956 /* 2957 * The rest of the info will be updated once the 2958 * snmp_mibII module notifies us of the interface. 2959 */ 2960 wif->status = RowStatus_active; 2961 if (wif->state == wlanIfaceState_up) 2962 (void)wlan_config_state(wif, 1); 2963 } 2964 2965 return (rc); 2966 } 2967 2968 static int 2969 wlan_iface_destroy(struct wlan_iface *wif) 2970 { 2971 int rc = SNMP_ERR_NOERROR; 2972 2973 if (wif->internal == 0) 2974 rc = wlan_clone_destroy(wif); 2975 2976 if (rc == SNMP_ERR_NOERROR) 2977 wlan_delete_wif(wif); 2978 2979 return (rc); 2980 } 2981 2982 static int 2983 wlan_update_interface(struct wlan_iface *wif) 2984 { 2985 int i; 2986 2987 (void)wlan_config_state(wif, 0); 2988 (void)wlan_get_driver_caps(wif); 2989 for (i = LEAF_wlanIfacePacketBurst; 2990 i <= LEAF_wlanIfaceTdmaBeaconInterval; i++) 2991 (void)wlan_config_get_ioctl(wif, i); 2992 (void)wlan_get_stats(wif); 2993 /* 2994 * XXX: wlan_get_channel_list() not needed - 2995 * fetched with wlan_get_driver_caps() 2996 */ 2997 (void)wlan_get_channel_list(wif); 2998 (void)wlan_get_roam_params(wif); 2999 (void)wlan_get_tx_params(wif); 3000 (void)wlan_get_scan_results(wif); 3001 (void)wlan_get_wepmode(wif); 3002 (void)wlan_get_weptxkey(wif); 3003 (void)wlan_get_mac_policy(wif); 3004 (void)wlan_get_mac_acl_macs(wif); 3005 (void)wlan_get_peerinfo(wif); 3006 3007 if (wif->mode == WlanIfaceOperatingModeType_meshPoint) { 3008 for (i = LEAF_wlanMeshTTL; i <= LEAF_wlanMeshPath; i++) 3009 (void)wlan_mesh_config_get(wif, i); 3010 (void)wlan_mesh_get_routelist(wif); 3011 for (i = LEAF_wlanHWMPRootMode; i <= LEAF_wlanHWMPMaxHops; i++) 3012 (void)wlan_hwmp_config_get(wif, i); 3013 } 3014 3015 return (0); 3016 } 3017 3018 static void 3019 wlan_update_interface_list(void) 3020 { 3021 struct wlan_iface *wif, *twif; 3022 3023 if ((time(NULL) - wlan_iflist_age) <= WLAN_LIST_MAXAGE) 3024 return; 3025 3026 /* 3027 * The snmp_mibII module would have notified us for new interfaces, 3028 * so only check if any have been deleted. 3029 */ 3030 SLIST_FOREACH_SAFE(wif, &wlan_ifaces, w_if, twif) 3031 if (wif->status == RowStatus_active && wlan_get_opmode(wif) < 0) 3032 wlan_delete_wif(wif); 3033 3034 wlan_iflist_age = time(NULL); 3035 } 3036 3037 static void 3038 wlan_append_ifindex(struct asn_oid *oid, uint sub, const struct wlan_iface *w) 3039 { 3040 uint32_t i; 3041 3042 oid->len = sub + strlen(w->wname) + 1; 3043 oid->subs[sub] = strlen(w->wname); 3044 for (i = 1; i <= strlen(w->wname); i++) 3045 oid->subs[sub + i] = w->wname[i - 1]; 3046 } 3047 3048 static uint8_t * 3049 wlan_get_ifname(const struct asn_oid *oid, uint sub, uint8_t *wname) 3050 { 3051 uint32_t i; 3052 3053 memset(wname, 0, IFNAMSIZ); 3054 3055 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ) 3056 return (NULL); 3057 3058 for (i = 0; i < oid->subs[sub]; i++) 3059 wname[i] = oid->subs[sub + i + 1]; 3060 wname[i] = '\0'; 3061 3062 return (wname); 3063 } 3064 3065 static struct wlan_iface * 3066 wlan_get_interface(const struct asn_oid *oid, uint sub) 3067 { 3068 uint8_t wname[IFNAMSIZ]; 3069 3070 if (wlan_get_ifname(oid, sub, wname) == NULL) 3071 return (NULL); 3072 3073 return (wlan_find_interface(wname)); 3074 } 3075 3076 static struct wlan_iface * 3077 wlan_get_next_interface(const struct asn_oid *oid, uint sub) 3078 { 3079 uint32_t i; 3080 uint8_t wname[IFNAMSIZ]; 3081 struct wlan_iface *wif; 3082 3083 if (oid->len - sub == 0) { 3084 for (wif = wlan_first_interface(); wif != NULL; 3085 wif = wlan_next_interface(wif)) 3086 if (wif->status == RowStatus_active) 3087 break; 3088 return (wif); 3089 } 3090 3091 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ) 3092 return (NULL); 3093 3094 memset(wname, 0, IFNAMSIZ); 3095 for (i = 0; i < oid->subs[sub]; i++) 3096 wname[i] = oid->subs[sub + i + 1]; 3097 wname[i] = '\0'; 3098 if ((wif = wlan_find_interface(wname)) == NULL) 3099 return (NULL); 3100 3101 while ((wif = wlan_next_interface(wif)) != NULL) 3102 if (wif->status == RowStatus_active) 3103 break; 3104 3105 return (wif); 3106 } 3107 3108 static struct wlan_iface * 3109 wlan_get_snmp_interface(const struct asn_oid *oid, uint sub) 3110 { 3111 uint8_t wname[IFNAMSIZ]; 3112 struct wlan_iface *wif; 3113 3114 if (wlan_get_ifname(oid, sub, wname) == NULL) 3115 return (NULL); 3116 3117 for (wif = wlan_first_interface(); wif != NULL; 3118 wif = wlan_next_interface(wif)) 3119 if (strcmp(wif->wname, wname) == 0) 3120 break; 3121 3122 return (wif); 3123 } 3124 3125 static struct wlan_iface * 3126 wlan_get_next_snmp_interface(const struct asn_oid *oid, uint sub) 3127 { 3128 uint32_t i; 3129 uint8_t wname[IFNAMSIZ]; 3130 struct wlan_iface *wif; 3131 3132 if (oid->len - sub == 0) 3133 return (wlan_first_interface()); 3134 3135 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ) 3136 return (NULL); 3137 3138 memset(wname, 0, IFNAMSIZ); 3139 for (i = 0; i < oid->subs[sub]; i++) 3140 wname[i] = oid->subs[sub + i + 1]; 3141 wname[i] = '\0'; 3142 3143 for (wif = wlan_first_interface(); wif != NULL; 3144 wif = wlan_next_interface(wif)) 3145 if (strcmp(wif->wname, wname) == 0) 3146 break; 3147 3148 return (wlan_next_interface(wif)); 3149 } 3150 3151 /* 3152 * Decode/Append an index for tables indexed by the wireless interface 3153 * name and a MAC address - ACL MACs and Mesh Routes. 3154 */ 3155 static int 3156 wlan_mac_index_decode(const struct asn_oid *oid, uint sub, 3157 char *wname, uint8_t *mac) 3158 { 3159 uint32_t i; 3160 int mac_off; 3161 3162 if (oid->len - sub != oid->subs[sub] + 2 + IEEE80211_ADDR_LEN 3163 || oid->subs[sub] >= IFNAMSIZ) 3164 return (-1); 3165 3166 for (i = 0; i < oid->subs[sub]; i++) 3167 wname[i] = oid->subs[sub + i + 1]; 3168 wname[i] = '\0'; 3169 3170 mac_off = sub + oid->subs[sub] + 1; 3171 if (oid->subs[mac_off] != IEEE80211_ADDR_LEN) 3172 return (-1); 3173 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 3174 mac[i] = oid->subs[mac_off + i + 1]; 3175 3176 return (0); 3177 } 3178 3179 static void 3180 wlan_append_mac_index(struct asn_oid *oid, uint sub, char *wname, uint8_t *mac) 3181 { 3182 uint32_t i; 3183 3184 oid->len = sub + strlen(wname) + IEEE80211_ADDR_LEN + 2; 3185 oid->subs[sub] = strlen(wname); 3186 for (i = 1; i <= strlen(wname); i++) 3187 oid->subs[sub + i] = wname[i - 1]; 3188 3189 sub += strlen(wname) + 1; 3190 oid->subs[sub] = IEEE80211_ADDR_LEN; 3191 for (i = 1; i <= IEEE80211_ADDR_LEN; i++) 3192 oid->subs[sub + i] = mac[i - 1]; 3193 } 3194 3195 /* 3196 * Decode/Append an index for tables indexed by the wireless interface 3197 * name and the PHY mode - Roam and TX params. 3198 */ 3199 static int 3200 wlan_phy_index_decode(const struct asn_oid *oid, uint sub, char *wname, 3201 uint32_t *phy) 3202 { 3203 uint32_t i; 3204 3205 if (oid->len - sub != oid->subs[sub] + 2 || oid->subs[sub] >= IFNAMSIZ) 3206 return (-1); 3207 3208 for (i = 0; i < oid->subs[sub]; i++) 3209 wname[i] = oid->subs[sub + i + 1]; 3210 wname[i] = '\0'; 3211 3212 *phy = oid->subs[sub + oid->subs[sub] + 1]; 3213 return (0); 3214 } 3215 3216 static void 3217 wlan_append_phy_index(struct asn_oid *oid, uint sub, char *wname, uint32_t phy) 3218 { 3219 uint32_t i; 3220 3221 oid->len = sub + strlen(wname) + 2; 3222 oid->subs[sub] = strlen(wname); 3223 for (i = 1; i <= strlen(wname); i++) 3224 oid->subs[sub + i] = wname[i - 1]; 3225 oid->subs[sub + strlen(wname) + 1] = phy; 3226 } 3227 3228 /* 3229 * Calls for manipulating the peerlist of a wireless interface. 3230 */ 3231 static void 3232 wlan_free_peerlist(struct wlan_iface *wif) 3233 { 3234 struct wlan_peer *wip; 3235 3236 while ((wip = SLIST_FIRST(&wif->peerlist)) != NULL) { 3237 SLIST_REMOVE_HEAD(&wif->peerlist, wp); 3238 free(wip); 3239 } 3240 3241 SLIST_INIT(&wif->peerlist); 3242 } 3243 3244 static struct wlan_peer * 3245 wlan_find_peer(struct wlan_iface *wif, uint8_t *peermac) 3246 { 3247 struct wlan_peer *wip; 3248 3249 SLIST_FOREACH(wip, &wif->peerlist, wp) 3250 if (memcmp(wip->pmac, peermac, IEEE80211_ADDR_LEN) == 0) 3251 break; 3252 3253 return (wip); 3254 } 3255 3256 struct wlan_peer * 3257 wlan_new_peer(const uint8_t *pmac) 3258 { 3259 struct wlan_peer *wip; 3260 3261 if ((wip = (struct wlan_peer *)malloc(sizeof(*wip))) == NULL) 3262 return (NULL); 3263 3264 memset(wip, 0, sizeof(struct wlan_peer)); 3265 memcpy(wip->pmac, pmac, IEEE80211_ADDR_LEN); 3266 3267 return (wip); 3268 } 3269 3270 void 3271 wlan_free_peer(struct wlan_peer *wip) 3272 { 3273 free(wip); 3274 } 3275 3276 int 3277 wlan_add_peer(struct wlan_iface *wif, struct wlan_peer *wip) 3278 { 3279 struct wlan_peer *temp, *prev; 3280 3281 SLIST_FOREACH(temp, &wif->peerlist, wp) 3282 if (memcmp(temp->pmac, wip->pmac, IEEE80211_ADDR_LEN) == 0) 3283 return (-1); 3284 3285 if ((prev = SLIST_FIRST(&wif->peerlist)) == NULL || 3286 memcmp(wip->pmac, prev->pmac, IEEE80211_ADDR_LEN) < 0) { 3287 SLIST_INSERT_HEAD(&wif->peerlist, wip, wp); 3288 return (0); 3289 } 3290 3291 SLIST_FOREACH(temp, &wif->peerlist, wp) { 3292 if (memcmp(wip->pmac, temp->pmac, IEEE80211_ADDR_LEN) < 0) 3293 break; 3294 prev = temp; 3295 } 3296 3297 SLIST_INSERT_AFTER(prev, wip, wp); 3298 return (0); 3299 } 3300 3301 static void 3302 wlan_update_peers(void) 3303 { 3304 struct wlan_iface *wif; 3305 3306 if ((time(NULL) - wlan_peerlist_age) <= WLAN_LIST_MAXAGE) 3307 return; 3308 3309 for (wif = wlan_first_interface(); wif != NULL; 3310 wif = wlan_next_interface(wif)) { 3311 if (wif->status != RowStatus_active) 3312 continue; 3313 wlan_free_peerlist(wif); 3314 (void)wlan_get_peerinfo(wif); 3315 } 3316 wlan_peerlist_age = time(NULL); 3317 } 3318 3319 static struct wlan_peer * 3320 wlan_get_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 3321 { 3322 char wname[IFNAMSIZ]; 3323 uint8_t pmac[IEEE80211_ADDR_LEN]; 3324 3325 if (wlan_mac_index_decode(oid, sub, wname, pmac) < 0) 3326 return (NULL); 3327 3328 if ((*wif = wlan_find_interface(wname)) == NULL) 3329 return (NULL); 3330 3331 return (wlan_find_peer(*wif, pmac)); 3332 } 3333 3334 static struct wlan_peer * 3335 wlan_get_next_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 3336 { 3337 char wname[IFNAMSIZ]; 3338 char pmac[IEEE80211_ADDR_LEN]; 3339 struct wlan_peer *wip; 3340 3341 if (oid->len - sub == 0) { 3342 for (*wif = wlan_first_interface(); *wif != NULL; 3343 *wif = wlan_next_interface(*wif)) { 3344 if ((*wif)->mode == 3345 WlanIfaceOperatingModeType_meshPoint) 3346 continue; 3347 wip = SLIST_FIRST(&(*wif)->peerlist); 3348 if (wip != NULL) 3349 return (wip); 3350 } 3351 return (NULL); 3352 } 3353 3354 if (wlan_mac_index_decode(oid, sub, wname, pmac) < 0 || 3355 (*wif = wlan_find_interface(wname)) == NULL || 3356 (wip = wlan_find_peer(*wif, pmac)) == NULL) 3357 return (NULL); 3358 3359 if ((wip = SLIST_NEXT(wip, wp)) != NULL) 3360 return (wip); 3361 3362 while ((*wif = wlan_next_interface(*wif)) != NULL) { 3363 if ((*wif)->mode == WlanIfaceOperatingModeType_meshPoint) 3364 continue; 3365 if ((wip = SLIST_FIRST(&(*wif)->peerlist)) != NULL) 3366 break; 3367 } 3368 3369 return (wip); 3370 } 3371 3372 /* 3373 * Calls for manipulating the active channel list of a wireless interface. 3374 */ 3375 static void 3376 wlan_update_channels(void) 3377 { 3378 struct wlan_iface *wif; 3379 3380 if ((time(NULL) - wlan_chanlist_age) <= WLAN_LIST_MAXAGE) 3381 return; 3382 3383 for (wif = wlan_first_interface(); wif != NULL; 3384 wif = wlan_next_interface(wif)) { 3385 if (wif->status != RowStatus_active) 3386 continue; 3387 (void)wlan_get_channel_list(wif); 3388 } 3389 wlan_chanlist_age = time(NULL); 3390 } 3391 3392 static int 3393 wlan_channel_index_decode(const struct asn_oid *oid, uint sub, char *wname, 3394 uint32_t *cindex) 3395 { 3396 uint32_t i; 3397 if (oid->len - sub != oid->subs[sub] + 2 || oid->subs[sub] >= IFNAMSIZ) 3398 return (-1); 3399 3400 for (i = 0; i < oid->subs[sub]; i++) 3401 wname[i] = oid->subs[sub + i + 1]; 3402 wname[i] = '\0'; 3403 3404 *cindex = oid->subs[sub + oid->subs[sub] + 1]; 3405 3406 return (0); 3407 } 3408 3409 static void 3410 wlan_append_channel_index(struct asn_oid *oid, uint sub, 3411 const struct wlan_iface *wif, const struct ieee80211_channel *channel) 3412 { 3413 uint32_t i; 3414 3415 oid->len = sub + strlen(wif->wname) + 2; 3416 oid->subs[sub] = strlen(wif->wname); 3417 for (i = 1; i <= strlen(wif->wname); i++) 3418 oid->subs[sub + i] = wif->wname[i - 1]; 3419 oid->subs[sub + strlen(wif->wname) + 1] = (channel - wif->chanlist) + 1; 3420 } 3421 3422 static int32_t 3423 wlan_get_channel_type(struct ieee80211_channel *c) 3424 { 3425 if (IEEE80211_IS_CHAN_FHSS(c)) 3426 return (WlanChannelType_fhss); 3427 if (IEEE80211_IS_CHAN_A(c)) 3428 return (WlanChannelType_dot11a); 3429 if (IEEE80211_IS_CHAN_B(c)) 3430 return (WlanChannelType_dot11b); 3431 if (IEEE80211_IS_CHAN_ANYG(c)) 3432 return (WlanChannelType_dot11g); 3433 if (IEEE80211_IS_CHAN_HALF(c)) 3434 return (WlanChannelType_tenMHz); 3435 if (IEEE80211_IS_CHAN_QUARTER(c)) 3436 return (WlanChannelType_fiveMHz); 3437 if (IEEE80211_IS_CHAN_TURBO(c)) 3438 return (WlanChannelType_turbo); 3439 if (IEEE80211_IS_CHAN_HT(c)) 3440 return (WlanChannelType_ht); 3441 3442 return (-1); 3443 } 3444 3445 static struct ieee80211_channel * 3446 wlan_find_channel(struct wlan_iface *wif, uint32_t cindex) 3447 { 3448 if (wif->chanlist == NULL || cindex > wif->nchannels) 3449 return (NULL); 3450 3451 return (wif->chanlist + cindex - 1); 3452 } 3453 3454 static struct ieee80211_channel * 3455 wlan_get_channel(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 3456 { 3457 uint32_t cindex; 3458 char wname[IFNAMSIZ]; 3459 3460 if (wlan_channel_index_decode(oid, sub, wname, &cindex) < 0) 3461 return (NULL); 3462 3463 if ((*wif = wlan_find_interface(wname)) == NULL) 3464 return (NULL); 3465 3466 return (wlan_find_channel(*wif, cindex)); 3467 } 3468 3469 static struct ieee80211_channel * 3470 wlan_get_next_channel(const struct asn_oid *oid, uint sub, 3471 struct wlan_iface **wif) 3472 { 3473 uint32_t cindex; 3474 char wname[IFNAMSIZ]; 3475 3476 if (oid->len - sub == 0) { 3477 for (*wif = wlan_first_interface(); *wif != NULL; 3478 *wif = wlan_next_interface(*wif)) { 3479 if ((*wif)->status != RowStatus_active) 3480 continue; 3481 if ((*wif)->nchannels != 0 && (*wif)->chanlist != NULL) 3482 return ((*wif)->chanlist); 3483 } 3484 return (NULL); 3485 } 3486 3487 if (wlan_channel_index_decode(oid, sub, wname, &cindex) < 0) 3488 return (NULL); 3489 3490 if ((*wif = wlan_find_interface(wname)) == NULL) 3491 return (NULL); 3492 3493 if (cindex < (*wif)->nchannels) 3494 return ((*wif)->chanlist + cindex); 3495 3496 while ((*wif = wlan_next_interface(*wif)) != NULL) 3497 if ((*wif)->status == RowStatus_active) 3498 if ((*wif)->nchannels != 0 && (*wif)->chanlist != NULL) 3499 return ((*wif)->chanlist); 3500 3501 return (NULL); 3502 } 3503 3504 /* 3505 * Calls for manipulating the roam params of a wireless interface. 3506 */ 3507 static void 3508 wlan_update_roam_params(void) 3509 { 3510 struct wlan_iface *wif; 3511 3512 if ((time(NULL) - wlan_roamlist_age) <= WLAN_LIST_MAXAGE) 3513 return; 3514 3515 for (wif = wlan_first_interface(); wif != NULL; 3516 wif = wlan_next_interface(wif)) { 3517 if (wif->status != RowStatus_active) 3518 continue; 3519 (void)wlan_get_roam_params(wif); 3520 } 3521 wlan_roamlist_age = time(NULL); 3522 } 3523 3524 static struct ieee80211_roamparam * 3525 wlan_get_roam_param(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 3526 { 3527 uint32_t phy; 3528 char wname[IFNAMSIZ]; 3529 3530 if (wlan_phy_index_decode(oid, sub, wname, &phy) < 0) 3531 return (NULL); 3532 3533 if ((*wif = wlan_find_interface(wname)) == NULL) 3534 return (NULL); 3535 3536 if (phy == 0 || phy > IEEE80211_MODE_MAX) 3537 return (NULL); 3538 3539 return ((*wif)->roamparams.params + phy - 1); 3540 } 3541 3542 static struct ieee80211_roamparam * 3543 wlan_get_next_roam_param(const struct asn_oid *oid, uint sub, 3544 struct wlan_iface **wif, uint32_t *phy) 3545 { 3546 char wname[IFNAMSIZ]; 3547 3548 if (oid->len - sub == 0) { 3549 for (*wif = wlan_first_interface(); *wif != NULL; 3550 *wif = wlan_next_interface(*wif)) { 3551 if ((*wif)->status != RowStatus_active) 3552 continue; 3553 *phy = 1; 3554 return ((*wif)->roamparams.params); 3555 } 3556 return (NULL); 3557 } 3558 3559 if (wlan_phy_index_decode(oid, sub, wname, phy) < 0) 3560 return (NULL); 3561 3562 if (*phy == 0 || (*wif = wlan_find_interface(wname)) == NULL) 3563 return (NULL); 3564 3565 if (++(*phy) <= IEEE80211_MODE_MAX) 3566 return ((*wif)->roamparams.params + *phy - 1); 3567 3568 *phy = 1; 3569 while ((*wif = wlan_next_interface(*wif)) != NULL) 3570 if ((*wif)->status == RowStatus_active) 3571 return ((*wif)->roamparams.params); 3572 3573 return (NULL); 3574 } 3575 3576 /* 3577 * Calls for manipulating the tx params of a wireless interface. 3578 */ 3579 static void 3580 wlan_update_tx_params(void) 3581 { 3582 struct wlan_iface *wif; 3583 3584 if ((time(NULL) - wlan_tx_paramlist_age) <= WLAN_LIST_MAXAGE) 3585 return; 3586 3587 for (wif = wlan_first_interface(); wif != NULL; 3588 wif = wlan_next_interface(wif)) { 3589 if (wif->status != RowStatus_active) 3590 continue; 3591 (void)wlan_get_tx_params(wif); 3592 } 3593 3594 wlan_tx_paramlist_age = time(NULL); 3595 } 3596 3597 static struct ieee80211_txparam * 3598 wlan_get_tx_param(const struct asn_oid *oid, uint sub, struct wlan_iface **wif, 3599 uint32_t *phy) 3600 { 3601 char wname[IFNAMSIZ]; 3602 3603 if (wlan_phy_index_decode(oid, sub, wname, phy) < 0) 3604 return (NULL); 3605 3606 if ((*wif = wlan_find_interface(wname)) == NULL) 3607 return (NULL); 3608 3609 if (*phy == 0 || *phy > IEEE80211_MODE_MAX) 3610 return (NULL); 3611 3612 return ((*wif)->txparams.params + *phy - 1); 3613 } 3614 3615 static struct ieee80211_txparam * 3616 wlan_get_next_tx_param(const struct asn_oid *oid, uint sub, 3617 struct wlan_iface **wif, uint32_t *phy) 3618 { 3619 char wname[IFNAMSIZ]; 3620 3621 if (oid->len - sub == 0) { 3622 for (*wif = wlan_first_interface(); *wif != NULL; 3623 *wif = wlan_next_interface(*wif)) { 3624 if ((*wif)->status != RowStatus_active) 3625 continue; 3626 *phy = 1; 3627 return ((*wif)->txparams.params); 3628 } 3629 return (NULL); 3630 } 3631 3632 if (wlan_phy_index_decode(oid, sub, wname, phy) < 0) 3633 return (NULL); 3634 3635 if (*phy == 0 || (*wif = wlan_find_interface(wname)) == NULL) 3636 return (NULL); 3637 3638 if (++(*phy) <= IEEE80211_MODE_MAX) 3639 return ((*wif)->txparams.params + *phy - 1); 3640 3641 *phy = 1; 3642 while ((*wif = wlan_next_interface(*wif)) != NULL) 3643 if ((*wif)->status == RowStatus_active) 3644 return ((*wif)->txparams.params); 3645 3646 return (NULL); 3647 } 3648 3649 /* 3650 * Calls for manipulating the scan results for a wireless interface. 3651 */ 3652 static void 3653 wlan_scan_free_results(struct wlan_iface *wif) 3654 { 3655 struct wlan_scan_result *sr; 3656 3657 while ((sr = SLIST_FIRST(&wif->scanlist)) != NULL) { 3658 SLIST_REMOVE_HEAD(&wif->scanlist, wsr); 3659 free(sr); 3660 } 3661 3662 SLIST_INIT(&wif->scanlist); 3663 } 3664 3665 static struct wlan_scan_result * 3666 wlan_scan_find_result(struct wlan_iface *wif, uint8_t *ssid, uint8_t *bssid) 3667 { 3668 struct wlan_scan_result *sr; 3669 3670 SLIST_FOREACH(sr, &wif->scanlist, wsr) 3671 if (strlen(ssid) == strlen(sr->ssid) && 3672 strcmp(sr->ssid, ssid) == 0 && 3673 memcmp(sr->bssid, bssid, IEEE80211_ADDR_LEN) == 0) 3674 break; 3675 3676 return (sr); 3677 } 3678 3679 struct wlan_scan_result * 3680 wlan_scan_new_result(const uint8_t *ssid, const uint8_t *bssid) 3681 { 3682 struct wlan_scan_result *sr; 3683 3684 sr = (struct wlan_scan_result *)malloc(sizeof(*sr)); 3685 if (sr == NULL) 3686 return (NULL); 3687 3688 memset(sr, 0, sizeof(*sr)); 3689 if (ssid[0] != '\0') 3690 strlcpy(sr->ssid, ssid, IEEE80211_NWID_LEN + 1); 3691 memcpy(sr->bssid, bssid, IEEE80211_ADDR_LEN); 3692 3693 return (sr); 3694 } 3695 3696 void 3697 wlan_scan_free_result(struct wlan_scan_result *sr) 3698 { 3699 free(sr); 3700 } 3701 3702 static int 3703 wlan_scan_compare_result(struct wlan_scan_result *sr1, 3704 struct wlan_scan_result *sr2) 3705 { 3706 uint32_t i; 3707 3708 if (strlen(sr1->ssid) < strlen(sr2->ssid)) 3709 return (-1); 3710 if (strlen(sr1->ssid) > strlen(sr2->ssid)) 3711 return (1); 3712 3713 for (i = 0; i < strlen(sr1->ssid) && i < strlen(sr2->ssid); i++) { 3714 if (sr1->ssid[i] < sr2->ssid[i]) 3715 return (-1); 3716 if (sr1->ssid[i] > sr2->ssid[i]) 3717 return (1); 3718 } 3719 3720 for (i = 0; i < IEEE80211_ADDR_LEN; i++) { 3721 if (sr1->bssid[i] < sr2->bssid[i]) 3722 return (-1); 3723 if (sr1->bssid[i] > sr2->bssid[i]) 3724 return (1); 3725 } 3726 3727 return (0); 3728 } 3729 3730 int 3731 wlan_scan_add_result(struct wlan_iface *wif, struct wlan_scan_result *sr) 3732 { 3733 struct wlan_scan_result *prev, *temp; 3734 3735 SLIST_FOREACH(temp, &wif->scanlist, wsr) 3736 if (strlen(temp->ssid) == strlen(sr->ssid) && 3737 strcmp(sr->ssid, temp->ssid) == 0 && 3738 memcmp(sr->bssid, temp->bssid, IEEE80211_ADDR_LEN) == 0) 3739 return (-1); 3740 3741 if ((prev = SLIST_FIRST(&wif->scanlist)) == NULL || 3742 wlan_scan_compare_result(sr, prev) < 0) { 3743 SLIST_INSERT_HEAD(&wif->scanlist, sr, wsr); 3744 return (0); 3745 } 3746 3747 SLIST_FOREACH(temp, &wif->scanlist, wsr) { 3748 if (wlan_scan_compare_result(sr, temp) < 0) 3749 break; 3750 prev = temp; 3751 } 3752 3753 SLIST_INSERT_AFTER(prev, sr, wsr); 3754 return (0); 3755 } 3756 3757 static void 3758 wlan_scan_update_results(void) 3759 { 3760 struct wlan_iface *wif; 3761 3762 if ((time(NULL) - wlan_scanlist_age) <= WLAN_LIST_MAXAGE) 3763 return; 3764 3765 for (wif = wlan_first_interface(); wif != NULL; 3766 wif = wlan_next_interface(wif)) { 3767 if (wif->status != RowStatus_active) 3768 continue; 3769 wlan_scan_free_results(wif); 3770 (void)wlan_get_scan_results(wif); 3771 } 3772 wlan_scanlist_age = time(NULL); 3773 } 3774 3775 static int 3776 wlan_scanr_index_decode(const struct asn_oid *oid, uint sub, 3777 char *wname, uint8_t *ssid, uint8_t *bssid) 3778 { 3779 uint32_t i; 3780 int offset; 3781 3782 if (oid->subs[sub] >= IFNAMSIZ) 3783 return (-1); 3784 for (i = 0; i < oid->subs[sub]; i++) 3785 wname[i] = oid->subs[sub + i + 1]; 3786 wname[oid->subs[sub]] = '\0'; 3787 3788 offset = sub + oid->subs[sub] + 1; 3789 if (oid->subs[offset] > IEEE80211_NWID_LEN) 3790 return (-1); 3791 for (i = 0; i < oid->subs[offset]; i++) 3792 ssid[i] = oid->subs[offset + i + 1]; 3793 ssid[i] = '\0'; 3794 3795 offset = sub + oid->subs[sub] + oid->subs[offset] + 2; 3796 if (oid->subs[offset] != IEEE80211_ADDR_LEN) 3797 return (-1); 3798 for (i = 0; i < IEEE80211_ADDR_LEN; i++) 3799 bssid[i] = oid->subs[offset + i + 1]; 3800 3801 return (0); 3802 } 3803 3804 static void 3805 wlan_append_scanr_index(struct asn_oid *oid, uint sub, char *wname, 3806 uint8_t *ssid, uint8_t *bssid) 3807 { 3808 uint32_t i; 3809 3810 oid->len = sub + strlen(wname) + strlen(ssid) + IEEE80211_ADDR_LEN + 3; 3811 oid->subs[sub] = strlen(wname); 3812 for (i = 1; i <= strlen(wname); i++) 3813 oid->subs[sub + i] = wname[i - 1]; 3814 3815 sub += strlen(wname) + 1; 3816 oid->subs[sub] = strlen(ssid); 3817 for (i = 1; i <= strlen(ssid); i++) 3818 oid->subs[sub + i] = ssid[i - 1]; 3819 3820 sub += strlen(ssid) + 1; 3821 oid->subs[sub] = IEEE80211_ADDR_LEN; 3822 for (i = 1; i <= IEEE80211_ADDR_LEN; i++) 3823 oid->subs[sub + i] = bssid[i - 1]; 3824 } 3825 3826 static struct wlan_scan_result * 3827 wlan_get_scanr(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 3828 { 3829 char wname[IFNAMSIZ]; 3830 uint8_t ssid[IEEE80211_NWID_LEN + 1]; 3831 uint8_t bssid[IEEE80211_ADDR_LEN]; 3832 3833 if (wlan_scanr_index_decode(oid, sub, wname, ssid, bssid) < 0) 3834 return (NULL); 3835 3836 if ((*wif = wlan_find_interface(wname)) == NULL) 3837 return (NULL); 3838 3839 return (wlan_scan_find_result(*wif, ssid, bssid)); 3840 } 3841 3842 static struct wlan_scan_result * 3843 wlan_get_next_scanr(const struct asn_oid *oid, uint sub, 3844 struct wlan_iface **wif) 3845 { 3846 char wname[IFNAMSIZ]; 3847 uint8_t ssid[IEEE80211_NWID_LEN + 1]; 3848 uint8_t bssid[IEEE80211_ADDR_LEN]; 3849 struct wlan_scan_result *sr; 3850 3851 if (oid->len - sub == 0) { 3852 for (*wif = wlan_first_interface(); *wif != NULL; 3853 *wif = wlan_next_interface(*wif)) { 3854 sr = SLIST_FIRST(&(*wif)->scanlist); 3855 if (sr != NULL) 3856 return (sr); 3857 } 3858 return (NULL); 3859 } 3860 3861 if (wlan_scanr_index_decode(oid, sub, wname, ssid, bssid) < 0 || 3862 (*wif = wlan_find_interface(wname)) == NULL || 3863 (sr = wlan_scan_find_result(*wif, ssid, bssid)) == NULL) 3864 return (NULL); 3865 3866 if ((sr = SLIST_NEXT(sr, wsr)) != NULL) 3867 return (sr); 3868 3869 while ((*wif = wlan_next_interface(*wif)) != NULL) 3870 if ((sr = SLIST_FIRST(&(*wif)->scanlist)) != NULL) 3871 break; 3872 3873 return (sr); 3874 } 3875 3876 /* 3877 * MAC Access Control. 3878 */ 3879 static void 3880 wlan_mac_free_maclist(struct wlan_iface *wif) 3881 { 3882 struct wlan_mac_mac *wmm; 3883 3884 while ((wmm = SLIST_FIRST(&wif->mac_maclist)) != NULL) { 3885 SLIST_REMOVE_HEAD(&wif->mac_maclist, wm); 3886 free(wmm); 3887 } 3888 3889 SLIST_INIT(&wif->mac_maclist); 3890 } 3891 3892 static struct wlan_mac_mac * 3893 wlan_mac_find_mac(struct wlan_iface *wif, uint8_t *mac) 3894 { 3895 struct wlan_mac_mac *wmm; 3896 3897 SLIST_FOREACH(wmm, &wif->mac_maclist, wm) 3898 if (memcmp(wmm->mac, mac, IEEE80211_ADDR_LEN) == 0) 3899 break; 3900 3901 return (wmm); 3902 } 3903 3904 struct wlan_mac_mac * 3905 wlan_mac_new_mac(const uint8_t *mac) 3906 { 3907 struct wlan_mac_mac *wmm; 3908 3909 if ((wmm = (struct wlan_mac_mac *)malloc(sizeof(*wmm))) == NULL) 3910 return (NULL); 3911 3912 memset(wmm, 0, sizeof(*wmm)); 3913 memcpy(wmm->mac, mac, IEEE80211_ADDR_LEN); 3914 wmm->mac_status = RowStatus_notReady; 3915 3916 return (wmm); 3917 } 3918 3919 void 3920 wlan_mac_free_mac(struct wlan_mac_mac *wmm) 3921 { 3922 free(wmm); 3923 } 3924 3925 int 3926 wlan_mac_add_mac(struct wlan_iface *wif, struct wlan_mac_mac *wmm) 3927 { 3928 struct wlan_mac_mac *temp, *prev; 3929 3930 SLIST_FOREACH(temp, &wif->mac_maclist, wm) 3931 if (memcmp(temp->mac, wmm->mac, IEEE80211_ADDR_LEN) == 0) 3932 return (-1); 3933 3934 if ((prev = SLIST_FIRST(&wif->mac_maclist)) == NULL || 3935 memcmp(wmm->mac, prev->mac,IEEE80211_ADDR_LEN) < 0) { 3936 SLIST_INSERT_HEAD(&wif->mac_maclist, wmm, wm); 3937 return (0); 3938 } 3939 3940 SLIST_FOREACH(temp, &wif->mac_maclist, wm) { 3941 if (memcmp(wmm->mac, temp->mac, IEEE80211_ADDR_LEN) < 0) 3942 break; 3943 prev = temp; 3944 } 3945 3946 SLIST_INSERT_AFTER(prev, wmm, wm); 3947 return (0); 3948 } 3949 3950 static int 3951 wlan_mac_delete_mac(struct wlan_iface *wif, struct wlan_mac_mac *wmm) 3952 { 3953 if (wmm->mac_status == RowStatus_active && 3954 wlan_del_mac_acl_mac(wif, wmm) < 0) 3955 return (-1); 3956 3957 SLIST_REMOVE(&wif->mac_maclist, wmm, wlan_mac_mac, wm); 3958 free(wmm); 3959 3960 return (0); 3961 } 3962 3963 static void 3964 wlan_mac_update_aclmacs(void) 3965 { 3966 struct wlan_iface *wif; 3967 struct wlan_mac_mac *wmm, *twmm; 3968 3969 if ((time(NULL) - wlan_maclist_age) <= WLAN_LIST_MAXAGE) 3970 return; 3971 3972 for (wif = wlan_first_interface(); wif != NULL; 3973 wif = wlan_next_interface(wif)) { 3974 if (wif->status != RowStatus_active) 3975 continue; 3976 /* 3977 * Nuke old entries - XXX - they are likely not to 3978 * change often - reconsider. 3979 */ 3980 SLIST_FOREACH_SAFE(wmm, &wif->mac_maclist, wm, twmm) 3981 if (wmm->mac_status == RowStatus_active) { 3982 SLIST_REMOVE(&wif->mac_maclist, wmm, 3983 wlan_mac_mac, wm); 3984 wlan_mac_free_mac(wmm); 3985 } 3986 (void)wlan_get_mac_acl_macs(wif); 3987 } 3988 wlan_maclist_age = time(NULL); 3989 } 3990 3991 static struct wlan_mac_mac * 3992 wlan_get_acl_mac(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 3993 { 3994 char wname[IFNAMSIZ]; 3995 char mac[IEEE80211_ADDR_LEN]; 3996 3997 if (wlan_mac_index_decode(oid, sub, wname, mac) < 0) 3998 return (NULL); 3999 4000 if ((*wif = wlan_find_interface(wname)) == NULL) 4001 return (NULL); 4002 4003 return (wlan_mac_find_mac(*wif, mac)); 4004 } 4005 4006 static struct wlan_mac_mac * 4007 wlan_get_next_acl_mac(const struct asn_oid *oid, uint sub, 4008 struct wlan_iface **wif) 4009 { 4010 char wname[IFNAMSIZ]; 4011 char mac[IEEE80211_ADDR_LEN]; 4012 struct wlan_mac_mac *wmm; 4013 4014 if (oid->len - sub == 0) { 4015 for (*wif = wlan_first_interface(); *wif != NULL; 4016 *wif = wlan_next_interface(*wif)) { 4017 wmm = SLIST_FIRST(&(*wif)->mac_maclist); 4018 if (wmm != NULL) 4019 return (wmm); 4020 } 4021 return (NULL); 4022 } 4023 4024 if (wlan_mac_index_decode(oid, sub, wname, mac) < 0 || 4025 (*wif = wlan_find_interface(wname)) == NULL || 4026 (wmm = wlan_mac_find_mac(*wif, mac)) == NULL) 4027 return (NULL); 4028 4029 if ((wmm = SLIST_NEXT(wmm, wm)) != NULL) 4030 return (wmm); 4031 4032 while ((*wif = wlan_next_interface(*wif)) != NULL) 4033 if ((wmm = SLIST_FIRST(&(*wif)->mac_maclist)) != NULL) 4034 break; 4035 4036 return (wmm); 4037 } 4038 4039 static int 4040 wlan_acl_mac_set_status(struct snmp_context *ctx, struct snmp_value *val, 4041 uint sub) 4042 { 4043 char wname[IFNAMSIZ]; 4044 uint8_t mac[IEEE80211_ADDR_LEN]; 4045 struct wlan_iface *wif; 4046 struct wlan_mac_mac *macl; 4047 4048 if (wlan_mac_index_decode(&val->var, sub, wname, mac) < 0) 4049 return (SNMP_ERR_GENERR); 4050 macl = wlan_get_acl_mac(&val->var, sub, &wif); 4051 4052 switch (val->v.integer) { 4053 case RowStatus_createAndGo: 4054 if (macl != NULL) 4055 return (SNMP_ERR_INCONS_NAME); 4056 break; 4057 case RowStatus_destroy: 4058 if (macl == NULL) 4059 return (SNMP_ERR_NOSUCHNAME); 4060 ctx->scratch->int1 = RowStatus_active; 4061 return (SNMP_ERR_NOERROR); 4062 default: 4063 return (SNMP_ERR_INCONS_VALUE); 4064 } 4065 4066 4067 if (wif == NULL || !wif->macsupported) 4068 return (SNMP_ERR_INCONS_VALUE); 4069 4070 if ((macl = wlan_mac_new_mac((const uint8_t *)mac)) == NULL) 4071 return (SNMP_ERR_GENERR); 4072 4073 ctx->scratch->int1 = RowStatus_destroy; 4074 4075 if (wlan_mac_add_mac(wif, macl) < 0) { 4076 wlan_mac_free_mac(macl); 4077 return (SNMP_ERR_GENERR); 4078 } 4079 4080 ctx->scratch->int1 = RowStatus_destroy; 4081 if (wlan_add_mac_acl_mac(wif, macl) < 0) { 4082 (void)wlan_mac_delete_mac(wif, macl); 4083 return (SNMP_ERR_GENERR); 4084 } 4085 4086 return (SNMP_ERR_NOERROR); 4087 } 4088 4089 /* 4090 * Wireless interfaces operating as mesh points. 4091 */ 4092 static struct wlan_iface * 4093 wlan_mesh_first_interface(void) 4094 { 4095 struct wlan_iface *wif; 4096 4097 SLIST_FOREACH(wif, &wlan_ifaces, w_if) 4098 if (wif->mode == WlanIfaceOperatingModeType_meshPoint && 4099 wif->status == RowStatus_active) 4100 break; 4101 4102 return (wif); 4103 } 4104 4105 static struct wlan_iface * 4106 wlan_mesh_next_interface(struct wlan_iface *wif) 4107 { 4108 struct wlan_iface *nwif; 4109 4110 while ((nwif = wlan_next_interface(wif)) != NULL) { 4111 if (nwif->mode == WlanIfaceOperatingModeType_meshPoint && 4112 nwif->status == RowStatus_active) 4113 break; 4114 wif = nwif; 4115 } 4116 4117 return (nwif); 4118 } 4119 4120 static struct wlan_iface * 4121 wlan_mesh_get_iface(const struct asn_oid *oid, uint sub) 4122 { 4123 struct wlan_iface *wif; 4124 4125 if ((wif = wlan_get_interface(oid, sub)) == NULL) 4126 return (NULL); 4127 4128 if (wif->mode != WlanIfaceOperatingModeType_meshPoint) 4129 return (NULL); 4130 4131 return (wif); 4132 } 4133 4134 static struct wlan_iface * 4135 wlan_mesh_get_next_iface(const struct asn_oid *oid, uint sub) 4136 { 4137 uint32_t i; 4138 uint8_t wname[IFNAMSIZ]; 4139 struct wlan_iface *wif; 4140 4141 if (oid->len - sub == 0) 4142 return (wlan_mesh_first_interface()); 4143 4144 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ) 4145 return (NULL); 4146 4147 memset(wname, 0, IFNAMSIZ); 4148 for (i = 0; i < oid->subs[sub]; i++) 4149 wname[i] = oid->subs[sub + i + 1]; 4150 wname[i] = '\0'; 4151 4152 if ((wif = wlan_find_interface(wname)) == NULL) 4153 return (NULL); 4154 4155 return (wlan_mesh_next_interface(wif)); 4156 } 4157 4158 /* 4159 * The neighbors of wireless interfaces operating as mesh points. 4160 */ 4161 static struct wlan_peer * 4162 wlan_mesh_get_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 4163 { 4164 char wname[IFNAMSIZ]; 4165 uint8_t pmac[IEEE80211_ADDR_LEN]; 4166 4167 if (wlan_mac_index_decode(oid, sub, wname, pmac) < 0) 4168 return (NULL); 4169 4170 if ((*wif = wlan_find_interface(wname)) == NULL || 4171 (*wif)->mode != WlanIfaceOperatingModeType_meshPoint) 4172 return (NULL); 4173 4174 return (wlan_find_peer(*wif, pmac)); 4175 } 4176 4177 static struct wlan_peer * 4178 wlan_mesh_get_next_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 4179 { 4180 char wname[IFNAMSIZ]; 4181 char pmac[IEEE80211_ADDR_LEN]; 4182 struct wlan_peer *wip; 4183 4184 if (oid->len - sub == 0) { 4185 for (*wif = wlan_mesh_first_interface(); *wif != NULL; 4186 *wif = wlan_mesh_next_interface(*wif)) { 4187 wip = SLIST_FIRST(&(*wif)->peerlist); 4188 if (wip != NULL) 4189 return (wip); 4190 } 4191 return (NULL); 4192 } 4193 4194 if (wlan_mac_index_decode(oid, sub, wname, pmac) < 0 || 4195 (*wif = wlan_find_interface(wname)) == NULL || 4196 (*wif)->mode != WlanIfaceOperatingModeType_meshPoint || 4197 (wip = wlan_find_peer(*wif, pmac)) == NULL) 4198 return (NULL); 4199 4200 if ((wip = SLIST_NEXT(wip, wp)) != NULL) 4201 return (wip); 4202 4203 while ((*wif = wlan_mesh_next_interface(*wif)) != NULL) 4204 if ((wip = SLIST_FIRST(&(*wif)->peerlist)) != NULL) 4205 break; 4206 4207 return (wip); 4208 } 4209 4210 /* 4211 * Mesh routing table. 4212 */ 4213 static void 4214 wlan_mesh_free_routes(struct wlan_iface *wif) 4215 { 4216 struct wlan_mesh_route *wmr; 4217 4218 while ((wmr = SLIST_FIRST(&wif->mesh_routelist)) != NULL) { 4219 SLIST_REMOVE_HEAD(&wif->mesh_routelist, wr); 4220 free(wmr); 4221 } 4222 4223 SLIST_INIT(&wif->mesh_routelist); 4224 } 4225 4226 static struct wlan_mesh_route * 4227 wlan_mesh_find_route(struct wlan_iface *wif, uint8_t *dstmac) 4228 { 4229 struct wlan_mesh_route *wmr; 4230 4231 if (wif->mode != WlanIfaceOperatingModeType_meshPoint) 4232 return (NULL); 4233 4234 SLIST_FOREACH(wmr, &wif->mesh_routelist, wr) 4235 if (memcmp(wmr->imroute.imr_dest, dstmac, 4236 IEEE80211_ADDR_LEN) == 0) 4237 break; 4238 4239 return (wmr); 4240 } 4241 4242 struct wlan_mesh_route * 4243 wlan_mesh_new_route(const uint8_t *dstmac) 4244 { 4245 struct wlan_mesh_route *wmr; 4246 4247 if ((wmr = (struct wlan_mesh_route *)malloc(sizeof(*wmr))) == NULL) 4248 return (NULL); 4249 4250 memset(wmr, 0, sizeof(*wmr)); 4251 memcpy(wmr->imroute.imr_dest, dstmac, IEEE80211_ADDR_LEN); 4252 wmr->mroute_status = RowStatus_notReady; 4253 4254 return (wmr); 4255 } 4256 4257 void 4258 wlan_mesh_free_route(struct wlan_mesh_route *wmr) 4259 { 4260 free(wmr); 4261 } 4262 4263 int 4264 wlan_mesh_add_rtentry(struct wlan_iface *wif, struct wlan_mesh_route *wmr) 4265 { 4266 struct wlan_mesh_route *temp, *prev; 4267 4268 SLIST_FOREACH(temp, &wif->mesh_routelist, wr) 4269 if (memcmp(temp->imroute.imr_dest, wmr->imroute.imr_dest, 4270 IEEE80211_ADDR_LEN) == 0) 4271 return (-1); 4272 4273 if ((prev = SLIST_FIRST(&wif->mesh_routelist)) == NULL || 4274 memcmp(wmr->imroute.imr_dest, prev->imroute.imr_dest, 4275 IEEE80211_ADDR_LEN) < 0) { 4276 SLIST_INSERT_HEAD(&wif->mesh_routelist, wmr, wr); 4277 return (0); 4278 } 4279 4280 SLIST_FOREACH(temp, &wif->mesh_routelist, wr) { 4281 if (memcmp(wmr->imroute.imr_dest, temp->imroute.imr_dest, 4282 IEEE80211_ADDR_LEN) < 0) 4283 break; 4284 prev = temp; 4285 } 4286 4287 SLIST_INSERT_AFTER(prev, wmr, wr); 4288 return (0); 4289 } 4290 4291 static int 4292 wlan_mesh_delete_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr) 4293 { 4294 if (wmr->mroute_status == RowStatus_active && 4295 wlan_mesh_del_route(wif, wmr) < 0) 4296 return (-1); 4297 4298 SLIST_REMOVE(&wif->mesh_routelist, wmr, wlan_mesh_route, wr); 4299 free(wmr); 4300 4301 return (0); 4302 } 4303 4304 static void 4305 wlan_mesh_update_routes(void) 4306 { 4307 struct wlan_iface *wif; 4308 struct wlan_mesh_route *wmr, *twmr; 4309 4310 if ((time(NULL) - wlan_mrlist_age) <= WLAN_LIST_MAXAGE) 4311 return; 4312 4313 for (wif = wlan_mesh_first_interface(); wif != NULL; 4314 wif = wlan_mesh_next_interface(wif)) { 4315 /* 4316 * Nuke old entries - XXX - they are likely not to 4317 * change often - reconsider. 4318 */ 4319 SLIST_FOREACH_SAFE(wmr, &wif->mesh_routelist, wr, twmr) 4320 if (wmr->mroute_status == RowStatus_active) { 4321 SLIST_REMOVE(&wif->mesh_routelist, wmr, 4322 wlan_mesh_route, wr); 4323 wlan_mesh_free_route(wmr); 4324 } 4325 (void)wlan_mesh_get_routelist(wif); 4326 } 4327 wlan_mrlist_age = time(NULL); 4328 } 4329 4330 static struct wlan_mesh_route * 4331 wlan_mesh_get_route(const struct asn_oid *oid, uint sub, struct wlan_iface **wif) 4332 { 4333 char wname[IFNAMSIZ]; 4334 char dstmac[IEEE80211_ADDR_LEN]; 4335 4336 if (wlan_mac_index_decode(oid, sub, wname, dstmac) < 0) 4337 return (NULL); 4338 4339 if ((*wif = wlan_find_interface(wname)) == NULL) 4340 return (NULL); 4341 4342 return (wlan_mesh_find_route(*wif, dstmac)); 4343 } 4344 4345 static struct wlan_mesh_route * 4346 wlan_mesh_get_next_route(const struct asn_oid *oid, uint sub, 4347 struct wlan_iface **wif) 4348 { 4349 char wname[IFNAMSIZ]; 4350 char dstmac[IEEE80211_ADDR_LEN]; 4351 struct wlan_mesh_route *wmr; 4352 4353 if (oid->len - sub == 0) { 4354 for (*wif = wlan_mesh_first_interface(); *wif != NULL; 4355 *wif = wlan_mesh_next_interface(*wif)) { 4356 wmr = SLIST_FIRST(&(*wif)->mesh_routelist); 4357 if (wmr != NULL) 4358 return (wmr); 4359 } 4360 return (NULL); 4361 } 4362 4363 if (wlan_mac_index_decode(oid, sub, wname, dstmac) < 0 || 4364 (*wif = wlan_find_interface(wname)) == NULL || 4365 (wmr = wlan_mesh_find_route(*wif, dstmac)) == NULL) 4366 return (NULL); 4367 4368 if ((wmr = SLIST_NEXT(wmr, wr)) != NULL) 4369 return (wmr); 4370 4371 while ((*wif = wlan_mesh_next_interface(*wif)) != NULL) 4372 if ((wmr = SLIST_FIRST(&(*wif)->mesh_routelist)) != NULL) 4373 break; 4374 4375 return (wmr); 4376 } 4377 4378 static int 4379 wlan_mesh_route_set_status(struct snmp_context *ctx, struct snmp_value *val, 4380 uint sub) 4381 { 4382 char wname[IFNAMSIZ]; 4383 char mac[IEEE80211_ADDR_LEN]; 4384 struct wlan_mesh_route *wmr; 4385 struct wlan_iface *wif; 4386 4387 if (wlan_mac_index_decode(&val->var, sub, wname, mac) < 0) 4388 return (SNMP_ERR_GENERR); 4389 wmr = wlan_mesh_get_route(&val->var, sub, &wif); 4390 4391 switch (val->v.integer) { 4392 case RowStatus_createAndGo: 4393 if (wmr != NULL) 4394 return (SNMP_ERR_INCONS_NAME); 4395 break; 4396 case RowStatus_destroy: 4397 if (wmr == NULL) 4398 return (SNMP_ERR_NOSUCHNAME); 4399 ctx->scratch->int1 = RowStatus_active; 4400 return (SNMP_ERR_NOERROR); 4401 default: 4402 return (SNMP_ERR_INCONS_VALUE); 4403 } 4404 4405 if ((wif = wlan_find_interface(wname)) == NULL) 4406 return (SNMP_ERR_INCONS_NAME); 4407 4408 if ((wmr = wlan_mesh_new_route(mac)) == NULL) 4409 return (SNMP_ERR_GENERR); 4410 4411 if (wlan_mesh_add_rtentry(wif, wmr) < 0) { 4412 wlan_mesh_free_route(wmr); 4413 return (SNMP_ERR_GENERR); 4414 } 4415 4416 ctx->scratch->int1 = RowStatus_destroy; 4417 if (wlan_mesh_add_route(wif, wmr) < 0) { 4418 (void)wlan_mesh_delete_route(wif, wmr); 4419 return (SNMP_ERR_GENERR); 4420 } 4421 4422 return (SNMP_ERR_NOERROR); 4423 } 4424 4425 /* 4426 * Wlan snmp module initialization hook. 4427 * Returns 0 on success, < 0 on error. 4428 */ 4429 static int 4430 wlan_init(struct lmodule * mod __unused, int argc __unused, 4431 char *argv[] __unused) 4432 { 4433 if (wlan_kmodules_load() < 0) 4434 return (-1); 4435 4436 if (wlan_ioctl_init() < 0) 4437 return (-1); 4438 4439 /* Register for new interface creation notifications. */ 4440 if (mib_register_newif(wlan_attach_newif, wlan_module)) { 4441 syslog(LOG_ERR, "Cannot register newif function: %s", 4442 strerror(errno)); 4443 return (-1); 4444 } 4445 4446 return (0); 4447 } 4448 4449 /* 4450 * Wlan snmp module finalization hook. 4451 */ 4452 static int 4453 wlan_fini(void) 4454 { 4455 mib_unregister_newif(wlan_module); 4456 or_unregister(reg_wlan); 4457 4458 /* XXX: Cleanup! */ 4459 wlan_free_iflist(); 4460 4461 return (0); 4462 } 4463 4464 /* 4465 * Refetch all available data from the kernel. 4466 */ 4467 static void 4468 wlan_update_data(void *arg __unused) 4469 { 4470 } 4471 4472 /* 4473 * Wlan snmp module start operation. 4474 */ 4475 static void 4476 wlan_start(void) 4477 { 4478 struct mibif *ifp; 4479 4480 reg_wlan = or_register(&oid_wlan, 4481 "The MIB module for managing wireless networking.", wlan_module); 4482 4483 /* Add the existing wlan interfaces. */ 4484 for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp)) 4485 wlan_attach_newif(ifp); 4486 4487 wlan_data_timer = timer_start_repeat(wlan_poll_ticks, 4488 wlan_poll_ticks, wlan_update_data, NULL, wlan_module); 4489 } 4490 4491 /* 4492 * Dump the Wlan snmp module data on SIGUSR1. 4493 */ 4494 static void 4495 wlan_dump(void) 4496 { 4497 /* XXX: Print some debug info to syslog. */ 4498 struct wlan_iface *wif; 4499 4500 for (wif = wlan_first_interface(); wif != NULL; 4501 wif = wlan_next_interface(wif)) 4502 syslog(LOG_ERR, "wlan iface %s", wif->wname); 4503 } 4504 4505 const char wlan_comment[] = \ 4506 "This module implements the BEGEMOT MIB for wireless networking."; 4507 4508 const struct snmp_module config = { 4509 .comment = wlan_comment, 4510 .init = wlan_init, 4511 .fini = wlan_fini, 4512 .start = wlan_start, 4513 .tree = wlan_ctree, 4514 .dump = wlan_dump, 4515 .tree_size = wlan_CTREE_SIZE, 4516 }; 4517