2 * Copyright (c) 2010 The FreeBSD Foundation
5 * This software was developed by Shteryana Sotirova Shopova under
6 * sponsorship from the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/queue.h>
33 #include <sys/socket.h>
34 #include <sys/types.h>
37 #include <net/if_media.h>
38 #include <net/if_mib.h>
39 #include <net/if_types.h>
40 #include <net80211/ieee80211.h>
41 #include <net80211/ieee80211_ioctl.h>
50 #include <bsnmp/snmpmod.h>
51 #include <bsnmp/snmp_mibII.h>
53 #include "wlan_tree.h"
54 #include "wlan_snmp.h"
57 static struct lmodule *wlan_module;
59 /* For the registration. */
60 static const struct asn_oid oid_wlan = OIDX_begemotWlan;
61 /* The registration. */
64 /* Periodic timer for polling the module's data. */
65 static void *wlan_data_timer;
68 * Poll data from kernel every 15 minutes unless explicitly requested by an
70 * XXX: make that configurable.
72 static int wlan_poll_ticks = (15 * 60) * 100;
74 /* The age of each table. */
75 #define WLAN_LIST_MAXAGE 5
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;
87 * The list of all virtual wireless interfaces - sorted by name.
89 SLIST_HEAD(wlan_ifaces, wlan_iface);
90 static struct wlan_ifaces wlan_ifaces = SLIST_HEAD_INITIALIZER(wlan_ifaces);
92 static struct wlan_config wlan_config;
94 /* Forward declarations */
95 static int bits_get(struct snmp_value *, const u_char *, ssize_t);
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 *);
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 *);
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);
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 *,
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 *,
129 static struct wlan_mesh_route * wlan_mesh_find_route(struct wlan_iface *,
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 *);
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 *,
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 **);
158 static struct wlan_iface * wlan_get_next_interface(const struct asn_oid *,
160 static struct wlan_iface * wlan_get_next_snmp_interface(const struct
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 *,
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 **);
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 *,
184 static int wlan_channel_index_decode(const struct asn_oid *, uint,
186 static int wlan_phy_index_decode(const struct asn_oid *, uint, char *,
188 static int wlan_scanr_index_decode(const struct asn_oid *oid, uint sub,
189 char *wname, uint8_t *ssid, uint8_t *bssid);
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 *);
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);
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 *);
213 * The module's GET/SET data hooks per each table or group of objects as
214 * required by bsnmpd(1).
217 op_wlan_iface(struct snmp_context *ctx, struct snmp_value *val, uint32_t sub,
218 uint32_t iidx __unused, enum snmp_op op)
221 char wname[IFNAMSIZ];
222 struct wlan_iface *wif;
224 wlan_update_interface_list();
228 if ((wif = wlan_get_snmp_interface(&val->var, sub)) == NULL)
229 return (SNMP_ERR_NOSUCHNAME);
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);
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);
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);
253 switch (val->var.subs[sub - 1]) {
254 case LEAF_wlanIfaceIndex:
255 return (SNMP_ERR_NOT_WRITEABLE);
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);
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);
279 case LEAF_wlanIfaceOperatingMode:
280 ctx->scratch->int1 = wif->mode;
281 wif->mode = val->v.integer;
282 return (SNMP_ERR_NOERROR);
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,
292 memcpy((uint8_t *)&wif->flags, val->v.octetstring.octets,
294 return (SNMP_ERR_NOERROR);
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,
304 memcpy(wif->dbssid, val->v.octetstring.octets,
306 return (SNMP_ERR_NOERROR);
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,
316 memcpy(wif->dlmac, val->v.octetstring.octets,
318 return (SNMP_ERR_NOERROR);
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;
329 } else if (wif->status == RowStatus_destroy)
330 return (wlan_iface_destroy(wif));
332 wif->status = RowStatus_notReady;
333 return (SNMP_ERR_NOERROR);
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);
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);
354 case LEAF_wlanParentIfName:
355 strlcpy(wif->pname, ctx->scratch->ptr1, IFNAMSIZ);
356 free(ctx->scratch->ptr1);
359 case LEAF_wlanIfaceOperatingMode:
360 wif->mode = ctx->scratch->int1;
363 case LEAF_wlanIfaceFlags:
364 memcpy((uint8_t *)&wif->flags, ctx->scratch->ptr1,
366 free(ctx->scratch->ptr1);
369 case LEAF_wlanIfaceBssid:
370 memcpy(wif->dbssid, ctx->scratch->ptr1,
372 free(ctx->scratch->ptr1);
375 case LEAF_wlanIfaceLocalAddress:
376 memcpy(wif->dlmac, ctx->scratch->ptr1,
378 free(ctx->scratch->ptr1);
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));
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);
396 return (SNMP_ERR_NOERROR);
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);
408 return (SNMP_ERR_NOERROR);
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);
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)
447 struct wlan_iface *wif;
449 wlan_update_interface_list();
453 if ((wif = wlan_get_interface(&val->var, sub)) == NULL)
454 return (SNMP_ERR_NOSUCHNAME);
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);
462 return (SNMP_ERR_NOT_WRITEABLE);
465 case SNMP_OP_ROLLBACK:
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)));
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)
490 int intval, vlen, rc;
492 struct wlan_iface *wif;
494 wlan_update_interface_list();
498 if ((wif = wlan_get_interface(&val->var, sub)) == NULL)
499 return (SNMP_ERR_NOSUCHNAME);
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);
509 if ((wif = wlan_get_interface(&val->var, sub)) == NULL)
510 return (SNMP_ERR_NOSUCHNAME);
512 intval = val->v.integer;
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);
522 case LEAF_wlanIfaceDesiredSsid:
523 if (val->v.octetstring.len > IEEE80211_NWID_LEN)
524 return (SNMP_ERR_INCONS_VALUE);
526 case LEAF_wlanIfaceDesiredBssid:
527 if (val->v.octetstring.len != IEEE80211_ADDR_LEN)
528 return (SNMP_ERR_INCONS_VALUE);
530 case LEAF_wlanIfacePacketBurst:
531 ctx->scratch->int1 = wif->packet_burst;
533 case LEAF_wlanIfaceRegDomain:
534 ctx->scratch->int1 = wif->reg_domain;
536 case LEAF_wlanIfaceDesiredChannel:
537 ctx->scratch->int1 = wif->desired_channel;
539 case LEAF_wlanIfaceDynamicFreqSelection:
540 ctx->scratch->int1 = wif->dyn_frequency;
542 case LEAF_wlanIfaceFastFrames:
543 ctx->scratch->int1 = wif->fast_frames;
545 case LEAF_wlanIfaceDturbo:
546 ctx->scratch->int1 = wif->dturbo;
548 case LEAF_wlanIfaceTxPower:
549 ctx->scratch->int1 = wif->tx_power;
551 case LEAF_wlanIfaceFragmentThreshold:
552 ctx->scratch->int1 = wif->frag_threshold;
554 case LEAF_wlanIfaceRTSThreshold:
555 ctx->scratch->int1 = wif->rts_threshold;
557 case LEAF_wlanIfaceWlanPrivacySubscribe:
558 ctx->scratch->int1 = wif->priv_subscribe;
560 case LEAF_wlanIfaceBgScan:
561 ctx->scratch->int1 = wif->bg_scan;
563 case LEAF_wlanIfaceBgScanIdle:
564 ctx->scratch->int1 = wif->bg_scan_idle;
566 case LEAF_wlanIfaceBgScanInterval:
567 ctx->scratch->int1 = wif->bg_scan_interval;
569 case LEAF_wlanIfaceBeaconMissedThreshold:
570 ctx->scratch->int1 = wif->beacons_missed;
572 case LEAF_wlanIfaceRoamingMode:
573 ctx->scratch->int1 = wif->roam_mode;
575 case LEAF_wlanIfaceDot11d:
576 ctx->scratch->int1 = wif->dot11d;
578 case LEAF_wlanIfaceDot11h:
579 ctx->scratch->int1 = wif->dot11h;
581 case LEAF_wlanIfaceDynamicWds:
582 ctx->scratch->int1 = wif->dynamic_wds;
584 case LEAF_wlanIfacePowerSave:
585 ctx->scratch->int1 = wif->power_save;
587 case LEAF_wlanIfaceApBridge:
588 ctx->scratch->int1 = wif->ap_bridge;
590 case LEAF_wlanIfaceBeaconInterval:
591 ctx->scratch->int1 = wif->beacon_interval;
593 case LEAF_wlanIfaceDtimPeriod:
594 ctx->scratch->int1 = wif->dtim_period;
596 case LEAF_wlanIfaceHideSsid:
597 ctx->scratch->int1 = wif->hide_ssid;
599 case LEAF_wlanIfaceInactivityProccess:
600 ctx->scratch->int1 = wif->inact_process;
602 case LEAF_wlanIfaceDot11gProtMode:
603 ctx->scratch->int1 = wif->do11g_protect;
605 case LEAF_wlanIfaceDot11gPureMode:
606 ctx->scratch->int1 = wif->dot11g_pure;
608 case LEAF_wlanIfaceDot11nPureMode:
609 ctx->scratch->int1 = wif->dot11n_pure;
611 case LEAF_wlanIfaceDot11nAmpdu:
612 ctx->scratch->int1 = wif->ampdu;
614 case LEAF_wlanIfaceDot11nAmpduDensity:
615 ctx->scratch->int1 = wif->ampdu_density;
617 case LEAF_wlanIfaceDot11nAmpduLimit:
618 ctx->scratch->int1 = wif->ampdu_limit;
620 case LEAF_wlanIfaceDot11nAmsdu:
621 ctx->scratch->int1 = wif->amsdu;
623 case LEAF_wlanIfaceDot11nAmsduLimit:
624 ctx->scratch->int1 = wif->amsdu_limit;
626 case LEAF_wlanIfaceDot11nHighThroughput:
627 ctx->scratch->int1 = wif->ht_enabled;
629 case LEAF_wlanIfaceDot11nHTCompatible:
630 ctx->scratch->int1 = wif->ht_compatible;
632 case LEAF_wlanIfaceDot11nHTProtMode:
633 ctx->scratch->int1 = wif->ht_prot_mode;
635 case LEAF_wlanIfaceDot11nRIFS:
636 ctx->scratch->int1 = wif->rifs;
638 case LEAF_wlanIfaceDot11nShortGI:
639 ctx->scratch->int1 = wif->short_gi;
641 case LEAF_wlanIfaceDot11nSMPSMode:
642 ctx->scratch->int1 = wif->smps_mode;
644 case LEAF_wlanIfaceTdmaSlot:
645 ctx->scratch->int1 = wif->tdma_slot;
647 case LEAF_wlanIfaceTdmaSlotCount:
648 ctx->scratch->int1 = wif->tdma_slot_count;
650 case LEAF_wlanIfaceTdmaSlotLength:
651 ctx->scratch->int1 = wif->tdma_slot_length;
653 case LEAF_wlanIfaceTdmaBeaconInterval:
654 ctx->scratch->int1 = wif->tdma_binterval;
660 if (val->syntax != SNMP_SYNTAX_OCTETSTRING)
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);
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;
677 case SNMP_OP_ROLLBACK:
678 intval = ctx->scratch->int1;
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;
697 switch (val->var.subs[sub - 1]) {
698 case LEAF_wlanIfaceCountryCode:
699 case LEAF_wlanIfaceDesiredSsid:
700 case LEAF_wlanIfaceDesiredBssid:
701 free(ctx->scratch->ptr1);
704 return (SNMP_ERR_NOERROR);
711 if (wlan_config_get_ioctl(wif, val->var.subs[sub - 1]) < 0)
712 return (SNMP_ERR_GENERR);
714 switch (val->var.subs[sub - 1]) {
715 case LEAF_wlanIfacePacketBurst:
716 val->v.integer = wif->packet_burst;
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;
724 case LEAF_wlanIfaceDesiredSsid:
725 return (string_get(val, wif->desired_ssid, -1));
726 case LEAF_wlanIfaceDesiredChannel:
727 val->v.integer = wif->desired_channel;
729 case LEAF_wlanIfaceDynamicFreqSelection:
730 val->v.integer = wif->dyn_frequency;
732 case LEAF_wlanIfaceFastFrames:
733 val->v.integer = wif->fast_frames;
735 case LEAF_wlanIfaceDturbo:
736 val->v.integer = wif->dturbo;
738 case LEAF_wlanIfaceTxPower:
739 val->v.integer = wif->tx_power;
741 case LEAF_wlanIfaceFragmentThreshold:
742 val->v.integer = wif->frag_threshold;
744 case LEAF_wlanIfaceRTSThreshold:
745 val->v.integer = wif->rts_threshold;
747 case LEAF_wlanIfaceWlanPrivacySubscribe:
748 val->v.integer = wif->priv_subscribe;
750 case LEAF_wlanIfaceBgScan:
751 val->v.integer = wif->bg_scan;
753 case LEAF_wlanIfaceBgScanIdle:
754 val->v.integer = wif->bg_scan_idle;
756 case LEAF_wlanIfaceBgScanInterval:
757 val->v.integer = wif->bg_scan_interval;
759 case LEAF_wlanIfaceBeaconMissedThreshold:
760 val->v.integer = wif->beacons_missed;
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;
768 case LEAF_wlanIfaceDot11d:
769 val->v.integer = wif->dot11d;
771 case LEAF_wlanIfaceDot11h:
772 val->v.integer = wif->dot11h;
774 case LEAF_wlanIfaceDynamicWds:
775 val->v.integer = wif->dynamic_wds;
777 case LEAF_wlanIfacePowerSave:
778 val->v.integer = wif->power_save;
780 case LEAF_wlanIfaceApBridge:
781 val->v.integer = wif->ap_bridge;
783 case LEAF_wlanIfaceBeaconInterval:
784 val->v.integer = wif->beacon_interval;
786 case LEAF_wlanIfaceDtimPeriod:
787 val->v.integer = wif->dtim_period;
789 case LEAF_wlanIfaceHideSsid:
790 val->v.integer = wif->hide_ssid;
792 case LEAF_wlanIfaceInactivityProccess:
793 val->v.integer = wif->inact_process;
795 case LEAF_wlanIfaceDot11gProtMode:
796 val->v.integer = wif->do11g_protect;
798 case LEAF_wlanIfaceDot11gPureMode:
799 val->v.integer = wif->dot11g_pure;
801 case LEAF_wlanIfaceDot11nPureMode:
802 val->v.integer = wif->dot11n_pure;
804 case LEAF_wlanIfaceDot11nAmpdu:
805 val->v.integer = wif->ampdu;
807 case LEAF_wlanIfaceDot11nAmpduDensity:
808 val->v.integer = wif->ampdu_density;
810 case LEAF_wlanIfaceDot11nAmpduLimit:
811 val->v.integer = wif->ampdu_limit;
813 case LEAF_wlanIfaceDot11nAmsdu:
814 val->v.integer = wif->amsdu;
816 case LEAF_wlanIfaceDot11nAmsduLimit:
817 val->v.integer = wif->amsdu_limit;
819 case LEAF_wlanIfaceDot11nHighThroughput:
820 val->v.integer = wif->ht_enabled;
822 case LEAF_wlanIfaceDot11nHTCompatible:
823 val->v.integer = wif->ht_compatible;
825 case LEAF_wlanIfaceDot11nHTProtMode:
826 val->v.integer = wif->ht_prot_mode;
828 case LEAF_wlanIfaceDot11nRIFS:
829 val->v.integer = wif->rifs;
831 case LEAF_wlanIfaceDot11nShortGI:
832 val->v.integer = wif->short_gi;
834 case LEAF_wlanIfaceDot11nSMPSMode:
835 val->v.integer = wif->smps_mode;
837 case LEAF_wlanIfaceTdmaSlot:
838 val->v.integer = wif->tdma_slot;
840 case LEAF_wlanIfaceTdmaSlotCount:
841 val->v.integer = wif->tdma_slot_count;
843 case LEAF_wlanIfaceTdmaSlotLength:
844 val->v.integer = wif->tdma_slot_length;
846 case LEAF_wlanIfaceTdmaBeaconInterval:
847 val->v.integer = wif->tdma_binterval;
851 return (SNMP_ERR_NOERROR);
854 rc = wlan_config_set_ioctl(wif, val->var.subs[sub - 1], intval,
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);
870 return (SNMP_ERR_GENERR);
872 return (SNMP_ERR_NOERROR);
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)
879 struct wlan_peer *wip;
880 struct wlan_iface *wif;
882 wlan_update_interface_list();
887 if ((wip = wlan_get_peer(&val->var, sub, &wif)) == NULL)
888 return (SNMP_ERR_NOSUCHNAME);
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);
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);
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);
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;
924 case LEAF_wlanIfacePeerVlanTag:
925 val->v.integer = wip->vlan;
927 case LEAF_wlanIfacePeerFrequency:
928 val->v.integer = wip->frequency;
930 case LEAF_wlanIfacePeerCurrentTXRate:
931 val->v.integer = wip->txrate;
933 case LEAF_wlanIfacePeerRxSignalStrength:
934 val->v.integer = wip->rssi;
936 case LEAF_wlanIfacePeerIdleTimer:
937 val->v.integer = wip->idle;
939 case LEAF_wlanIfacePeerTxSequenceNo:
940 val->v.integer = wip->txseqs;
942 case LEAF_wlanIfacePeerRxSequenceNo:
943 val->v.integer = wip->rxseqs;
945 case LEAF_wlanIfacePeerTxPower:
946 val->v.integer = wip->txpower;
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)));
958 return (SNMP_ERR_NOERROR);
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)
966 struct ieee80211_channel *channel;
967 struct wlan_iface *wif;
969 wlan_update_interface_list();
970 wlan_update_channels();
974 if ((channel = wlan_get_channel(&val->var, sub, &wif)) == NULL)
975 return (SNMP_ERR_NOSUCHNAME);
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);
984 return (SNMP_ERR_NOT_WRITEABLE);
987 case SNMP_OP_ROLLBACK:
993 switch (val->var.subs[sub - 1]) {
994 case LEAF_wlanIfaceChannelIeeeId:
995 val->v.integer = channel->ic_ieee;
997 case LEAF_wlanIfaceChannelType:
998 val->v.integer = wlan_get_channel_type(channel);
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;
1006 case LEAF_wlanIfaceChannelMaxRegPower:
1007 val->v.integer = channel->ic_maxregpower;
1009 case LEAF_wlanIfaceChannelMaxTxPower:
1010 val->v.integer = channel->ic_maxpower;
1012 case LEAF_wlanIfaceChannelMinTxPower:
1013 val->v.integer = channel->ic_minpower;
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;
1021 case LEAF_wlanIfaceChannelMaxAntennaGain:
1022 val->v.integer = channel->ic_maxantgain;
1026 return (SNMP_ERR_NOERROR);
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)
1034 struct ieee80211_roamparam *rparam;
1035 struct wlan_iface *wif;
1037 wlan_update_interface_list();
1038 wlan_update_roam_params();
1042 rparam = wlan_get_roam_param(&val->var, sub, &wif);
1044 return (SNMP_ERR_NOSUCHNAME);
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);
1053 return (SNMP_ERR_NOT_WRITEABLE);
1054 case SNMP_OP_COMMIT:
1056 case SNMP_OP_ROLLBACK:
1062 switch (val->var.subs[sub - 1]) {
1063 case LEAF_wlanIfRoamRxSignalStrength:
1064 val->v.integer = rparam->rssi/2;
1066 case LEAF_wlanIfRoamTxRateThreshold:
1067 val->v.integer = rparam->rate/2;
1073 return (SNMP_ERR_NOERROR);
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)
1081 struct ieee80211_txparam *txparam;
1082 struct wlan_iface *wif;
1084 wlan_update_interface_list();
1085 wlan_update_tx_params();
1089 txparam = wlan_get_tx_param(&val->var, sub, &wif, &phy);
1090 if (txparam == NULL)
1091 return (SNMP_ERR_NOSUCHNAME);
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);
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;
1110 case LEAF_wlanIfTxMcastRate:
1111 ctx->scratch->int1 = txparam->mcastrate;
1112 txparam->mcastrate = val->v.integer * 2;
1114 case LEAF_wlanIfTxMgmtRate:
1115 ctx->scratch->int1 = txparam->mgmtrate;
1116 txparam->mgmtrate = val->v.integer * 2;
1118 case LEAF_wlanIfTxMaxRetryCount:
1119 ctx->scratch->int1 = txparam->maxretry;
1120 txparam->maxretry = val->v.integer;
1125 if (wlan_set_tx_params(wif, phy) < 0)
1126 return (SNMP_ERR_GENERR);
1127 return (SNMP_ERR_NOERROR);
1129 case SNMP_OP_COMMIT:
1130 return (SNMP_ERR_NOERROR);
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;
1140 case LEAF_wlanIfTxMcastRate:
1141 txparam->mcastrate = ctx->scratch->int1;
1143 case LEAF_wlanIfTxMgmtRate:
1144 txparam->mgmtrate = ctx->scratch->int1;
1146 case LEAF_wlanIfTxMaxRetryCount:
1147 txparam->maxretry = ctx->scratch->int1;
1152 if (wlan_set_tx_params(wif, phy) < 0)
1153 return (SNMP_ERR_GENERR);
1154 return (SNMP_ERR_NOERROR);
1160 switch (val->var.subs[sub - 1]) {
1161 case LEAF_wlanIfTxUnicastRate:
1162 val->v.integer = txparam->ucastrate / 2;
1164 case LEAF_wlanIfTxMcastRate:
1165 val->v.integer = txparam->mcastrate / 2;
1167 case LEAF_wlanIfTxMgmtRate:
1168 val->v.integer = txparam->mgmtrate / 2;
1170 case LEAF_wlanIfTxMaxRetryCount:
1171 val->v.integer = txparam->maxretry;
1177 return (SNMP_ERR_NOERROR);
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)
1184 struct wlan_iface *wif;
1186 wlan_update_interface_list();
1190 if ((wif = wlan_get_interface(&val->var, sub)) == NULL)
1191 return (SNMP_ERR_NOSUCHNAME);
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);
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;
1211 case LEAF_wlanScanDuration:
1212 ctx->scratch->int1 = wif->scan_duration;
1213 wif->scan_duration = val->v.integer;
1215 case LEAF_wlanScanMinChannelDwellTime:
1216 ctx->scratch->int1 = wif->scan_mindwell;
1217 wif->scan_mindwell = val->v.integer;
1219 case LEAF_wlanScanMaxChannelDwellTime:
1220 ctx->scratch->int1 = wif->scan_maxdwell;
1221 wif->scan_maxdwell = val->v.integer;
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;
1230 return (SNMP_ERR_INCONS_VALUE);
1232 return (SNMP_ERR_NOERROR);
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);
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;
1249 case LEAF_wlanScanDuration:
1250 wif->scan_duration = ctx->scratch->int1;
1252 case LEAF_wlanScanMinChannelDwellTime:
1253 wif->scan_mindwell = ctx->scratch->int1;
1255 case LEAF_wlanScanMaxChannelDwellTime:
1256 wif->scan_maxdwell = ctx->scratch->int1;
1258 case LEAF_wlanScanConfigStatus:
1259 wif->scan_status = ctx->scratch->int1;
1262 return (SNMP_ERR_NOERROR);
1267 switch (val->var.subs[sub - 1]) {
1268 case LEAF_wlanScanFlags:
1269 val->v.integer = wif->scan_flags;
1271 case LEAF_wlanScanDuration:
1272 val->v.integer = wif->scan_duration;
1274 case LEAF_wlanScanMinChannelDwellTime:
1275 val->v.integer = wif->scan_mindwell;
1277 case LEAF_wlanScanMaxChannelDwellTime:
1278 val->v.integer = wif->scan_maxdwell;
1280 case LEAF_wlanScanConfigStatus:
1281 val->v.integer = wif->scan_status;
1285 return (SNMP_ERR_NOERROR);
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)
1292 struct wlan_scan_result *sr;
1293 struct wlan_iface *wif;
1295 wlan_update_interface_list();
1296 wlan_scan_update_results();
1300 if ((sr = wlan_get_scanr(&val->var, sub, &wif)) == NULL)
1301 return (SNMP_ERR_NOSUCHNAME);
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,
1312 return (SNMP_ERR_NOT_WRITEABLE);
1313 case SNMP_OP_COMMIT:
1315 case SNMP_OP_ROLLBACK:
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 */
1329 case LEAF_wlanScanResultRate:
1330 val->v.integer = sr->rssi;
1332 case LEAF_wlanScanResultNoise:
1333 val->v.integer = sr->noise;
1335 case LEAF_wlanScanResultBeaconInterval:
1336 val->v.integer = sr->bintval;
1338 case LEAF_wlanScanResultCapabilities:
1339 return (bits_get(val, &sr->capinfo, sizeof(sr->capinfo)));
1344 return (SNMP_ERR_NOERROR);
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)
1351 struct wlan_iface *wif;
1353 wlan_update_interface_list();
1357 if ((wif = wlan_get_interface(&val->var, sub)) == NULL)
1358 return (SNMP_ERR_NOSUCHNAME);
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);
1366 /* XXX: LEAF_wlanStatsReset */
1367 return (SNMP_ERR_NOT_WRITEABLE);
1368 case SNMP_OP_COMMIT:
1370 case SNMP_OP_ROLLBACK:
1376 if (wlan_get_stats(wif) < 0)
1377 return (SNMP_ERR_GENERR);
1379 switch (val->var.subs[sub - 1]) {
1380 case LEAF_wlanStatsRxBadVersion:
1381 val->v.uint32 = wif->stats.is_rx_badversion;
1383 case LEAF_wlanStatsRxTooShort:
1384 val->v.uint32 = wif->stats.is_rx_tooshort;
1386 case LEAF_wlanStatsRxWrongBssid:
1387 val->v.uint32 = wif->stats.is_rx_wrongbss;
1389 case LEAF_wlanStatsRxDiscardedDups:
1390 val->v.uint32 = wif->stats.is_rx_dup;
1392 case LEAF_wlanStatsRxWrongDir:
1393 val->v.uint32 = wif->stats.is_rx_wrongdir;
1395 case LEAF_wlanStatsRxDiscardMcastEcho:
1396 val->v.uint32 = wif->stats.is_rx_mcastecho;
1398 case LEAF_wlanStatsRxDiscardNoAssoc:
1399 val->v.uint32 = wif->stats.is_rx_notassoc;
1401 case LEAF_wlanStatsRxWepNoPrivacy:
1402 val->v.uint32 = wif->stats.is_rx_noprivacy;
1404 case LEAF_wlanStatsRxWepUnencrypted:
1405 val->v.uint32 = wif->stats.is_rx_unencrypted;
1407 case LEAF_wlanStatsRxWepFailed:
1408 val->v.uint32 = wif->stats.is_rx_wepfail;
1410 case LEAF_wlanStatsRxDecapsulationFailed:
1411 val->v.uint32 = wif->stats.is_rx_decap;
1413 case LEAF_wlanStatsRxDiscardMgmt:
1414 val->v.uint32 = wif->stats.is_rx_mgtdiscard;
1416 case LEAF_wlanStatsRxControl:
1417 val->v.uint32 = wif->stats.is_rx_ctl;
1419 case LEAF_wlanStatsRxBeacon:
1420 val->v.uint32 = wif->stats.is_rx_beacon;
1422 case LEAF_wlanStatsRxRateSetTooBig:
1423 val->v.uint32 = wif->stats.is_rx_rstoobig;
1425 case LEAF_wlanStatsRxElemMissing:
1426 val->v.uint32 = wif->stats.is_rx_elem_missing;
1428 case LEAF_wlanStatsRxElemTooBig:
1429 val->v.uint32 = wif->stats.is_rx_elem_toobig;
1431 case LEAF_wlanStatsRxElemTooSmall:
1432 val->v.uint32 = wif->stats.is_rx_elem_toosmall;
1434 case LEAF_wlanStatsRxElemUnknown:
1435 val->v.uint32 = wif->stats.is_rx_elem_unknown;
1437 case LEAF_wlanStatsRxChannelMismatch:
1438 val->v.uint32 = wif->stats.is_rx_chanmismatch;
1440 case LEAF_wlanStatsRxDropped:
1441 val->v.uint32 = wif->stats.is_rx_nodealloc;
1443 case LEAF_wlanStatsRxSsidMismatch:
1444 val->v.uint32 = wif->stats.is_rx_ssidmismatch;
1446 case LEAF_wlanStatsRxAuthNotSupported:
1447 val->v.uint32 = wif->stats.is_rx_auth_unsupported;
1449 case LEAF_wlanStatsRxAuthFailed:
1450 val->v.uint32 = wif->stats.is_rx_auth_fail;
1452 case LEAF_wlanStatsRxAuthCM:
1453 val->v.uint32 = wif->stats.is_rx_auth_countermeasures;
1455 case LEAF_wlanStatsRxAssocWrongBssid:
1456 val->v.uint32 = wif->stats.is_rx_assoc_bss;
1458 case LEAF_wlanStatsRxAssocNoAuth:
1459 val->v.uint32 = wif->stats.is_rx_assoc_notauth;
1461 case LEAF_wlanStatsRxAssocCapMismatch:
1462 val->v.uint32 = wif->stats.is_rx_assoc_capmismatch;
1464 case LEAF_wlanStatsRxAssocNoRateMatch:
1465 val->v.uint32 = wif->stats.is_rx_assoc_norate;
1467 case LEAF_wlanStatsRxBadWpaIE:
1468 val->v.uint32 = wif->stats.is_rx_assoc_badwpaie;
1470 case LEAF_wlanStatsRxDeauthenticate:
1471 val->v.uint32 = wif->stats.is_rx_deauth;
1473 case LEAF_wlanStatsRxDisassociate:
1474 val->v.uint32 = wif->stats.is_rx_disassoc;
1476 case LEAF_wlanStatsRxUnknownSubtype:
1477 val->v.uint32 = wif->stats.is_rx_badsubtype;
1479 case LEAF_wlanStatsRxFailedNoBuf:
1480 val->v.uint32 = wif->stats.is_rx_nobuf;
1482 case LEAF_wlanStatsRxBadAuthRequest:
1483 val->v.uint32 = wif->stats.is_rx_bad_auth;
1485 case LEAF_wlanStatsRxUnAuthorized:
1486 val->v.uint32 = wif->stats.is_rx_unauth;
1488 case LEAF_wlanStatsRxBadKeyId:
1489 val->v.uint32 = wif->stats.is_rx_badkeyid;
1491 case LEAF_wlanStatsRxCCMPSeqViolation:
1492 val->v.uint32 = wif->stats.is_rx_ccmpreplay;
1494 case LEAF_wlanStatsRxCCMPBadFormat:
1495 val->v.uint32 = wif->stats.is_rx_ccmpformat;
1497 case LEAF_wlanStatsRxCCMPFailedMIC:
1498 val->v.uint32 = wif->stats.is_rx_ccmpmic;
1500 case LEAF_wlanStatsRxTKIPSeqViolation:
1501 val->v.uint32 = wif->stats.is_rx_tkipreplay;
1503 case LEAF_wlanStatsRxTKIPBadFormat:
1504 val->v.uint32 = wif->stats.is_rx_tkipformat;
1506 case LEAF_wlanStatsRxTKIPFailedMIC:
1507 val->v.uint32 = wif->stats.is_rx_tkipmic;
1509 case LEAF_wlanStatsRxTKIPFailedICV:
1510 val->v.uint32 = wif->stats.is_rx_tkipicv;
1512 case LEAF_wlanStatsRxDiscardACL:
1513 val->v.uint32 = wif->stats.is_rx_acl;
1515 case LEAF_wlanStatsTxFailedNoBuf:
1516 val->v.uint32 = wif->stats.is_tx_nobuf;
1518 case LEAF_wlanStatsTxFailedNoNode:
1519 val->v.uint32 = wif->stats.is_tx_nonode;
1521 case LEAF_wlanStatsTxUnknownMgmt:
1522 val->v.uint32 = wif->stats.is_tx_unknownmgt;
1524 case LEAF_wlanStatsTxBadCipher:
1525 val->v.uint32 = wif->stats.is_tx_badcipher;
1527 case LEAF_wlanStatsTxNoDefKey:
1528 val->v.uint32 = wif->stats.is_tx_nodefkey;
1530 case LEAF_wlanStatsTxFragmented:
1531 val->v.uint32 = wif->stats.is_tx_fragframes;
1533 case LEAF_wlanStatsTxFragmentsCreated:
1534 val->v.uint32 = wif->stats.is_tx_frags;
1536 case LEAF_wlanStatsActiveScans:
1537 val->v.uint32 = wif->stats.is_scan_active;
1539 case LEAF_wlanStatsPassiveScans:
1540 val->v.uint32 = wif->stats.is_scan_passive;
1542 case LEAF_wlanStatsTimeoutInactivity:
1543 val->v.uint32 = wif->stats.is_node_timeout;
1545 case LEAF_wlanStatsCryptoNoMem:
1546 val->v.uint32 = wif->stats.is_crypto_nomem;
1548 case LEAF_wlanStatsSwCryptoTKIP:
1549 val->v.uint32 = wif->stats.is_crypto_tkip;
1551 case LEAF_wlanStatsSwCryptoTKIPEnMIC:
1552 val->v.uint32 = wif->stats.is_crypto_tkipenmic;
1554 case LEAF_wlanStatsSwCryptoTKIPDeMIC:
1555 val->v.uint32 = wif->stats.is_crypto_tkipdemic;
1557 case LEAF_wlanStatsCryptoTKIPCM:
1558 val->v.uint32 = wif->stats.is_crypto_tkipcm;
1560 case LEAF_wlanStatsSwCryptoCCMP:
1561 val->v.uint32 = wif->stats.is_crypto_ccmp;
1563 case LEAF_wlanStatsSwCryptoWEP:
1564 val->v.uint32 = wif->stats.is_crypto_wep;
1566 case LEAF_wlanStatsCryptoCipherKeyRejected:
1567 val->v.uint32 = wif->stats.is_crypto_setkey_cipher;
1569 case LEAF_wlanStatsCryptoNoKey:
1570 val->v.uint32 = wif->stats.is_crypto_setkey_nokey;
1572 case LEAF_wlanStatsCryptoDeleteKeyFailed:
1573 val->v.uint32 = wif->stats.is_crypto_delkey;
1575 case LEAF_wlanStatsCryptoUnknownCipher:
1576 val->v.uint32 = wif->stats.is_crypto_badcipher;
1578 case LEAF_wlanStatsCryptoAttachFailed:
1579 val->v.uint32 = wif->stats.is_crypto_attachfail;
1581 case LEAF_wlanStatsCryptoKeyFailed:
1582 val->v.uint32 = wif->stats.is_crypto_keyfail;
1584 case LEAF_wlanStatsCryptoEnMICFailed:
1585 val->v.uint32 = wif->stats.is_crypto_enmicfail;
1587 case LEAF_wlanStatsIBSSCapMismatch:
1588 val->v.uint32 = wif->stats.is_ibss_capmismatch;
1590 case LEAF_wlanStatsUnassocStaPSPoll:
1591 val->v.uint32 = wif->stats.is_ps_unassoc;
1593 case LEAF_wlanStatsBadAidPSPoll:
1594 val->v.uint32 = wif->stats.is_ps_badaid;
1596 case LEAF_wlanStatsEmptyPSPoll:
1597 val->v.uint32 = wif->stats.is_ps_qempty;
1599 case LEAF_wlanStatsRxFFBadHdr:
1600 val->v.uint32 = wif->stats.is_ff_badhdr;
1602 case LEAF_wlanStatsRxFFTooShort:
1603 val->v.uint32 = wif->stats.is_ff_tooshort;
1605 case LEAF_wlanStatsRxFFSplitError:
1606 val->v.uint32 = wif->stats.is_ff_split;
1608 case LEAF_wlanStatsRxFFDecap:
1609 val->v.uint32 = wif->stats.is_ff_decap;
1611 case LEAF_wlanStatsTxFFEncap:
1612 val->v.uint32 = wif->stats.is_ff_encap;
1614 case LEAF_wlanStatsRxBadBintval:
1615 val->v.uint32 = wif->stats.is_rx_badbintval;
1617 case LEAF_wlanStatsRxDemicFailed:
1618 val->v.uint32 = wif->stats.is_rx_demicfail;
1620 case LEAF_wlanStatsRxDefragFailed:
1621 val->v.uint32 = wif->stats.is_rx_defrag;
1623 case LEAF_wlanStatsRxMgmt:
1624 val->v.uint32 = wif->stats.is_rx_mgmt;
1626 case LEAF_wlanStatsRxActionMgmt:
1627 val->v.uint32 = wif->stats.is_rx_action;
1629 case LEAF_wlanStatsRxAMSDUTooShort:
1630 val->v.uint32 = wif->stats.is_amsdu_tooshort;
1632 case LEAF_wlanStatsRxAMSDUSplitError:
1633 val->v.uint32 = wif->stats.is_amsdu_split;
1635 case LEAF_wlanStatsRxAMSDUDecap:
1636 val->v.uint32 = wif->stats.is_amsdu_decap;
1638 case LEAF_wlanStatsTxAMSDUEncap:
1639 val->v.uint32 = wif->stats.is_amsdu_encap;
1641 case LEAF_wlanStatsAMPDUBadBAR:
1642 val->v.uint32 = wif->stats.is_ampdu_bar_bad;
1644 case LEAF_wlanStatsAMPDUOowBar:
1645 val->v.uint32 = wif->stats.is_ampdu_bar_oow;
1647 case LEAF_wlanStatsAMPDUMovedBAR:
1648 val->v.uint32 = wif->stats.is_ampdu_bar_move;
1650 case LEAF_wlanStatsAMPDURxBAR:
1651 val->v.uint32 = wif->stats.is_ampdu_bar_rx;
1653 case LEAF_wlanStatsAMPDURxOor:
1654 val->v.uint32 = wif->stats.is_ampdu_rx_oor;
1656 case LEAF_wlanStatsAMPDURxCopied:
1657 val->v.uint32 = wif->stats.is_ampdu_rx_copy;
1659 case LEAF_wlanStatsAMPDURxDropped:
1660 val->v.uint32 = wif->stats.is_ampdu_rx_drop;
1662 case LEAF_wlanStatsTxDiscardBadState:
1663 val->v.uint32 = wif->stats.is_tx_badstate;
1665 case LEAF_wlanStatsTxFailedNoAssoc:
1666 val->v.uint32 = wif->stats.is_tx_notassoc;
1668 case LEAF_wlanStatsTxClassifyFailed:
1669 val->v.uint32 = wif->stats.is_tx_classify;
1671 case LEAF_wlanStatsDwdsMcastDiscard:
1672 val->v.uint32 = wif->stats.is_dwds_mcast;
1674 case LEAF_wlanStatsHTAssocRejectNoHT:
1675 val->v.uint32 = wif->stats.is_ht_assoc_nohtcap;
1677 case LEAF_wlanStatsHTAssocDowngrade:
1678 val->v.uint32 = wif->stats.is_ht_assoc_downgrade;
1680 case LEAF_wlanStatsHTAssocRateMismatch:
1681 val->v.uint32 = wif->stats.is_ht_assoc_norate;
1683 case LEAF_wlanStatsAMPDURxAge:
1684 val->v.uint32 = wif->stats.is_ampdu_rx_age;
1686 case LEAF_wlanStatsAMPDUMoved:
1687 val->v.uint32 = wif->stats.is_ampdu_rx_move;
1689 case LEAF_wlanStatsADDBADisabledReject:
1690 val->v.uint32 = wif->stats.is_addba_reject;
1692 case LEAF_wlanStatsADDBANoRequest:
1693 val->v.uint32 = wif->stats.is_addba_norequest;
1695 case LEAF_wlanStatsADDBABadToken:
1696 val->v.uint32 = wif->stats.is_addba_badtoken;
1698 case LEAF_wlanStatsADDBABadPolicy:
1699 val->v.uint32 = wif->stats.is_addba_badpolicy;
1701 case LEAF_wlanStatsAMPDUStopped:
1702 val->v.uint32 = wif->stats.is_ampdu_stop;
1704 case LEAF_wlanStatsAMPDUStopFailed:
1705 val->v.uint32 = wif->stats.is_ampdu_stop_failed;
1707 case LEAF_wlanStatsAMPDURxReorder:
1708 val->v.uint32 = wif->stats.is_ampdu_rx_reorder;
1710 case LEAF_wlanStatsScansBackground:
1711 val->v.uint32 = wif->stats.is_scan_bg;
1713 case LEAF_wlanLastDeauthReason:
1714 val->v.uint32 = wif->stats.is_rx_deauth_code;
1716 case LEAF_wlanLastDissasocReason:
1717 val->v.uint32 = wif->stats.is_rx_disassoc_code;
1719 case LEAF_wlanLastAuthFailReason:
1720 val->v.uint32 = wif->stats.is_rx_authfail_code;
1722 case LEAF_wlanStatsBeaconMissedEvents:
1723 val->v.uint32 = wif->stats.is_beacon_miss;
1725 case LEAF_wlanStatsRxDiscardBadStates:
1726 val->v.uint32 = wif->stats.is_rx_badstate;
1728 case LEAF_wlanStatsFFFlushed:
1729 val->v.uint32 = wif->stats.is_ff_flush;
1731 case LEAF_wlanStatsTxControlFrames:
1732 val->v.uint32 = wif->stats.is_tx_ctl;
1734 case LEAF_wlanStatsAMPDURexmt:
1735 val->v.uint32 = wif->stats.is_ampdu_rexmt;
1737 case LEAF_wlanStatsAMPDURexmtFailed:
1738 val->v.uint32 = wif->stats.is_ampdu_rexmt_fail;
1740 case LEAF_wlanStatsReset:
1741 val->v.uint32 = wlanStatsReset_no_op;
1747 return (SNMP_ERR_NOERROR);
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)
1754 struct wlan_iface *wif;
1756 wlan_update_interface_list();
1760 if ((wif = wlan_get_interface(&val->var, sub)) == NULL ||
1762 return (SNMP_ERR_NOSUCHNAME);
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);
1773 if ((wif = wlan_get_interface(&val->var, sub)) == NULL ||
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);
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);
1802 return (SNMP_ERR_NOERROR);
1804 case SNMP_OP_COMMIT:
1805 return (SNMP_ERR_NOERROR);
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);
1816 case LEAF_wlanWepDefTxKey:
1817 wif->weptxkey = ctx->scratch->int1;
1818 if (wlan_set_weptxkey(wif) < 0)
1819 return (SNMP_ERR_GENERR);
1824 return (SNMP_ERR_NOERROR);
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;
1836 case LEAF_wlanWepDefTxKey:
1837 if (wlan_get_weptxkey(wif) < 0)
1838 return (SNMP_ERR_GENERR);
1839 val->v.integer = wif->weptxkey;
1845 return (SNMP_ERR_NOERROR);
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)
1853 return (SNMP_ERR_NOSUCHNAME);
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)
1860 struct wlan_iface *wif;
1862 wlan_update_interface_list();
1866 if ((wif = wlan_get_interface(&val->var, sub)) == NULL ||
1868 return (SNMP_ERR_NOSUCHNAME);
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);
1879 if ((wif = wlan_get_interface(&val->var, sub)) == NULL ||
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;
1887 case LEAF_wlanMACAccessControlNacl:
1888 return (SNMP_ERR_NOT_WRITEABLE);
1889 case LEAF_wlanMACAccessControlFlush:
1894 return (SNMP_ERR_NOERROR);
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);
1906 case LEAF_wlanMACAccessControlFlush:
1907 if (wlan_flush_mac_mac(wif) < 0)
1908 return (SNMP_ERR_GENERR);
1913 return (SNMP_ERR_NOERROR);
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);
1926 if (wlan_get_mac_policy(wif) < 0)
1927 return (SNMP_ERR_GENERR);
1929 switch (val->var.subs[sub - 1]) {
1930 case LEAF_wlanMACAccessControlPolicy:
1931 val->v.integer = wif->mac_policy;
1933 case LEAF_wlanMACAccessControlNacl:
1934 val->v.integer = wif->mac_nacls;
1936 case LEAF_wlanMACAccessControlFlush:
1937 val->v.integer = wlanMACAccessControlFlush_no_op;
1943 return (SNMP_ERR_NOERROR);
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)
1950 struct wlan_iface *wif;
1951 struct wlan_mac_mac *macl;
1953 wlan_update_interface_list();
1954 wlan_mac_update_aclmacs();
1958 if ((macl = wlan_get_acl_mac(&val->var, sub, &wif)) == NULL)
1959 return (SNMP_ERR_NOSUCHNAME);
1962 case SNMP_OP_GETNEXT:
1963 if ((macl = wlan_get_next_acl_mac(&val->var, sub, &wif))
1965 return (SNMP_ERR_NOSUCHNAME);
1966 wlan_append_mac_index(&val->var, sub, wif->wname, macl->mac);
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));
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);
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);
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;
2009 return (SNMP_ERR_NOERROR);
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)
2018 switch (val->var.subs[sub - 1]) {
2019 case LEAF_wlanMeshMaxRetries:
2020 which = WLAN_MESH_MAX_RETRIES;
2022 case LEAF_wlanMeshHoldingTimeout:
2023 which = WLAN_MESH_HOLDING_TO;
2025 case LEAF_wlanMeshConfirmTimeout:
2026 which = WLAN_MESH_CONFIRM_TO;
2028 case LEAF_wlanMeshRetryTimeout:
2029 which = WLAN_MESH_RETRY_TO;
2037 if (wlan_do_sysctl(&wlan_config, which, 0) < 0)
2038 return (SNMP_ERR_GENERR);
2041 case SNMP_OP_GETNEXT:
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;
2050 case LEAF_wlanMeshHoldingTimeout:
2051 ctx->scratch->int1 = wlan_config.mesh_holdingto;
2052 wlan_config.mesh_holdingto = val->v.integer;
2054 case LEAF_wlanMeshConfirmTimeout:
2055 ctx->scratch->int1 = wlan_config.mesh_confirmto;
2056 wlan_config.mesh_confirmto = val->v.integer;
2058 case LEAF_wlanMeshMaxRetries:
2059 ctx->scratch->int1 = wlan_config.mesh_maxretries;
2060 wlan_config.mesh_maxretries = val->v.integer;
2063 if (wlan_do_sysctl(&wlan_config, which, 1) < 0)
2064 return (SNMP_ERR_GENERR);
2065 return (SNMP_ERR_NOERROR);
2067 case SNMP_OP_COMMIT:
2068 return (SNMP_ERR_NOERROR);
2070 case SNMP_OP_ROLLBACK:
2071 switch (val->var.subs[sub - 1]) {
2072 case LEAF_wlanMeshRetryTimeout:
2073 wlan_config.mesh_retryto = ctx->scratch->int1;
2075 case LEAF_wlanMeshConfirmTimeout:
2076 wlan_config.mesh_confirmto = ctx->scratch->int1;
2078 case LEAF_wlanMeshHoldingTimeout:
2079 wlan_config.mesh_holdingto= ctx->scratch->int1;
2081 case LEAF_wlanMeshMaxRetries:
2082 wlan_config.mesh_maxretries = ctx->scratch->int1;
2085 if (wlan_do_sysctl(&wlan_config, which, 1) < 0)
2086 return (SNMP_ERR_GENERR);
2087 return (SNMP_ERR_NOERROR);
2093 switch (val->var.subs[sub - 1]) {
2094 case LEAF_wlanMeshRetryTimeout:
2095 val->v.integer = wlan_config.mesh_retryto;
2097 case LEAF_wlanMeshHoldingTimeout:
2098 val->v.integer = wlan_config.mesh_holdingto;
2100 case LEAF_wlanMeshConfirmTimeout:
2101 val->v.integer = wlan_config.mesh_confirmto;
2103 case LEAF_wlanMeshMaxRetries:
2104 val->v.integer = wlan_config.mesh_maxretries;
2108 return (SNMP_ERR_NOERROR);
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)
2116 struct wlan_iface *wif;
2118 wlan_update_interface_list();
2122 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL)
2123 return (SNMP_ERR_NOSUCHNAME);
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);
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';
2149 case LEAF_wlanMeshTTL:
2150 ctx->scratch->int1 = wif->mesh_ttl;
2151 wif->mesh_ttl = val->v.integer;
2153 case LEAF_wlanMeshPeeringEnabled:
2154 ctx->scratch->int1 = wif->mesh_peering;
2155 wif->mesh_peering = val->v.integer;
2157 case LEAF_wlanMeshForwardingEnabled:
2158 ctx->scratch->int1 = wif->mesh_forwarding;
2159 wif->mesh_forwarding = val->v.integer;
2161 case LEAF_wlanMeshMetric:
2162 ctx->scratch->int1 = wif->mesh_metric;
2163 wif->mesh_metric = val->v.integer;
2165 case LEAF_wlanMeshPath:
2166 ctx->scratch->int1 = wif->mesh_path;
2167 wif->mesh_path = val->v.integer;
2169 case LEAF_wlanMeshRoutesFlush:
2170 if (val->v.integer != wlanMeshRoutesFlush_flush)
2171 return (SNMP_ERR_INCONS_VALUE);
2172 return (SNMP_ERR_NOERROR);
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);
2180 rc = wlan_mesh_config_set(wif, val->var.subs[sub - 1]);
2182 return (SNMP_ERR_GENERR);
2183 return (SNMP_ERR_NOERROR);
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);
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);
2204 case LEAF_wlanMeshTTL:
2205 wif->mesh_ttl = ctx->scratch->int1;
2207 case LEAF_wlanMeshPeeringEnabled:
2208 wif->mesh_peering = ctx->scratch->int1;
2210 case LEAF_wlanMeshForwardingEnabled:
2211 wif->mesh_forwarding = ctx->scratch->int1;
2213 case LEAF_wlanMeshMetric:
2214 wif->mesh_metric = ctx->scratch->int1;
2216 case LEAF_wlanMeshPath:
2217 wif->mesh_path = ctx->scratch->int1;
2219 case LEAF_wlanMeshRoutesFlush:
2220 return (SNMP_ERR_NOERROR);
2224 if (val->var.subs[sub - 1] == LEAF_wlanMeshId)
2225 rc = wlan_config_set_dssid(wif, wif->desired_ssid,
2226 strlen(wif->desired_ssid));
2228 rc = wlan_mesh_config_set(wif, val->var.subs[sub - 1]);
2230 return (SNMP_ERR_GENERR);
2231 return (SNMP_ERR_NOERROR);
2237 if (val->var.subs[sub - 1] == LEAF_wlanMeshId)
2238 rc = wlan_config_get_dssid(wif);
2240 rc = wlan_mesh_config_get(wif, val->var.subs[sub - 1]);
2242 return (SNMP_ERR_GENERR);
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;
2250 case LEAF_wlanMeshPeeringEnabled:
2251 val->v.integer = wif->mesh_peering;
2253 case LEAF_wlanMeshForwardingEnabled:
2254 val->v.integer = wif->mesh_forwarding;
2256 case LEAF_wlanMeshMetric:
2257 val->v.integer = wif->mesh_metric;
2259 case LEAF_wlanMeshPath:
2260 val->v.integer = wif->mesh_path;
2262 case LEAF_wlanMeshRoutesFlush:
2263 val->v.integer = wlanMeshRoutesFlush_no_op;
2269 return (SNMP_ERR_NOERROR);
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)
2276 struct wlan_peer *wip;
2277 struct wlan_iface *wif;
2279 wlan_update_interface_list();
2280 wlan_update_peers();
2284 if ((wip = wlan_mesh_get_peer(&val->var, sub, &wif)) == NULL)
2285 return (SNMP_ERR_NOSUCHNAME);
2287 case SNMP_OP_GETNEXT:
2288 wip = wlan_mesh_get_next_peer(&val->var, sub, &wif);
2290 return (SNMP_ERR_NOSUCHNAME);
2291 wlan_append_mac_index(&val->var, sub, wif->wname,
2295 return (SNMP_ERR_NOT_WRITEABLE);
2296 case SNMP_OP_COMMIT:
2298 case SNMP_OP_ROLLBACK:
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;
2310 case LEAF_wlanMeshNeighborLocalId:
2311 val->v.integer = wip->local_id;
2313 case LEAF_wlanMeshNeighborPeerId:
2314 val->v.integer = wip->peer_id;
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;
2322 case LEAF_wlanMeshNeighborRxSignalStrength:
2323 val->v.integer = wip->rssi;
2325 case LEAF_wlanMeshNeighborIdleTimer:
2326 val->v.integer = wip->idle;
2328 case LEAF_wlanMeshNeighborTxSequenceNo:
2329 val->v.integer = wip->txseqs;
2331 case LEAF_wlanMeshNeighborRxSequenceNo:
2332 val->v.integer = wip->rxseqs;
2338 return (SNMP_ERR_NOERROR);
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)
2345 struct wlan_mesh_route *wmr;
2346 struct wlan_iface *wif;
2348 wlan_update_interface_list();
2349 wlan_mesh_update_routes();
2353 if ((wmr = wlan_mesh_get_route(&val->var, sub, &wif)) == NULL)
2354 return (SNMP_ERR_NOSUCHNAME);
2357 case SNMP_OP_GETNEXT:
2358 wmr = wlan_mesh_get_next_route(&val->var, sub, &wif);
2360 return (SNMP_ERR_NOSUCHNAME);
2361 wlan_append_mac_index(&val->var, sub, wif->wname,
2362 wmr->imroute.imr_dest);
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));
2372 return (SNMP_ERR_NOT_WRITEABLE);
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);
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);
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;
2406 case LEAF_wlanMeshRouteMetric:
2407 val->v.integer = wmr->imroute.imr_metric;
2409 case LEAF_wlanMeshRouteLifeTime:
2410 val->v.integer = wmr->imroute.imr_lifetime;
2412 case LEAF_wlanMeshRouteLastMseq:
2413 val->v.integer = wmr->imroute.imr_lastmseq;
2415 case LEAF_wlanMeshRouteFlags:
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;
2430 return (SNMP_ERR_NOERROR);
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)
2437 struct wlan_iface *wif;
2439 wlan_update_interface_list();
2443 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL)
2444 return (SNMP_ERR_NOSUCHNAME);
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);
2452 return (SNMP_ERR_NOT_WRITEABLE);
2453 case SNMP_OP_COMMIT:
2455 case SNMP_OP_ROLLBACK:
2461 if (wlan_get_stats(wif) < 0)
2462 return (SNMP_ERR_GENERR);
2464 switch (val->var.subs[sub - 1]) {
2465 case LEAF_wlanMeshDroppedBadSta:
2466 val->v.uint32 = wif->stats.is_mesh_wrongmesh;
2468 case LEAF_wlanMeshDroppedNoLink:
2469 val->v.uint32 = wif->stats.is_mesh_nolink;
2471 case LEAF_wlanMeshNoFwdTtl:
2472 val->v.uint32 = wif->stats.is_mesh_fwd_ttl;
2474 case LEAF_wlanMeshNoFwdBuf:
2475 val->v.uint32 = wif->stats.is_mesh_fwd_nobuf;
2477 case LEAF_wlanMeshNoFwdTooShort:
2478 val->v.uint32 = wif->stats.is_mesh_fwd_tooshort;
2480 case LEAF_wlanMeshNoFwdDisabled:
2481 val->v.uint32 = wif->stats.is_mesh_fwd_disabled;
2483 case LEAF_wlanMeshNoFwdPathUnknown:
2484 val->v.uint32 = wif->stats.is_mesh_fwd_nopath;
2486 case LEAF_wlanMeshDroppedBadAE:
2487 val->v.uint32 = wif->stats.is_mesh_badae;
2489 case LEAF_wlanMeshRouteAddFailed:
2490 val->v.uint32 = wif->stats.is_mesh_rtaddfailed;
2492 case LEAF_wlanMeshDroppedNoProxy:
2493 val->v.uint32 = wif->stats.is_mesh_notproxy;
2495 case LEAF_wlanMeshDroppedMisaligned:
2496 val->v.uint32 = wif->stats.is_rx_badalign;
2502 return (SNMP_ERR_NOERROR);
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)
2511 switch (val->var.subs[sub - 1]) {
2512 case LEAF_wlanHWMPRouteInactiveTimeout:
2513 which = WLAN_HWMP_INACTIVITY_TO;
2515 case LEAF_wlanHWMPRootAnnounceInterval:
2516 which = WLAN_HWMP_RANN_INT;
2518 case LEAF_wlanHWMPRootInterval:
2519 which = WLAN_HWMP_ROOT_INT;
2521 case LEAF_wlanHWMPRootTimeout:
2522 which = WLAN_HWMP_ROOT_TO;
2524 case LEAF_wlanHWMPPathLifetime:
2525 which = WLAN_HWMP_PATH_LIFETIME;
2527 case LEAF_wlanHWMPReplyForwardBit:
2528 which = WLAN_HWMP_REPLY_FORWARD;
2530 case LEAF_wlanHWMPTargetOnlyBit:
2531 which = WLAN_HWMP_TARGET_ONLY;
2539 if (wlan_do_sysctl(&wlan_config, which, 0) < 0)
2540 return (SNMP_ERR_GENERR);
2543 case SNMP_OP_GETNEXT:
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;
2552 case LEAF_wlanHWMPRootAnnounceInterval:
2553 ctx->scratch->int1 = wlan_config.hwmp_rannint;
2554 wlan_config.hwmp_rannint = val->v.integer;
2556 case LEAF_wlanHWMPRootInterval:
2557 ctx->scratch->int1 = wlan_config.hwmp_rootint;
2558 wlan_config.hwmp_rootint = val->v.integer;
2560 case LEAF_wlanHWMPRootTimeout:
2561 ctx->scratch->int1 = wlan_config.hwmp_roottimeout;
2562 wlan_config.hwmp_roottimeout = val->v.integer;
2564 case LEAF_wlanHWMPPathLifetime:
2565 ctx->scratch->int1 = wlan_config.hwmp_pathlifetime;
2566 wlan_config.hwmp_pathlifetime = val->v.integer;
2568 case LEAF_wlanHWMPReplyForwardBit:
2569 ctx->scratch->int1 = wlan_config.hwmp_replyforward;
2570 wlan_config.hwmp_replyforward = val->v.integer;
2572 case LEAF_wlanHWMPTargetOnlyBit:
2573 ctx->scratch->int1 = wlan_config.hwmp_targetonly;
2574 wlan_config.hwmp_targetonly = val->v.integer;
2577 if (wlan_do_sysctl(&wlan_config, which, 1) < 0)
2578 return (SNMP_ERR_GENERR);
2579 return (SNMP_ERR_NOERROR);
2581 case SNMP_OP_COMMIT:
2582 return (SNMP_ERR_NOERROR);
2584 case SNMP_OP_ROLLBACK:
2585 switch (val->var.subs[sub - 1]) {
2586 case LEAF_wlanHWMPRouteInactiveTimeout:
2587 wlan_config.hwmp_inact = ctx->scratch->int1;
2589 case LEAF_wlanHWMPRootAnnounceInterval:
2590 wlan_config.hwmp_rannint = ctx->scratch->int1;
2592 case LEAF_wlanHWMPRootInterval:
2593 wlan_config.hwmp_rootint = ctx->scratch->int1;
2595 case LEAF_wlanHWMPRootTimeout:
2596 wlan_config.hwmp_roottimeout = ctx->scratch->int1;
2598 case LEAF_wlanHWMPPathLifetime:
2599 wlan_config.hwmp_pathlifetime = ctx->scratch->int1;
2601 case LEAF_wlanHWMPReplyForwardBit:
2602 wlan_config.hwmp_replyforward = ctx->scratch->int1;
2604 case LEAF_wlanHWMPTargetOnlyBit:
2605 wlan_config.hwmp_targetonly = ctx->scratch->int1;
2608 if (wlan_do_sysctl(&wlan_config, which, 1) < 0)
2609 return (SNMP_ERR_GENERR);
2610 return (SNMP_ERR_NOERROR);
2616 switch (val->var.subs[sub - 1]) {
2617 case LEAF_wlanHWMPRouteInactiveTimeout:
2618 val->v.integer = wlan_config.hwmp_inact;
2620 case LEAF_wlanHWMPRootAnnounceInterval:
2621 val->v.integer = wlan_config.hwmp_rannint;
2623 case LEAF_wlanHWMPRootInterval:
2624 val->v.integer = wlan_config.hwmp_rootint;
2626 case LEAF_wlanHWMPRootTimeout:
2627 val->v.integer = wlan_config.hwmp_roottimeout;
2629 case LEAF_wlanHWMPPathLifetime:
2630 val->v.integer = wlan_config.hwmp_pathlifetime;
2632 case LEAF_wlanHWMPReplyForwardBit:
2633 val->v.integer = wlan_config.hwmp_replyforward;
2635 case LEAF_wlanHWMPTargetOnlyBit:
2636 val->v.integer = wlan_config.hwmp_targetonly;
2640 return (SNMP_ERR_NOERROR);
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)
2647 struct wlan_iface *wif;
2649 wlan_update_interface_list();
2653 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL)
2654 return (SNMP_ERR_NOSUCHNAME);
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);
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;
2671 case LEAF_wlanHWMPMaxHops:
2672 ctx->scratch->int1 = wif->hwmp_max_hops;
2673 wif->hwmp_max_hops = val->v.integer;
2678 if (wlan_hwmp_config_set(wif, val->var.subs[sub - 1]) < 0)
2679 return (SNMP_ERR_GENERR);
2680 return (SNMP_ERR_NOERROR);
2682 case SNMP_OP_COMMIT:
2683 return (SNMP_ERR_NOERROR);
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;
2692 case LEAF_wlanHWMPMaxHops:
2693 wif->hwmp_max_hops = ctx->scratch->int1;
2698 if (wlan_hwmp_config_set(wif, val->var.subs[sub - 1]) < 0)
2699 return (SNMP_ERR_GENERR);
2700 return (SNMP_ERR_NOERROR);
2706 if (wlan_hwmp_config_get(wif, val->var.subs[sub - 1]) < 0)
2707 return (SNMP_ERR_GENERR);
2709 switch (val->var.subs[sub - 1]) {
2710 case LEAF_wlanHWMPRootMode:
2711 val->v.integer = wif->hwmp_root_mode;
2713 case LEAF_wlanHWMPMaxHops:
2714 val->v.integer = wif->hwmp_max_hops;
2720 return (SNMP_ERR_NOERROR);
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)
2727 struct wlan_iface *wif;
2729 wlan_update_interface_list();
2733 if ((wif = wlan_mesh_get_iface(&val->var, sub)) == NULL)
2734 return (SNMP_ERR_NOSUCHNAME);
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);
2742 return (SNMP_ERR_NOT_WRITEABLE);
2743 case SNMP_OP_COMMIT:
2745 case SNMP_OP_ROLLBACK:
2751 if (wlan_get_stats(wif) < 0)
2752 return (SNMP_ERR_GENERR);
2754 switch (val->var.subs[sub - 1]) {
2755 case LEAF_wlanMeshHWMPWrongSeqNo:
2756 val->v.uint32 = wif->stats.is_hwmp_wrongseq;
2758 case LEAF_wlanMeshHWMPTxRootPREQ:
2759 val->v.uint32 = wif->stats.is_hwmp_rootreqs;
2761 case LEAF_wlanMeshHWMPTxRootRANN:
2762 val->v.uint32 = wif->stats.is_hwmp_rootrann;
2764 case LEAF_wlanMeshHWMPProxy:
2765 val->v.uint32 = wif->stats.is_hwmp_proxy;
2771 return (SNMP_ERR_NOERROR);
2775 * Encode BITS type for a response packet - XXX: this belongs to the snmp lib.
2778 bits_get(struct snmp_value *value, const u_char *ptr, ssize_t len)
2783 value->v.octetstring.len = 0;
2784 value->v.octetstring.octets = NULL;
2785 return (SNMP_ERR_NOERROR);
2788 /* Determine length - up to 8 octets supported so far. */
2789 for (size = len; size > 0; size--)
2790 if (ptr[size - 1] != 0)
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);
2803 * Calls for adding/updating/freeing/etc of wireless interfaces.
2806 wlan_free_interface(struct wlan_iface *wif)
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);
2817 wlan_free_iflist(void)
2819 struct wlan_iface *w;
2821 while ((w = SLIST_FIRST(&wlan_ifaces)) != NULL) {
2822 SLIST_REMOVE_HEAD(&wlan_ifaces, w_if);
2823 wlan_free_interface(w);
2827 static struct wlan_iface *
2828 wlan_find_interface(const char *wname)
2830 struct wlan_iface *wif;
2832 SLIST_FOREACH(wif, &wlan_ifaces, w_if)
2833 if (strcmp(wif->wname, wname) == 0) {
2834 if (wif->status != RowStatus_active)
2842 static struct wlan_iface *
2843 wlan_first_interface(void)
2845 return (SLIST_FIRST(&wlan_ifaces));
2848 static struct wlan_iface *
2849 wlan_next_interface(struct wlan_iface *wif)
2854 return (SLIST_NEXT(wif, w_if));
2858 * Add a new interface to the list - sorted by name.
2861 wlan_add_wif(struct wlan_iface *wif)
2864 struct wlan_iface *temp, *prev;
2866 if ((prev = SLIST_FIRST(&wlan_ifaces)) == NULL ||
2867 strcmp(wif->wname, prev->wname) < 0) {
2868 SLIST_INSERT_HEAD(&wlan_ifaces, wif, w_if);
2872 SLIST_FOREACH(temp, &wlan_ifaces, w_if) {
2873 if ((cmp = strcmp(wif->wname, temp->wname)) <= 0)
2879 SLIST_INSERT_AFTER(prev, wif, w_if);
2881 SLIST_INSERT_AFTER(temp, wif, w_if);
2883 syslog(LOG_ERR, "Wlan iface %s already in list", wif->wname);
2890 static struct wlan_iface *
2891 wlan_new_wif(char *wname)
2893 struct wlan_iface *wif;
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) {
2903 if ((wif = (struct wlan_iface *)malloc(sizeof(*wif))) == NULL)
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;
2912 if (wlan_add_wif(wif) < 0) {
2921 wlan_delete_wif(struct wlan_iface *wif)
2923 SLIST_REMOVE(&wlan_ifaces, wif, wlan_iface, w_if);
2924 wlan_free_interface(wif);
2928 wlan_attach_newif(struct mibif *mif)
2930 struct wlan_iface *wif;
2932 if (mif->mib.ifmd_data.ifi_type != IFT_ETHER ||
2933 wlan_check_media(mif->name) != IFM_IEEE80211)
2936 if ((wif = wlan_new_wif(mif->name)) == NULL)
2939 (void)wlan_get_opmode(wif);
2940 wif->index = mif->index;
2941 wif->status = RowStatus_active;
2942 (void)wlan_update_interface(wif);
2948 wlan_iface_create(struct wlan_iface *wif)
2952 if ((rc = wlan_clone_create(wif)) == SNMP_ERR_NOERROR) {
2954 * The rest of the info will be updated once the
2955 * snmp_mibII module notifies us of the interface.
2957 wif->status = RowStatus_active;
2958 if (wif->state == wlanIfaceState_up)
2959 (void)wlan_config_state(wif, 1);
2966 wlan_iface_destroy(struct wlan_iface *wif)
2968 int rc = SNMP_ERR_NOERROR;
2970 if (wif->internal == 0)
2971 rc = wlan_clone_destroy(wif);
2973 if (rc == SNMP_ERR_NOERROR)
2974 wlan_delete_wif(wif);
2980 wlan_update_interface(struct wlan_iface *wif)
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);
2991 * XXX: wlan_get_channel_list() not needed -
2992 * fetched with wlan_get_driver_caps()
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);
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);
3016 wlan_update_interface_list(void)
3018 struct wlan_iface *wif, *twif;
3020 if ((time(NULL) - wlan_iflist_age) <= WLAN_LIST_MAXAGE)
3024 * The snmp_mibII module would have notified us for new interfaces,
3025 * so only check if any have been deleted.
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);
3031 wlan_iflist_age = time(NULL);
3035 wlan_append_ifindex(struct asn_oid *oid, uint sub, const struct wlan_iface *w)
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];
3046 wlan_get_ifname(const struct asn_oid *oid, uint sub, uint8_t *wname)
3050 memset(wname, 0, IFNAMSIZ);
3052 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ)
3055 for (i = 0; i < oid->subs[sub]; i++)
3056 wname[i] = oid->subs[sub + i + 1];
3062 static struct wlan_iface *
3063 wlan_get_interface(const struct asn_oid *oid, uint sub)
3065 uint8_t wname[IFNAMSIZ];
3067 if (wlan_get_ifname(oid, sub, wname) == NULL)
3070 return (wlan_find_interface(wname));
3073 static struct wlan_iface *
3074 wlan_get_next_interface(const struct asn_oid *oid, uint sub)
3077 uint8_t wname[IFNAMSIZ];
3078 struct wlan_iface *wif;
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)
3088 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ)
3091 memset(wname, 0, IFNAMSIZ);
3092 for (i = 0; i < oid->subs[sub]; i++)
3093 wname[i] = oid->subs[sub + i + 1];
3095 if ((wif = wlan_find_interface(wname)) == NULL)
3098 while ((wif = wlan_next_interface(wif)) != NULL)
3099 if (wif->status == RowStatus_active)
3105 static struct wlan_iface *
3106 wlan_get_snmp_interface(const struct asn_oid *oid, uint sub)
3108 uint8_t wname[IFNAMSIZ];
3109 struct wlan_iface *wif;
3111 if (wlan_get_ifname(oid, sub, wname) == NULL)
3114 for (wif = wlan_first_interface(); wif != NULL;
3115 wif = wlan_next_interface(wif))
3116 if (strcmp(wif->wname, wname) == 0)
3122 static struct wlan_iface *
3123 wlan_get_next_snmp_interface(const struct asn_oid *oid, uint sub)
3126 uint8_t wname[IFNAMSIZ];
3127 struct wlan_iface *wif;
3129 if (oid->len - sub == 0)
3130 return (wlan_first_interface());
3132 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ)
3135 memset(wname, 0, IFNAMSIZ);
3136 for (i = 0; i < oid->subs[sub]; i++)
3137 wname[i] = oid->subs[sub + i + 1];
3140 for (wif = wlan_first_interface(); wif != NULL;
3141 wif = wlan_next_interface(wif))
3142 if (strcmp(wif->wname, wname) == 0)
3145 return (wlan_next_interface(wif));
3149 * Decode/Append an index for tables indexed by the wireless interface
3150 * name and a MAC address - ACL MACs and Mesh Routes.
3153 wlan_mac_index_decode(const struct asn_oid *oid, uint sub,
3154 char *wname, uint8_t *mac)
3159 if (oid->len - sub != oid->subs[sub] + 2 + IEEE80211_ADDR_LEN
3160 || oid->subs[sub] >= IFNAMSIZ)
3163 for (i = 0; i < oid->subs[sub]; i++)
3164 wname[i] = oid->subs[sub + i + 1];
3167 mac_off = sub + oid->subs[sub] + 1;
3168 if (oid->subs[mac_off] != IEEE80211_ADDR_LEN)
3170 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
3171 mac[i] = oid->subs[mac_off + i + 1];
3177 wlan_append_mac_index(struct asn_oid *oid, uint sub, char *wname, uint8_t *mac)
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];
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];
3193 * Decode/Append an index for tables indexed by the wireless interface
3194 * name and the PHY mode - Roam and TX params.
3197 wlan_phy_index_decode(const struct asn_oid *oid, uint sub, char *wname,
3202 if (oid->len - sub != oid->subs[sub] + 2 || oid->subs[sub] >= IFNAMSIZ)
3205 for (i = 0; i < oid->subs[sub]; i++)
3206 wname[i] = oid->subs[sub + i + 1];
3209 *phy = oid->subs[sub + oid->subs[sub] + 1];
3214 wlan_append_phy_index(struct asn_oid *oid, uint sub, char *wname, uint32_t phy)
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;
3226 * Calls for manipulating the peerlist of a wireless interface.
3229 wlan_free_peerlist(struct wlan_iface *wif)
3231 struct wlan_peer *wip;
3233 while ((wip = SLIST_FIRST(&wif->peerlist)) != NULL) {
3234 SLIST_REMOVE_HEAD(&wif->peerlist, wp);
3238 SLIST_INIT(&wif->peerlist);
3241 static struct wlan_peer *
3242 wlan_find_peer(struct wlan_iface *wif, uint8_t *peermac)
3244 struct wlan_peer *wip;
3246 SLIST_FOREACH(wip, &wif->peerlist, wp)
3247 if (memcmp(wip->pmac, peermac, IEEE80211_ADDR_LEN) == 0)
3254 wlan_new_peer(const uint8_t *pmac)
3256 struct wlan_peer *wip;
3258 if ((wip = (struct wlan_peer *)malloc(sizeof(*wip))) == NULL)
3261 memset(wip, 0, sizeof(struct wlan_peer));
3262 memcpy(wip->pmac, pmac, IEEE80211_ADDR_LEN);
3268 wlan_free_peer(struct wlan_peer *wip)
3274 wlan_add_peer(struct wlan_iface *wif, struct wlan_peer *wip)
3276 struct wlan_peer *temp, *prev;
3278 SLIST_FOREACH(temp, &wif->peerlist, wp)
3279 if (memcmp(temp->pmac, wip->pmac, IEEE80211_ADDR_LEN) == 0)
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);
3288 SLIST_FOREACH(temp, &wif->peerlist, wp) {
3289 if (memcmp(wip->pmac, temp->pmac, IEEE80211_ADDR_LEN) < 0)
3294 SLIST_INSERT_AFTER(prev, wip, wp);
3299 wlan_update_peers(void)
3301 struct wlan_iface *wif;
3303 if ((time(NULL) - wlan_peerlist_age) <= WLAN_LIST_MAXAGE)
3306 for (wif = wlan_first_interface(); wif != NULL;
3307 wif = wlan_next_interface(wif)) {
3308 if (wif->status != RowStatus_active)
3310 wlan_free_peerlist(wif);
3311 (void)wlan_get_peerinfo(wif);
3313 wlan_peerlist_age = time(NULL);
3316 static struct wlan_peer *
3317 wlan_get_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
3319 char wname[IFNAMSIZ];
3320 uint8_t pmac[IEEE80211_ADDR_LEN];
3322 if (wlan_mac_index_decode(oid, sub, wname, pmac) < 0)
3325 if ((*wif = wlan_find_interface(wname)) == NULL)
3328 return (wlan_find_peer(*wif, pmac));
3331 static struct wlan_peer *
3332 wlan_get_next_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
3334 char wname[IFNAMSIZ];
3335 char pmac[IEEE80211_ADDR_LEN];
3336 struct wlan_peer *wip;
3338 if (oid->len - sub == 0) {
3339 for (*wif = wlan_first_interface(); *wif != NULL;
3340 *wif = wlan_next_interface(*wif)) {
3342 WlanIfaceOperatingModeType_meshPoint)
3344 wip = SLIST_FIRST(&(*wif)->peerlist);
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)
3356 if ((wip = SLIST_NEXT(wip, wp)) != NULL)
3359 while ((*wif = wlan_next_interface(*wif)) != NULL) {
3360 if ((*wif)->mode == WlanIfaceOperatingModeType_meshPoint)
3362 if ((wip = SLIST_FIRST(&(*wif)->peerlist)) != NULL)
3370 * Calls for manipulating the active channel list of a wireless interface.
3373 wlan_update_channels(void)
3375 struct wlan_iface *wif;
3377 if ((time(NULL) - wlan_chanlist_age) <= WLAN_LIST_MAXAGE)
3380 for (wif = wlan_first_interface(); wif != NULL;
3381 wif = wlan_next_interface(wif)) {
3382 if (wif->status != RowStatus_active)
3384 (void)wlan_get_channel_list(wif);
3386 wlan_chanlist_age = time(NULL);
3390 wlan_channel_index_decode(const struct asn_oid *oid, uint sub, char *wname,
3394 if (oid->len - sub != oid->subs[sub] + 2 || oid->subs[sub] >= IFNAMSIZ)
3397 for (i = 0; i < oid->subs[sub]; i++)
3398 wname[i] = oid->subs[sub + i + 1];
3401 *cindex = oid->subs[sub + oid->subs[sub] + 1];
3407 wlan_append_channel_index(struct asn_oid *oid, uint sub,
3408 const struct wlan_iface *wif, const struct ieee80211_channel *channel)
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;
3420 wlan_get_channel_type(struct ieee80211_channel *c)
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);
3442 static struct ieee80211_channel *
3443 wlan_find_channel(struct wlan_iface *wif, uint32_t cindex)
3445 if (wif->chanlist == NULL || cindex > wif->nchannels)
3448 return (wif->chanlist + cindex - 1);
3451 static struct ieee80211_channel *
3452 wlan_get_channel(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
3455 char wname[IFNAMSIZ];
3457 if (wlan_channel_index_decode(oid, sub, wname, &cindex) < 0)
3460 if ((*wif = wlan_find_interface(wname)) == NULL)
3463 return (wlan_find_channel(*wif, cindex));
3466 static struct ieee80211_channel *
3467 wlan_get_next_channel(const struct asn_oid *oid, uint sub,
3468 struct wlan_iface **wif)
3471 char wname[IFNAMSIZ];
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)
3478 if ((*wif)->nchannels != 0 && (*wif)->chanlist != NULL)
3479 return ((*wif)->chanlist);
3484 if (wlan_channel_index_decode(oid, sub, wname, &cindex) < 0)
3487 if ((*wif = wlan_find_interface(wname)) == NULL)
3490 if (cindex < (*wif)->nchannels)
3491 return ((*wif)->chanlist + cindex);
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);
3502 * Calls for manipulating the roam params of a wireless interface.
3505 wlan_update_roam_params(void)
3507 struct wlan_iface *wif;
3509 if ((time(NULL) - wlan_roamlist_age) <= WLAN_LIST_MAXAGE)
3512 for (wif = wlan_first_interface(); wif != NULL;
3513 wif = wlan_next_interface(wif)) {
3514 if (wif->status != RowStatus_active)
3516 (void)wlan_get_roam_params(wif);
3518 wlan_roamlist_age = time(NULL);
3521 static struct ieee80211_roamparam *
3522 wlan_get_roam_param(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
3525 char wname[IFNAMSIZ];
3527 if (wlan_phy_index_decode(oid, sub, wname, &phy) < 0)
3530 if ((*wif = wlan_find_interface(wname)) == NULL)
3533 if (phy == 0 || phy > IEEE80211_MODE_MAX)
3536 return ((*wif)->roamparams.params + phy - 1);
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)
3543 char wname[IFNAMSIZ];
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)
3551 return ((*wif)->roamparams.params);
3556 if (wlan_phy_index_decode(oid, sub, wname, phy) < 0)
3559 if (*phy == 0 || (*wif = wlan_find_interface(wname)) == NULL)
3562 if (++(*phy) <= IEEE80211_MODE_MAX)
3563 return ((*wif)->roamparams.params + *phy - 1);
3566 while ((*wif = wlan_next_interface(*wif)) != NULL)
3567 if ((*wif)->status == RowStatus_active)
3568 return ((*wif)->roamparams.params);
3574 * Calls for manipulating the tx params of a wireless interface.
3577 wlan_update_tx_params(void)
3579 struct wlan_iface *wif;
3581 if ((time(NULL) - wlan_tx_paramlist_age) <= WLAN_LIST_MAXAGE)
3584 for (wif = wlan_first_interface(); wif != NULL;
3585 wif = wlan_next_interface(wif)) {
3586 if (wif->status != RowStatus_active)
3588 (void)wlan_get_tx_params(wif);
3591 wlan_tx_paramlist_age = time(NULL);
3594 static struct ieee80211_txparam *
3595 wlan_get_tx_param(const struct asn_oid *oid, uint sub, struct wlan_iface **wif,
3598 char wname[IFNAMSIZ];
3600 if (wlan_phy_index_decode(oid, sub, wname, phy) < 0)
3603 if ((*wif = wlan_find_interface(wname)) == NULL)
3606 if (*phy == 0 || *phy > IEEE80211_MODE_MAX)
3609 return ((*wif)->txparams.params + *phy - 1);
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)
3616 char wname[IFNAMSIZ];
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)
3624 return ((*wif)->txparams.params);
3629 if (wlan_phy_index_decode(oid, sub, wname, phy) < 0)
3632 if (*phy == 0 || (*wif = wlan_find_interface(wname)) == NULL)
3635 if (++(*phy) <= IEEE80211_MODE_MAX)
3636 return ((*wif)->txparams.params + *phy - 1);
3639 while ((*wif = wlan_next_interface(*wif)) != NULL)
3640 if ((*wif)->status == RowStatus_active)
3641 return ((*wif)->txparams.params);
3647 * Calls for manipulating the scan results for a wireless interface.
3650 wlan_scan_free_results(struct wlan_iface *wif)
3652 struct wlan_scan_result *sr;
3654 while ((sr = SLIST_FIRST(&wif->scanlist)) != NULL) {
3655 SLIST_REMOVE_HEAD(&wif->scanlist, wsr);
3659 SLIST_INIT(&wif->scanlist);
3662 static struct wlan_scan_result *
3663 wlan_scan_find_result(struct wlan_iface *wif, uint8_t *ssid, uint8_t *bssid)
3665 struct wlan_scan_result *sr;
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)
3676 struct wlan_scan_result *
3677 wlan_scan_new_result(const uint8_t *ssid, const uint8_t *bssid)
3679 struct wlan_scan_result *sr;
3681 sr = (struct wlan_scan_result *)malloc(sizeof(*sr));
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);
3694 wlan_scan_free_result(struct wlan_scan_result *sr)
3700 wlan_scan_compare_result(struct wlan_scan_result *sr1,
3701 struct wlan_scan_result *sr2)
3705 if (strlen(sr1->ssid) < strlen(sr2->ssid))
3707 if (strlen(sr1->ssid) > strlen(sr2->ssid))
3710 for (i = 0; i < strlen(sr1->ssid) && i < strlen(sr2->ssid); i++) {
3711 if (sr1->ssid[i] < sr2->ssid[i])
3713 if (sr1->ssid[i] > sr2->ssid[i])
3717 for (i = 0; i < IEEE80211_ADDR_LEN; i++) {
3718 if (sr1->bssid[i] < sr2->bssid[i])
3720 if (sr1->bssid[i] > sr2->bssid[i])
3728 wlan_scan_add_result(struct wlan_iface *wif, struct wlan_scan_result *sr)
3730 struct wlan_scan_result *prev, *temp;
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)
3738 if ((prev = SLIST_FIRST(&wif->scanlist)) == NULL ||
3739 wlan_scan_compare_result(sr, prev) < 0) {
3740 SLIST_INSERT_HEAD(&wif->scanlist, sr, wsr);
3744 SLIST_FOREACH(temp, &wif->scanlist, wsr) {
3745 if (wlan_scan_compare_result(sr, temp) < 0)
3750 SLIST_INSERT_AFTER(prev, sr, wsr);
3755 wlan_scan_update_results(void)
3757 struct wlan_iface *wif;
3759 if ((time(NULL) - wlan_scanlist_age) <= WLAN_LIST_MAXAGE)
3762 for (wif = wlan_first_interface(); wif != NULL;
3763 wif = wlan_next_interface(wif)) {
3764 if (wif->status != RowStatus_active)
3766 wlan_scan_free_results(wif);
3767 (void)wlan_get_scan_results(wif);
3769 wlan_scanlist_age = time(NULL);
3773 wlan_scanr_index_decode(const struct asn_oid *oid, uint sub,
3774 char *wname, uint8_t *ssid, uint8_t *bssid)
3779 if (oid->subs[sub] >= IFNAMSIZ)
3781 for (i = 0; i < oid->subs[sub]; i++)
3782 wname[i] = oid->subs[sub + i + 1];
3783 wname[oid->subs[sub]] = '\0';
3785 offset = sub + oid->subs[sub] + 1;
3786 if (oid->subs[offset] > IEEE80211_NWID_LEN)
3788 for (i = 0; i < oid->subs[offset]; i++)
3789 ssid[i] = oid->subs[offset + i + 1];
3792 offset = sub + oid->subs[sub] + oid->subs[offset] + 2;
3793 if (oid->subs[offset] != IEEE80211_ADDR_LEN)
3795 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
3796 bssid[i] = oid->subs[offset + i + 1];
3802 wlan_append_scanr_index(struct asn_oid *oid, uint sub, char *wname,
3803 uint8_t *ssid, uint8_t *bssid)
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];
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];
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];
3823 static struct wlan_scan_result *
3824 wlan_get_scanr(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
3826 char wname[IFNAMSIZ];
3827 uint8_t ssid[IEEE80211_NWID_LEN + 1];
3828 uint8_t bssid[IEEE80211_ADDR_LEN];
3830 if (wlan_scanr_index_decode(oid, sub, wname, ssid, bssid) < 0)
3833 if ((*wif = wlan_find_interface(wname)) == NULL)
3836 return (wlan_scan_find_result(*wif, ssid, bssid));
3839 static struct wlan_scan_result *
3840 wlan_get_next_scanr(const struct asn_oid *oid, uint sub,
3841 struct wlan_iface **wif)
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;
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);
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)
3863 if ((sr = SLIST_NEXT(sr, wsr)) != NULL)
3866 while ((*wif = wlan_next_interface(*wif)) != NULL)
3867 if ((sr = SLIST_FIRST(&(*wif)->scanlist)) != NULL)
3874 * MAC Access Control.
3877 wlan_mac_free_maclist(struct wlan_iface *wif)
3879 struct wlan_mac_mac *wmm;
3881 while ((wmm = SLIST_FIRST(&wif->mac_maclist)) != NULL) {
3882 SLIST_REMOVE_HEAD(&wif->mac_maclist, wm);
3886 SLIST_INIT(&wif->mac_maclist);
3889 static struct wlan_mac_mac *
3890 wlan_mac_find_mac(struct wlan_iface *wif, uint8_t *mac)
3892 struct wlan_mac_mac *wmm;
3894 SLIST_FOREACH(wmm, &wif->mac_maclist, wm)
3895 if (memcmp(wmm->mac, mac, IEEE80211_ADDR_LEN) == 0)
3901 struct wlan_mac_mac *
3902 wlan_mac_new_mac(const uint8_t *mac)
3904 struct wlan_mac_mac *wmm;
3906 if ((wmm = (struct wlan_mac_mac *)malloc(sizeof(*wmm))) == NULL)
3909 memset(wmm, 0, sizeof(*wmm));
3910 memcpy(wmm->mac, mac, IEEE80211_ADDR_LEN);
3911 wmm->mac_status = RowStatus_notReady;
3917 wlan_mac_free_mac(struct wlan_mac_mac *wmm)
3923 wlan_mac_add_mac(struct wlan_iface *wif, struct wlan_mac_mac *wmm)
3925 struct wlan_mac_mac *temp, *prev;
3927 SLIST_FOREACH(temp, &wif->mac_maclist, wm)
3928 if (memcmp(temp->mac, wmm->mac, IEEE80211_ADDR_LEN) == 0)
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);
3937 SLIST_FOREACH(temp, &wif->mac_maclist, wm) {
3938 if (memcmp(wmm->mac, temp->mac, IEEE80211_ADDR_LEN) < 0)
3943 SLIST_INSERT_AFTER(prev, wmm, wm);
3948 wlan_mac_delete_mac(struct wlan_iface *wif, struct wlan_mac_mac *wmm)
3950 if (wmm->mac_status == RowStatus_active &&
3951 wlan_del_mac_acl_mac(wif, wmm) < 0)
3954 SLIST_REMOVE(&wif->mac_maclist, wmm, wlan_mac_mac, wm);
3961 wlan_mac_update_aclmacs(void)
3963 struct wlan_iface *wif;
3964 struct wlan_mac_mac *wmm, *twmm;
3966 if ((time(NULL) - wlan_maclist_age) <= WLAN_LIST_MAXAGE)
3969 for (wif = wlan_first_interface(); wif != NULL;
3970 wif = wlan_next_interface(wif)) {
3971 if (wif->status != RowStatus_active)
3974 * Nuke old entries - XXX - they are likely not to
3975 * change often - reconsider.
3977 SLIST_FOREACH_SAFE(wmm, &wif->mac_maclist, wm, twmm)
3978 if (wmm->mac_status == RowStatus_active) {
3979 SLIST_REMOVE(&wif->mac_maclist, wmm,
3981 wlan_mac_free_mac(wmm);
3983 (void)wlan_get_mac_acl_macs(wif);
3985 wlan_maclist_age = time(NULL);
3988 static struct wlan_mac_mac *
3989 wlan_get_acl_mac(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
3991 char wname[IFNAMSIZ];
3992 char mac[IEEE80211_ADDR_LEN];
3994 if (wlan_mac_index_decode(oid, sub, wname, mac) < 0)
3997 if ((*wif = wlan_find_interface(wname)) == NULL)
4000 return (wlan_mac_find_mac(*wif, mac));
4003 static struct wlan_mac_mac *
4004 wlan_get_next_acl_mac(const struct asn_oid *oid, uint sub,
4005 struct wlan_iface **wif)
4007 char wname[IFNAMSIZ];
4008 char mac[IEEE80211_ADDR_LEN];
4009 struct wlan_mac_mac *wmm;
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);
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)
4026 if ((wmm = SLIST_NEXT(wmm, wm)) != NULL)
4029 while ((*wif = wlan_next_interface(*wif)) != NULL)
4030 if ((wmm = SLIST_FIRST(&(*wif)->mac_maclist)) != NULL)
4037 wlan_acl_mac_set_status(struct snmp_context *ctx, struct snmp_value *val,
4040 char wname[IFNAMSIZ];
4041 uint8_t mac[IEEE80211_ADDR_LEN];
4042 struct wlan_iface *wif;
4043 struct wlan_mac_mac *macl;
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);
4049 switch (val->v.integer) {
4050 case RowStatus_createAndGo:
4052 return (SNMP_ERR_INCONS_NAME);
4054 case RowStatus_destroy:
4056 return (SNMP_ERR_NOSUCHNAME);
4057 ctx->scratch->int1 = RowStatus_active;
4058 return (SNMP_ERR_NOERROR);
4060 return (SNMP_ERR_INCONS_VALUE);
4064 if (wif == NULL || !wif->macsupported)
4065 return (SNMP_ERR_INCONS_VALUE);
4067 if ((macl = wlan_mac_new_mac((const uint8_t *)mac)) == NULL)
4068 return (SNMP_ERR_GENERR);
4070 ctx->scratch->int1 = RowStatus_destroy;
4072 if (wlan_mac_add_mac(wif, macl) < 0) {
4073 wlan_mac_free_mac(macl);
4074 return (SNMP_ERR_GENERR);
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);
4083 return (SNMP_ERR_NOERROR);
4087 * Wireless interfaces operating as mesh points.
4089 static struct wlan_iface *
4090 wlan_mesh_first_interface(void)
4092 struct wlan_iface *wif;
4094 SLIST_FOREACH(wif, &wlan_ifaces, w_if)
4095 if (wif->mode == WlanIfaceOperatingModeType_meshPoint &&
4096 wif->status == RowStatus_active)
4102 static struct wlan_iface *
4103 wlan_mesh_next_interface(struct wlan_iface *wif)
4105 struct wlan_iface *nwif;
4107 while ((nwif = wlan_next_interface(wif)) != NULL) {
4108 if (nwif->mode == WlanIfaceOperatingModeType_meshPoint &&
4109 nwif->status == RowStatus_active)
4117 static struct wlan_iface *
4118 wlan_mesh_get_iface(const struct asn_oid *oid, uint sub)
4120 struct wlan_iface *wif;
4122 if ((wif = wlan_get_interface(oid, sub)) == NULL)
4125 if (wif->mode != WlanIfaceOperatingModeType_meshPoint)
4131 static struct wlan_iface *
4132 wlan_mesh_get_next_iface(const struct asn_oid *oid, uint sub)
4135 uint8_t wname[IFNAMSIZ];
4136 struct wlan_iface *wif;
4138 if (oid->len - sub == 0)
4139 return (wlan_mesh_first_interface());
4141 if (oid->len - sub != oid->subs[sub] + 1 || oid->subs[sub] >= IFNAMSIZ)
4144 memset(wname, 0, IFNAMSIZ);
4145 for (i = 0; i < oid->subs[sub]; i++)
4146 wname[i] = oid->subs[sub + i + 1];
4149 if ((wif = wlan_find_interface(wname)) == NULL)
4152 return (wlan_mesh_next_interface(wif));
4156 * The neighbors of wireless interfaces operating as mesh points.
4158 static struct wlan_peer *
4159 wlan_mesh_get_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
4161 char wname[IFNAMSIZ];
4162 uint8_t pmac[IEEE80211_ADDR_LEN];
4164 if (wlan_mac_index_decode(oid, sub, wname, pmac) < 0)
4167 if ((*wif = wlan_find_interface(wname)) == NULL ||
4168 (*wif)->mode != WlanIfaceOperatingModeType_meshPoint)
4171 return (wlan_find_peer(*wif, pmac));
4174 static struct wlan_peer *
4175 wlan_mesh_get_next_peer(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
4177 char wname[IFNAMSIZ];
4178 char pmac[IEEE80211_ADDR_LEN];
4179 struct wlan_peer *wip;
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);
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)
4197 if ((wip = SLIST_NEXT(wip, wp)) != NULL)
4200 while ((*wif = wlan_mesh_next_interface(*wif)) != NULL)
4201 if ((wip = SLIST_FIRST(&(*wif)->peerlist)) != NULL)
4208 * Mesh routing table.
4211 wlan_mesh_free_routes(struct wlan_iface *wif)
4213 struct wlan_mesh_route *wmr;
4215 while ((wmr = SLIST_FIRST(&wif->mesh_routelist)) != NULL) {
4216 SLIST_REMOVE_HEAD(&wif->mesh_routelist, wr);
4220 SLIST_INIT(&wif->mesh_routelist);
4223 static struct wlan_mesh_route *
4224 wlan_mesh_find_route(struct wlan_iface *wif, uint8_t *dstmac)
4226 struct wlan_mesh_route *wmr;
4228 if (wif->mode != WlanIfaceOperatingModeType_meshPoint)
4231 SLIST_FOREACH(wmr, &wif->mesh_routelist, wr)
4232 if (memcmp(wmr->imroute.imr_dest, dstmac,
4233 IEEE80211_ADDR_LEN) == 0)
4239 struct wlan_mesh_route *
4240 wlan_mesh_new_route(const uint8_t *dstmac)
4242 struct wlan_mesh_route *wmr;
4244 if ((wmr = (struct wlan_mesh_route *)malloc(sizeof(*wmr))) == NULL)
4247 memset(wmr, 0, sizeof(*wmr));
4248 memcpy(wmr->imroute.imr_dest, dstmac, IEEE80211_ADDR_LEN);
4249 wmr->mroute_status = RowStatus_notReady;
4255 wlan_mesh_free_route(struct wlan_mesh_route *wmr)
4261 wlan_mesh_add_rtentry(struct wlan_iface *wif, struct wlan_mesh_route *wmr)
4263 struct wlan_mesh_route *temp, *prev;
4265 SLIST_FOREACH(temp, &wif->mesh_routelist, wr)
4266 if (memcmp(temp->imroute.imr_dest, wmr->imroute.imr_dest,
4267 IEEE80211_ADDR_LEN) == 0)
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);
4277 SLIST_FOREACH(temp, &wif->mesh_routelist, wr) {
4278 if (memcmp(wmr->imroute.imr_dest, temp->imroute.imr_dest,
4279 IEEE80211_ADDR_LEN) < 0)
4284 SLIST_INSERT_AFTER(prev, wmr, wr);
4289 wlan_mesh_delete_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr)
4291 if (wmr->mroute_status == RowStatus_active &&
4292 wlan_mesh_del_route(wif, wmr) < 0)
4295 SLIST_REMOVE(&wif->mesh_routelist, wmr, wlan_mesh_route, wr);
4302 wlan_mesh_update_routes(void)
4304 struct wlan_iface *wif;
4305 struct wlan_mesh_route *wmr, *twmr;
4307 if ((time(NULL) - wlan_mrlist_age) <= WLAN_LIST_MAXAGE)
4310 for (wif = wlan_mesh_first_interface(); wif != NULL;
4311 wif = wlan_mesh_next_interface(wif)) {
4313 * Nuke old entries - XXX - they are likely not to
4314 * change often - reconsider.
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);
4322 (void)wlan_mesh_get_routelist(wif);
4324 wlan_mrlist_age = time(NULL);
4327 static struct wlan_mesh_route *
4328 wlan_mesh_get_route(const struct asn_oid *oid, uint sub, struct wlan_iface **wif)
4330 char wname[IFNAMSIZ];
4331 char dstmac[IEEE80211_ADDR_LEN];
4333 if (wlan_mac_index_decode(oid, sub, wname, dstmac) < 0)
4336 if ((*wif = wlan_find_interface(wname)) == NULL)
4339 return (wlan_mesh_find_route(*wif, dstmac));
4342 static struct wlan_mesh_route *
4343 wlan_mesh_get_next_route(const struct asn_oid *oid, uint sub,
4344 struct wlan_iface **wif)
4346 char wname[IFNAMSIZ];
4347 char dstmac[IEEE80211_ADDR_LEN];
4348 struct wlan_mesh_route *wmr;
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);
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)
4365 if ((wmr = SLIST_NEXT(wmr, wr)) != NULL)
4368 while ((*wif = wlan_mesh_next_interface(*wif)) != NULL)
4369 if ((wmr = SLIST_FIRST(&(*wif)->mesh_routelist)) != NULL)
4376 wlan_mesh_route_set_status(struct snmp_context *ctx, struct snmp_value *val,
4379 char wname[IFNAMSIZ];
4380 char mac[IEEE80211_ADDR_LEN];
4381 struct wlan_mesh_route *wmr;
4382 struct wlan_iface *wif;
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);
4388 switch (val->v.integer) {
4389 case RowStatus_createAndGo:
4391 return (SNMP_ERR_INCONS_NAME);
4393 case RowStatus_destroy:
4395 return (SNMP_ERR_NOSUCHNAME);
4396 ctx->scratch->int1 = RowStatus_active;
4397 return (SNMP_ERR_NOERROR);
4399 return (SNMP_ERR_INCONS_VALUE);
4402 if ((wif = wlan_find_interface(wname)) == NULL)
4403 return (SNMP_ERR_INCONS_NAME);
4405 if ((wmr = wlan_mesh_new_route(mac)) == NULL)
4406 return (SNMP_ERR_GENERR);
4408 if (wlan_mesh_add_rtentry(wif, wmr) < 0) {
4409 wlan_mesh_free_route(wmr);
4410 return (SNMP_ERR_GENERR);
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);
4419 return (SNMP_ERR_NOERROR);
4423 * Wlan snmp module initialization hook.
4424 * Returns 0 on success, < 0 on error.
4427 wlan_init(struct lmodule * mod __unused, int argc __unused,
4428 char *argv[] __unused)
4430 if (wlan_kmodules_load() < 0)
4433 if (wlan_ioctl_init() < 0)
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",
4447 * Wlan snmp module finalization hook.
4452 mib_unregister_newif(wlan_module);
4453 or_unregister(reg_wlan);
4462 * Refetch all available data from the kernel.
4465 wlan_update_data(void *arg __unused)
4470 * Wlan snmp module start operation.
4477 reg_wlan = or_register(&oid_wlan,
4478 "The MIB module for managing wireless networking.", wlan_module);
4480 /* Add the existing wlan interfaces. */
4481 for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp))
4482 wlan_attach_newif(ifp);
4484 wlan_data_timer = timer_start_repeat(wlan_poll_ticks,
4485 wlan_poll_ticks, wlan_update_data, NULL, wlan_module);
4489 * Dump the Wlan snmp module data on SIGUSR1.
4494 /* XXX: Print some debug info to syslog. */
4495 struct wlan_iface *wif;
4497 for (wif = wlan_first_interface(); wif != NULL;
4498 wif = wlan_next_interface(wif))
4499 syslog(LOG_ERR, "wlan iface %s", wif->wname);
4502 const char wlan_comment[] = \
4503 "This module implements the BEGEMOT MIB for wireless networking.";
4505 const struct snmp_module config = {
4506 .comment = wlan_comment,
4509 .start = wlan_start,
4512 .tree_size = wlan_CTREE_SIZE,