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