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