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