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