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