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_sys.c
105774 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/ioctl.h>
32
#include <sys/param.h>
33
#include <sys/module.h>
34
#include <sys/linker.h>
35
#include <sys/socket.h>
36
#include <sys/sysctl.h>
37
38
#include <net/if.h>
39
#include <net/if_dl.h>
40
#include <net/if_media.h>
41
#include <net/if_mib.h>
42
#include <net/if_types.h>
43
#include <net80211/ieee80211.h>
44
#include <net80211/ieee80211_ioctl.h>
45
#include <net80211/ieee80211_regdomain.h>
46
47
#include <errno.h>
48
#include <ifaddrs.h>
49
#include <stdarg.h>
50
#include <stdlib.h>
51
#include <stdio.h>
52
#include <string.h>
53
#include <syslog.h>
54
55
#include <bsnmp/snmpmod.h>
56
#include <bsnmp/snmp_mibII.h>
57
58
#define SNMPTREE_TYPES
59
#include "wlan_tree.h"
60
#include "wlan_snmp.h"
61
62
static int sock = -1;
63
64
static int wlan_ioctl(char *, uint16_t, int *, void *, size_t *, int);
65
static int wlan_kmod_load(const char *);
66
static uint32_t wlan_drivercaps_to_snmp(uint32_t);
67
static uint32_t wlan_cryptocaps_to_snmp(uint32_t);
68
static uint32_t wlan_htcaps_to_snmp(uint32_t);
69
static uint32_t wlan_peerstate_to_snmp(uint32_t);
70
static uint32_t wlan_peercaps_to_snmp(uint32_t );
71
static enum WlanIfPhyMode wlan_channel_flags_to_snmp_phy(uint32_t);
72
static enum WlanRegDomainCode wlan_regdomain_to_snmp(int);
73
static uint32_t wlan_snmp_to_scan_flags(int);
74
static int wlan_config_snmp2ioctl(int);
75
static int wlan_snmp_to_regdomain(enum WlanRegDomainCode);
76
static int wlan_config_get_country(struct wlan_iface *);
77
static int wlan_config_set_country(struct wlan_iface *, char *, int);
78
static int wlan_config_get_dchannel(struct wlan_iface *wif);
79
static int wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t);
80
static int wlan_config_get_bssid(struct wlan_iface *);
81
static int wlan_config_set_bssid(struct wlan_iface *, uint8_t *);
82
static void wlan_config_set_snmp_intval(struct wlan_iface *, int, int);
83
static int wlan_config_snmp2value(int, int, int *);
84
static int wlan_config_check(struct wlan_iface *, int);
85
static int wlan_config_get_intval(struct wlan_iface *, int);
86
static int wlan_config_set_intval(struct wlan_iface *, int, int);
87
static int wlan_add_new_scan_result(struct wlan_iface *,
88
const struct ieee80211req_scan_result *, uint8_t *);
89
static int wlan_add_mac_macinfo(struct wlan_iface *,
90
const struct ieee80211req_maclist *);
91
static struct wlan_peer *wlan_add_peerinfo(const struct ieee80211req_sta_info *);
92
93
int
94
wlan_ioctl_init(void)
95
{
96
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
97
syslog(LOG_ERR, "cannot open socket : %s", strerror(errno));
98
return (-1);
99
}
100
101
return (0);
102
}
103
/*
104
* Load the needed modules in kernel if not already there.
105
*/
106
enum wlan_kmodules {
107
WLAN_KMOD = 0,
108
WLAN_KMOD_ACL,
109
WLAN_KMOD_WEP,
110
WLAN_KMODS_MAX
111
};
112
113
static const char *wmod_names[] = {
114
"wlan",
115
"wlan_wlan_acl",
116
"wlan_wep",
117
NULL
118
};
119
120
static int
121
wlan_kmod_load(const char *modname)
122
{
123
int fileid, modid;
124
struct module_stat mstat;
125
126
mstat.version = sizeof(struct module_stat);
127
for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
128
for (modid = kldfirstmod(fileid); modid > 0;
129
modid = modfnext(modid)) {
130
if (modstat(modid, &mstat) < 0)
131
continue;
132
if (strcmp(modname, mstat.name) == 0)
133
return (0);
134
}
135
}
136
137
/* Not present - load it. */
138
if (kldload(modname) < 0) {
139
syslog(LOG_ERR, "failed to load %s kernel module - %s", modname,
140
strerror(errno));
141
return (-1);
142
}
143
144
return (1);
145
}
146
147
int
148
wlan_kmodules_load(void)
149
{
150
if (wlan_kmod_load(wmod_names[WLAN_KMOD]) < 0)
151
return (-1);
152
153
if (wlan_kmod_load(wmod_names[WLAN_KMOD_ACL]) > 0)
154
syslog(LOG_NOTICE, "SNMP wlan loaded %s module",
155
wmod_names[WLAN_KMOD_ACL]);
156
157
if (wlan_kmod_load(wmod_names[WLAN_KMOD_WEP]) > 0)
158
syslog(LOG_NOTICE, "SNMP wlan loaded %s module",
159
wmod_names[WLAN_KMOD_WEP]);
160
161
return (0);
162
}
163
164
/* XXX: FIXME */
165
static int
166
wlan_ioctl(char *wif_name, uint16_t req_type, int *val, void *arg,
167
size_t *argsize, int set)
168
{
169
struct ieee80211req ireq;
170
171
memset(&ireq, 0, sizeof(struct ieee80211req));
172
strlcpy(ireq.i_name, wif_name, IFNAMSIZ);
173
174
ireq.i_type = req_type;
175
ireq.i_val = *val;
176
ireq.i_len = *argsize;
177
ireq.i_data = arg;
178
179
if (ioctl(sock, set ? SIOCS80211 : SIOCG80211, &ireq) < 0) {
180
syslog(LOG_ERR, "iface %s - %s param: ioctl(%d) "
181
"failed: %s", wif_name, set ? "set" : "get",
182
req_type, strerror(errno));
183
return (-1);
184
}
185
186
*argsize = ireq.i_len;
187
*val = ireq.i_val;
188
189
return (0);
190
}
191
192
int
193
wlan_check_media(char *ifname)
194
{
195
struct ifmediareq ifmr;
196
197
memset(&ifmr, 0, sizeof(struct ifmediareq));
198
strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
199
200
if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0 || ifmr.ifm_count == 0)
201
return (0); /* Interface doesn't support SIOCGIFMEDIA. */
202
203
if ((ifmr.ifm_status & IFM_AVALID) == 0)
204
return (0);
205
206
return (IFM_TYPE(ifmr.ifm_active));
207
}
208
209
int
210
wlan_get_opmode(struct wlan_iface *wif)
211
{
212
struct ifmediareq ifmr;
213
214
memset(&ifmr, 0, sizeof(struct ifmediareq));
215
strlcpy(ifmr.ifm_name, wif->wname, sizeof(ifmr.ifm_name));
216
217
if (ioctl(sock, SIOCGIFMEDIA, &ifmr) < 0) {
218
if (errno == ENXIO)
219
return (-1);
220
wif->mode = WlanIfaceOperatingModeType_station;
221
return (0);
222
}
223
224
if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
225
if (ifmr.ifm_current & IFM_FLAG0)
226
wif->mode = WlanIfaceOperatingModeType_adhocDemo;
227
else
228
wif->mode = WlanIfaceOperatingModeType_ibss;
229
} else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
230
wif->mode = WlanIfaceOperatingModeType_hostAp;
231
else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
232
wif->mode = WlanIfaceOperatingModeType_monitor;
233
else if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
234
wif->mode = WlanIfaceOperatingModeType_meshPoint;
235
else if (ifmr.ifm_current & IFM_IEEE80211_WDS)
236
wif->mode = WlanIfaceOperatingModeType_wds;
237
238
return (0);
239
}
240
241
int
242
wlan_config_state(struct wlan_iface *wif, uint8_t set)
243
{
244
int flags;
245
struct ifreq ifr;
246
247
memset(&ifr, 0, sizeof(ifr));
248
strcpy(ifr.ifr_name, wif->wname);
249
250
if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
251
syslog(LOG_ERR, "set %s status: ioctl(SIOCGIFFLAGS) "
252
"failed: %s", wif->wname, strerror(errno));
253
return (-1);
254
}
255
256
if (set == 0) {
257
if ((ifr.ifr_flags & IFF_UP) != 0)
258
wif->state = wlanIfaceState_up;
259
else
260
wif->state = wlanIfaceState_down;
261
return (0);
262
}
263
264
flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
265
266
if (wif->state == wlanIfaceState_up)
267
flags |= IFF_UP;
268
else
269
flags &= ~IFF_UP;
270
271
ifr.ifr_flags = flags & 0xffff;
272
ifr.ifr_flagshigh = flags >> 16;
273
if (ioctl(sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
274
syslog(LOG_ERR, "set %s %s: ioctl(SIOCSIFFLAGS) failed: %s",
275
wif->wname, wif->state == wlanIfaceState_up?"up":"down",
276
strerror(errno));
277
return (-1);
278
}
279
280
return (0);
281
}
282
283
int
284
wlan_get_local_addr(struct wlan_iface *wif)
285
{
286
int len;
287
char ifname[IFNAMSIZ];
288
struct ifaddrs *ifap, *ifa;
289
struct sockaddr_dl sdl;
290
291
if (getifaddrs(&ifap) != 0) {
292
syslog(LOG_ERR, "wlan get mac: getifaddrs() failed - %s",
293
strerror(errno));
294
return (-1);
295
}
296
297
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
298
if (ifa->ifa_addr->sa_family != AF_LINK)
299
continue;
300
memcpy(&sdl, ifa->ifa_addr, sizeof(struct sockaddr_dl));
301
if (sdl.sdl_alen > IEEE80211_ADDR_LEN)
302
continue;
303
if ((len = sdl.sdl_nlen) >= IFNAMSIZ)
304
len = IFNAMSIZ - 1;
305
memcpy(ifname, sdl.sdl_data, len);
306
ifname[len] = '\0';
307
if (strcmp(wif->wname, ifname) == 0)
308
break;
309
}
310
311
freeifaddrs(ifap);
312
return (0);
313
}
314
315
int
316
wlan_get_parent(struct wlan_iface *wif __unused)
317
{
318
/* XXX: There's no way to fetch this from the kernel. */
319
return (0);
320
}
321
322
/* XXX */
323
#define IEEE80211_C_STA 0x00000001 /* CAPABILITY: STA available */
324
#define IEEE80211_C_8023ENCAP 0x00000002 /* CAPABILITY: 802.3 encap */
325
#define IEEE80211_C_FF 0x00000040 /* CAPABILITY: ATH FF avail */
326
#define IEEE80211_C_TURBOP 0x00000080 /* CAPABILITY: ATH Turbo avail*/
327
#define IEEE80211_C_IBSS 0x00000100 /* CAPABILITY: IBSS available */
328
#define IEEE80211_C_PMGT 0x00000200 /* CAPABILITY: Power mgmt */
329
#define IEEE80211_C_HOSTAP 0x00000400 /* CAPABILITY: HOSTAP avail */
330
#define IEEE80211_C_AHDEMO 0x00000800 /* CAPABILITY: Old Adhoc Demo */
331
#define IEEE80211_C_SWRETRY 0x00001000 /* CAPABILITY: sw tx retry */
332
#define IEEE80211_C_TXPMGT 0x00002000 /* CAPABILITY: tx power mgmt */
333
#define IEEE80211_C_SHSLOT 0x00004000 /* CAPABILITY: short slottime */
334
#define IEEE80211_C_SHPREAMBLE 0x00008000 /* CAPABILITY: short preamble */
335
#define IEEE80211_C_MONITOR 0x00010000 /* CAPABILITY: monitor mode */
336
#define IEEE80211_C_DFS 0x00020000 /* CAPABILITY: DFS/radar avail*/
337
#define IEEE80211_C_MBSS 0x00040000 /* CAPABILITY: MBSS available */
338
/* 0x7c0000 available */
339
#define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */
340
#define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */
341
#define IEEE80211_C_WPA 0x01800000 /* CAPABILITY: WPA1+WPA2 avail*/
342
#define IEEE80211_C_BURST 0x02000000 /* CAPABILITY: frame bursting */
343
#define IEEE80211_C_WME 0x04000000 /* CAPABILITY: WME avail */
344
#define IEEE80211_C_WDS 0x08000000 /* CAPABILITY: 4-addr support */
345
/* 0x10000000 reserved */
346
#define IEEE80211_C_BGSCAN 0x20000000 /* CAPABILITY: bg scanning */
347
#define IEEE80211_C_TXFRAG 0x40000000 /* CAPABILITY: tx fragments */
348
#define IEEE80211_C_TDMA 0x80000000 /* CAPABILITY: TDMA avail */
349
350
static uint32_t
351
wlan_drivercaps_to_snmp(uint32_t dcaps)
352
{
353
uint32_t scaps = 0;
354
355
if ((dcaps & IEEE80211_C_STA) != 0)
356
scaps |= (0x1 << WlanDriverCaps_station);
357
if ((dcaps & IEEE80211_C_8023ENCAP) != 0)
358
scaps |= (0x1 << WlanDriverCaps_ieee8023encap);
359
if ((dcaps & IEEE80211_C_FF) != 0)
360
scaps |= (0x1 << WlanDriverCaps_athFastFrames);
361
if ((dcaps & IEEE80211_C_TURBOP) != 0)
362
scaps |= (0x1 << WlanDriverCaps_athTurbo);
363
if ((dcaps & IEEE80211_C_IBSS) != 0)
364
scaps |= (0x1 << WlanDriverCaps_ibss);
365
if ((dcaps & IEEE80211_C_PMGT) != 0)
366
scaps |= (0x1 << WlanDriverCaps_pmgt);
367
if ((dcaps & IEEE80211_C_HOSTAP) != 0)
368
scaps |= (0x1 << WlanDriverCaps_hostAp);
369
if ((dcaps & IEEE80211_C_AHDEMO) != 0)
370
scaps |= (0x1 << WlanDriverCaps_ahDemo);
371
if ((dcaps & IEEE80211_C_SWRETRY) != 0)
372
scaps |= (0x1 << WlanDriverCaps_swRetry);
373
if ((dcaps & IEEE80211_C_TXPMGT) != 0)
374
scaps |= (0x1 << WlanDriverCaps_txPmgt);
375
if ((dcaps & IEEE80211_C_SHSLOT) != 0)
376
scaps |= (0x1 << WlanDriverCaps_shortSlot);
377
if ((dcaps & IEEE80211_C_SHPREAMBLE) != 0)
378
scaps |= (0x1 << WlanDriverCaps_shortPreamble);
379
if ((dcaps & IEEE80211_C_MONITOR) != 0)
380
scaps |= (0x1 << WlanDriverCaps_monitor);
381
if ((dcaps & IEEE80211_C_DFS) != 0)
382
scaps |= (0x1 << WlanDriverCaps_dfs);
383
if ((dcaps & IEEE80211_C_MBSS) != 0)
384
scaps |= (0x1 << WlanDriverCaps_mbss);
385
if ((dcaps & IEEE80211_C_WPA1) != 0)
386
scaps |= (0x1 << WlanDriverCaps_wpa1);
387
if ((dcaps & IEEE80211_C_WPA2) != 0)
388
scaps |= (0x1 << WlanDriverCaps_wpa2);
389
if ((dcaps & IEEE80211_C_BURST) != 0)
390
scaps |= (0x1 << WlanDriverCaps_burst);
391
if ((dcaps & IEEE80211_C_WME) != 0)
392
scaps |= (0x1 << WlanDriverCaps_wme);
393
if ((dcaps & IEEE80211_C_WDS) != 0)
394
scaps |= (0x1 << WlanDriverCaps_wds);
395
if ((dcaps & IEEE80211_C_BGSCAN) != 0)
396
scaps |= (0x1 << WlanDriverCaps_bgScan);
397
if ((dcaps & IEEE80211_C_TXFRAG) != 0)
398
scaps |= (0x1 << WlanDriverCaps_txFrag);
399
if ((dcaps & IEEE80211_C_TDMA) != 0)
400
scaps |= (0x1 << WlanDriverCaps_tdma);
401
402
return (scaps);
403
}
404
405
static uint32_t
406
wlan_cryptocaps_to_snmp(uint32_t ccaps)
407
{
408
uint32_t scaps = 0;
409
410
#if NOT_YET
411
if ((ccaps & IEEE80211_CRYPTO_WEP) != 0)
412
scaps |= (0x1 << wlanCryptoCaps_wep);
413
if ((ccaps & IEEE80211_CRYPTO_TKIP) != 0)
414
scaps |= (0x1 << wlanCryptoCaps_tkip);
415
if ((ccaps & IEEE80211_CRYPTO_AES_OCB) != 0)
416
scaps |= (0x1 << wlanCryptoCaps_aes);
417
if ((ccaps & IEEE80211_CRYPTO_AES_CCM) != 0)
418
scaps |= (0x1 << wlanCryptoCaps_aesCcm);
419
if ((ccaps & IEEE80211_CRYPTO_TKIPMIC) != 0)
420
scaps |= (0x1 << wlanCryptoCaps_tkipMic);
421
if ((ccaps & IEEE80211_CRYPTO_CKIP) != 0)
422
scaps |= (0x1 << wlanCryptoCaps_ckip);
423
#else /* !NOT_YET */
424
scaps = ccaps;
425
#endif
426
return (scaps);
427
}
428
429
#define IEEE80211_HTC_AMPDU 0x00010000 /* CAPABILITY: A-MPDU tx */
430
#define IEEE80211_HTC_AMSDU 0x00020000 /* CAPABILITY: A-MSDU tx */
431
/* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */
432
#define IEEE80211_HTC_HT 0x00040000 /* CAPABILITY: HT operation */
433
#define IEEE80211_HTC_SMPS 0x00080000 /* CAPABILITY: MIMO power save*/
434
#define IEEE80211_HTC_RIFS 0x00100000 /* CAPABILITY: RIFS support */
435
436
static uint32_t
437
wlan_htcaps_to_snmp(uint32_t hcaps)
438
{
439
uint32_t scaps = 0;
440
441
if ((hcaps & IEEE80211_HTCAP_LDPC) != 0)
442
scaps |= (0x1 << WlanHTCaps_ldpc);
443
if ((hcaps & IEEE80211_HTCAP_CHWIDTH40) != 0)
444
scaps |= (0x1 << WlanHTCaps_chwidth40);
445
if ((hcaps & IEEE80211_HTCAP_GREENFIELD) != 0)
446
scaps |= (0x1 << WlanHTCaps_greenField);
447
if ((hcaps & IEEE80211_HTCAP_SHORTGI20) != 0)
448
scaps |= (0x1 << WlanHTCaps_shortGi20);
449
if ((hcaps & IEEE80211_HTCAP_SHORTGI40) != 0)
450
scaps |= (0x1 << WlanHTCaps_shortGi40);
451
if ((hcaps & IEEE80211_HTCAP_TXSTBC) != 0)
452
scaps |= (0x1 << WlanHTCaps_txStbc);
453
if ((hcaps & IEEE80211_HTCAP_DELBA) != 0)
454
scaps |= (0x1 << WlanHTCaps_delba);
455
if ((hcaps & IEEE80211_HTCAP_MAXAMSDU_7935) != 0)
456
scaps |= (0x1 << WlanHTCaps_amsdu7935);
457
if ((hcaps & IEEE80211_HTCAP_DSSSCCK40) != 0)
458
scaps |= (0x1 << WlanHTCaps_dssscck40);
459
if ((hcaps & IEEE80211_HTCAP_PSMP) != 0)
460
scaps |= (0x1 << WlanHTCaps_psmp);
461
if ((hcaps & IEEE80211_HTCAP_40INTOLERANT) != 0)
462
scaps |= (0x1 << WlanHTCaps_fortyMHzIntolerant);
463
if ((hcaps & IEEE80211_HTCAP_LSIGTXOPPROT) != 0)
464
scaps |= (0x1 << WlanHTCaps_lsigTxOpProt);
465
if ((hcaps & IEEE80211_HTC_AMPDU) != 0)
466
scaps |= (0x1 << WlanHTCaps_htcAmpdu);
467
if ((hcaps & IEEE80211_HTC_AMSDU) != 0)
468
scaps |= (0x1 << WlanHTCaps_htcAmsdu);
469
if ((hcaps & IEEE80211_HTC_HT) != 0)
470
scaps |= (0x1 << WlanHTCaps_htcHt);
471
if ((hcaps & IEEE80211_HTC_SMPS) != 0)
472
scaps |= (0x1 << WlanHTCaps_htcSmps);
473
if ((hcaps & IEEE80211_HTC_RIFS) != 0)
474
scaps |= (0x1 << WlanHTCaps_htcRifs);
475
476
return (scaps);
477
}
478
479
/* XXX: Not here? */
480
#define WLAN_SET_TDMA_OPMODE(w) do { \
481
if ((w)->mode == WlanIfaceOperatingModeType_adhocDemo && \
482
((w)->drivercaps & WlanDriverCaps_tdma) != 0) \
483
(w)->mode = WlanIfaceOperatingModeType_tdma; \
484
} while (0)
485
int
486
wlan_get_driver_caps(struct wlan_iface *wif)
487
{
488
int val = 0;
489
size_t argsize;
490
struct ieee80211_devcaps_req dc;
491
492
memset(&dc, 0, sizeof(struct ieee80211_devcaps_req));
493
argsize = sizeof(struct ieee80211_devcaps_req);
494
495
if (wlan_ioctl(wif->wname, IEEE80211_IOC_DEVCAPS, &val, &dc,
496
&argsize, 0) < 0)
497
return (-1);
498
499
wif->drivercaps = wlan_drivercaps_to_snmp(dc.dc_drivercaps);
500
wif->cryptocaps = wlan_cryptocaps_to_snmp(dc.dc_cryptocaps);
501
wif->htcaps = wlan_htcaps_to_snmp(dc.dc_htcaps);
502
503
WLAN_SET_TDMA_OPMODE(wif);
504
505
argsize = dc.dc_chaninfo.ic_nchans * sizeof(struct ieee80211_channel);
506
wif->chanlist = (struct ieee80211_channel *)malloc(argsize);
507
if (wif->chanlist == NULL)
508
return (0);
509
510
memcpy(wif->chanlist, dc.dc_chaninfo.ic_chans, argsize);
511
wif->nchannels = dc.dc_chaninfo.ic_nchans;
512
513
return (0);
514
}
515
516
uint8_t
517
wlan_channel_state_to_snmp(uint8_t cstate)
518
{
519
uint8_t cs = 0;
520
521
if ((cstate & IEEE80211_CHANSTATE_RADAR) != 0)
522
cs |= (0x1 << WlanIfaceChannelStateType_radar);
523
if ((cstate & IEEE80211_CHANSTATE_CACDONE) != 0)
524
cs |= (0x1 << WlanIfaceChannelStateType_cacDone);
525
if ((cstate & IEEE80211_CHANSTATE_CWINT) != 0)
526
cs |= (0x1 << WlanIfaceChannelStateType_interferenceDetected);
527
if ((cstate & IEEE80211_CHANSTATE_NORADAR) != 0)
528
cs |= (0x1 << WlanIfaceChannelStateType_radarClear);
529
530
return (cs);
531
}
532
533
uint32_t
534
wlan_channel_flags_to_snmp(uint32_t cflags)
535
{
536
uint32_t cf = 0;
537
538
if ((cflags & IEEE80211_CHAN_TURBO) != 0)
539
cf |= (0x1 << WlanIfaceChannelFlagsType_turbo);
540
if ((cflags & IEEE80211_CHAN_CCK) != 0)
541
cf |= (0x1 << WlanIfaceChannelFlagsType_cck);
542
if ((cflags & IEEE80211_CHAN_OFDM) != 0)
543
cf |= (0x1 << WlanIfaceChannelFlagsType_ofdm);
544
if ((cflags & IEEE80211_CHAN_2GHZ) != 0)
545
cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum2Ghz);
546
if ((cflags & IEEE80211_CHAN_5GHZ) != 0)
547
cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum5Ghz);
548
if ((cflags & IEEE80211_CHAN_PASSIVE) != 0)
549
cf |= (0x1 << WlanIfaceChannelFlagsType_passiveScan);
550
if ((cflags & IEEE80211_CHAN_DYN) != 0)
551
cf |= (0x1 << WlanIfaceChannelFlagsType_dynamicCckOfdm);
552
if ((cflags & IEEE80211_CHAN_GFSK) != 0)
553
cf |= (0x1 << WlanIfaceChannelFlagsType_gfsk);
554
if ((cflags & IEEE80211_CHAN_GSM) != 0)
555
cf |= (0x1 << WlanIfaceChannelFlagsType_spectrum900Mhz);
556
if ((cflags & IEEE80211_CHAN_STURBO) != 0)
557
cf |= (0x1 << WlanIfaceChannelFlagsType_dot11aStaticTurbo);
558
if ((cflags & IEEE80211_CHAN_HALF) != 0)
559
cf |= (0x1 << WlanIfaceChannelFlagsType_halfRate);
560
if ((cflags & IEEE80211_CHAN_QUARTER) != 0)
561
cf |= (0x1 << WlanIfaceChannelFlagsType_quarterRate);
562
if ((cflags & IEEE80211_CHAN_HT20) != 0)
563
cf |= (0x1 << WlanIfaceChannelFlagsType_ht20);
564
if ((cflags & IEEE80211_CHAN_HT40U) != 0)
565
cf |= (0x1 << WlanIfaceChannelFlagsType_ht40u);
566
if ((cflags & IEEE80211_CHAN_HT40D) != 0)
567
cf |= (0x1 << WlanIfaceChannelFlagsType_ht40d);
568
if ((cflags & IEEE80211_CHAN_DFS) != 0)
569
cf |= (0x1 << WlanIfaceChannelFlagsType_dfs);
570
if ((cflags & IEEE80211_CHAN_4MSXMIT) != 0)
571
cf |= (0x1 << WlanIfaceChannelFlagsType_xmit4ms);
572
if ((cflags & IEEE80211_CHAN_NOADHOC) != 0)
573
cf |= (0x1 << WlanIfaceChannelFlagsType_noAdhoc);
574
if ((cflags & IEEE80211_CHAN_NOHOSTAP) != 0)
575
cf |= (0x1 << WlanIfaceChannelFlagsType_noHostAp);
576
if ((cflags & IEEE80211_CHAN_11D) != 0)
577
cf |= (0x1 << WlanIfaceChannelFlagsType_dot11d);
578
579
return (cf);
580
}
581
582
/* XXX: */
583
#define WLAN_SNMP_MAX_CHANS 256
584
int
585
wlan_get_channel_list(struct wlan_iface *wif)
586
{
587
int val = 0;
588
uint32_t i, nchans;
589
size_t argsize;
590
struct ieee80211req_chaninfo *chaninfo;
591
struct ieee80211req_chanlist active;
592
const struct ieee80211_channel *c;
593
594
argsize = sizeof(struct ieee80211req_chaninfo) +
595
sizeof(struct ieee80211_channel) * WLAN_SNMP_MAX_CHANS;
596
chaninfo = (struct ieee80211req_chaninfo *)malloc(argsize);
597
if (chaninfo == NULL)
598
return (-1);
599
600
if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANINFO, &val, chaninfo,
601
&argsize, 0) < 0)
602
return (-1);
603
604
argsize = sizeof(active);
605
if (wlan_ioctl(wif->wname, IEEE80211_IOC_CHANLIST, &val, &active,
606
&argsize, 0) < 0)
607
goto error;
608
609
for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) {
610
c = &chaninfo->ic_chans[i];
611
if (!isset(active.ic_channels, c->ic_ieee))
612
continue;
613
nchans++;
614
}
615
wif->chanlist = (struct ieee80211_channel *)reallocf(wif->chanlist,
616
nchans * sizeof(*c));
617
if (wif->chanlist == NULL)
618
goto error;
619
wif->nchannels = nchans;
620
for (i = 0, nchans = 0; i < chaninfo->ic_nchans; i++) {
621
c = &chaninfo->ic_chans[i];
622
if (!isset(active.ic_channels, c->ic_ieee))
623
continue;
624
memcpy(wif->chanlist + nchans, c, sizeof (*c));
625
nchans++;
626
}
627
628
free(chaninfo);
629
return (0);
630
error:
631
wif->nchannels = 0;
632
free(chaninfo);
633
return (-1);
634
}
635
636
static enum WlanIfPhyMode
637
wlan_channel_flags_to_snmp_phy(uint32_t cflags)
638
{
639
/* XXX: recheck */
640
if ((cflags & IEEE80211_CHAN_A) != 0)
641
return (WlanIfPhyMode_dot11a);
642
if ((cflags & IEEE80211_CHAN_B) != 0)
643
return (WlanIfPhyMode_dot11b);
644
if ((cflags & IEEE80211_CHAN_G) != 0 ||
645
(cflags & IEEE80211_CHAN_PUREG) != 0)
646
return (WlanIfPhyMode_dot11g);
647
if ((cflags & IEEE80211_CHAN_FHSS) != 0)
648
return (WlanIfPhyMode_fh);
649
if ((cflags & IEEE80211_CHAN_TURBO) != 0 &&
650
(cflags & IEEE80211_CHAN_A) != 0)
651
return (WlanIfPhyMode_turboA);
652
if ((cflags & IEEE80211_CHAN_TURBO) != 0 &&
653
(cflags & IEEE80211_CHAN_G) != 0)
654
return (WlanIfPhyMode_turboG);
655
if ((cflags & IEEE80211_CHAN_STURBO) != 0)
656
return (WlanIfPhyMode_sturboA);
657
if ((cflags & IEEE80211_CHAN_HALF) != 0)
658
return (WlanIfPhyMode_ofdmHalf);
659
if ((cflags & IEEE80211_CHAN_QUARTER) != 0)
660
return (WlanIfPhyMode_ofdmQuarter);
661
662
return (WlanIfPhyMode_auto);
663
}
664
665
int
666
wlan_get_roam_params(struct wlan_iface *wif)
667
{
668
int val = 0;
669
size_t argsize;
670
671
argsize = sizeof(struct ieee80211_roamparams_req);
672
if (wlan_ioctl(wif->wname, IEEE80211_IOC_ROAM, &val,
673
&wif->roamparams, &argsize, 0) < 0)
674
return (-1);
675
676
return (0);
677
}
678
679
int
680
wlan_get_tx_params(struct wlan_iface *wif)
681
{
682
int val = 0;
683
size_t argsize;
684
685
/*
686
* XXX: Reset IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA
687
* and IEEE80211_MODE_11NG modes.
688
*/
689
argsize = sizeof(struct ieee80211_txparams_req);
690
if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val,
691
&wif->txparams, &argsize, 0) < 0)
692
return (-1);
693
694
return (0);
695
}
696
697
int
698
wlan_set_tx_params(struct wlan_iface *wif, int32_t pmode __unused)
699
{
700
int val = 0;
701
size_t argsize;
702
703
/*
704
* XXX: Set IEEE80211_RATE_MCS bit on IEEE80211_MODE_11NA
705
* and IEEE80211_MODE_11NG modes.
706
*/
707
argsize = sizeof(struct ieee80211_txparams_req);
708
if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPARAMS, &val,
709
&wif->txparams, &argsize, 1) < 0)
710
return (-1);
711
712
return (0);
713
}
714
715
int
716
wlan_clone_create(struct wlan_iface *wif)
717
{
718
struct ifreq ifr;
719
struct ieee80211_clone_params wcp;
720
static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
721
722
memset(&wcp, 0, sizeof(wcp));
723
memset(&ifr, 0, sizeof(ifr));
724
725
/* Sanity checks. */
726
if (wif == NULL || wif->pname[0] == '\0' || wif->mode > WLAN_IFMODE_MAX)
727
return (SNMP_ERR_INCONS_VALUE);
728
729
if (wif->mode == WlanIfaceOperatingModeType_wds &&
730
memcmp(wif->dbssid, zerobssid, IEEE80211_ADDR_LEN) == 0)
731
return (SNMP_ERR_INCONS_VALUE);
732
733
strlcpy(wcp.icp_parent, wif->pname, IFNAMSIZ);
734
if ((wif->flags & WlanIfaceFlagsType_uniqueBssid) != 0)
735
wcp.icp_flags |= IEEE80211_CLONE_BSSID;
736
if ((wif->flags & WlanIfaceFlagsType_noBeacons) != 0)
737
wcp.icp_flags |= IEEE80211_CLONE_NOBEACONS;
738
if (wif->mode == WlanIfaceOperatingModeType_wds &&
739
(wif->flags & WlanIfaceFlagsType_wdsLegacy) != 0)
740
wcp.icp_flags |= IEEE80211_CLONE_WDSLEGACY;
741
742
switch (wif->mode) {
743
case WlanIfaceOperatingModeType_ibss:
744
wcp.icp_opmode = IEEE80211_M_IBSS;
745
break;
746
case WlanIfaceOperatingModeType_station:
747
wcp.icp_opmode = IEEE80211_M_STA;
748
break;
749
case WlanIfaceOperatingModeType_wds:
750
wcp.icp_opmode = IEEE80211_M_WDS;
751
break;
752
case WlanIfaceOperatingModeType_adhocDemo:
753
wcp.icp_opmode = IEEE80211_M_AHDEMO;
754
break;
755
case WlanIfaceOperatingModeType_hostAp:
756
wcp.icp_opmode = IEEE80211_M_HOSTAP;
757
break;
758
case WlanIfaceOperatingModeType_monitor:
759
wcp.icp_opmode = IEEE80211_M_MONITOR;
760
break;
761
case WlanIfaceOperatingModeType_meshPoint:
762
wcp.icp_opmode = IEEE80211_M_MBSS;
763
break;
764
case WlanIfaceOperatingModeType_tdma:
765
wcp.icp_opmode = IEEE80211_M_AHDEMO;
766
wcp.icp_flags |= IEEE80211_CLONE_TDMA;
767
break;
768
}
769
770
memcpy(wcp.icp_bssid, wif->dbssid, IEEE80211_ADDR_LEN);
771
if (memcmp(wif->dlmac, zerobssid, IEEE80211_ADDR_LEN) != 0) {
772
memcpy(wcp.icp_macaddr, wif->dlmac, IEEE80211_ADDR_LEN);
773
wcp.icp_flags |= IEEE80211_CLONE_MACADDR;
774
}
775
776
strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ);
777
ifr.ifr_data = (caddr_t) &wcp;
778
779
if (ioctl(sock, SIOCIFCREATE2, (caddr_t) &ifr) < 0) {
780
syslog(LOG_ERR, "wlan clone create: ioctl(SIOCIFCREATE2) "
781
"failed: %s", strerror(errno));
782
return (SNMP_ERR_GENERR);
783
}
784
785
return (SNMP_ERR_NOERROR);
786
}
787
788
int
789
wlan_clone_destroy(struct wlan_iface *wif)
790
{
791
struct ifreq ifr;
792
793
if (wif == NULL)
794
return (SNMP_ERR_INCONS_VALUE);
795
796
memset(&ifr, 0, sizeof(ifr));
797
strcpy(ifr.ifr_name, wif->wname);
798
799
if (ioctl(sock, SIOCIFDESTROY, &ifr) < 0) {
800
syslog(LOG_ERR, "wlan clone destroy: ioctl(SIOCIFDESTROY) "
801
"failed: %s", strerror(errno));
802
return (SNMP_ERR_GENERR);
803
}
804
805
return (SNMP_ERR_NOERROR);
806
}
807
808
static int
809
wlan_config_snmp2ioctl(int which)
810
{
811
int op;
812
813
switch (which) {
814
case LEAF_wlanIfacePacketBurst:
815
op = IEEE80211_IOC_BURST;
816
break;
817
case LEAF_wlanIfaceCountryCode:
818
op = IEEE80211_IOC_REGDOMAIN;
819
break;
820
case LEAF_wlanIfaceRegDomain:
821
op = IEEE80211_IOC_REGDOMAIN;
822
break;
823
case LEAF_wlanIfaceDesiredSsid:
824
op = IEEE80211_IOC_SSID;
825
break;
826
case LEAF_wlanIfaceDesiredChannel:
827
op = IEEE80211_IOC_CURCHAN;
828
break;
829
case LEAF_wlanIfaceDynamicFreqSelection:
830
op = IEEE80211_IOC_DFS;
831
break;
832
case LEAF_wlanIfaceFastFrames:
833
op = IEEE80211_IOC_FF;
834
break;
835
case LEAF_wlanIfaceDturbo:
836
op = IEEE80211_IOC_TURBOP;
837
break;
838
case LEAF_wlanIfaceTxPower:
839
op = IEEE80211_IOC_TXPOWER;
840
break;
841
case LEAF_wlanIfaceFragmentThreshold:
842
op = IEEE80211_IOC_FRAGTHRESHOLD;
843
break;
844
case LEAF_wlanIfaceRTSThreshold:
845
op = IEEE80211_IOC_RTSTHRESHOLD;
846
break;
847
case LEAF_wlanIfaceWlanPrivacySubscribe:
848
op = IEEE80211_IOC_WPS;
849
break;
850
case LEAF_wlanIfaceBgScan:
851
op = IEEE80211_IOC_BGSCAN;
852
break;
853
case LEAF_wlanIfaceBgScanIdle:
854
op = IEEE80211_IOC_BGSCAN_IDLE;
855
break;
856
case LEAF_wlanIfaceBgScanInterval:
857
op = IEEE80211_IOC_BGSCAN_INTERVAL;
858
break;
859
case LEAF_wlanIfaceBeaconMissedThreshold:
860
op = IEEE80211_IOC_BMISSTHRESHOLD;
861
break;
862
case LEAF_wlanIfaceDesiredBssid:
863
op = IEEE80211_IOC_BSSID;
864
break;
865
case LEAF_wlanIfaceRoamingMode:
866
op = IEEE80211_IOC_ROAMING;
867
break;
868
case LEAF_wlanIfaceDot11d:
869
op = IEEE80211_IOC_DOTD;
870
break;
871
case LEAF_wlanIfaceDot11h:
872
op = IEEE80211_IOC_DOTH;
873
break;
874
case LEAF_wlanIfaceDynamicWds:
875
op = IEEE80211_IOC_DWDS;
876
break;
877
case LEAF_wlanIfacePowerSave:
878
op = IEEE80211_IOC_POWERSAVE;
879
break;
880
case LEAF_wlanIfaceApBridge:
881
op = IEEE80211_IOC_APBRIDGE;
882
break;
883
case LEAF_wlanIfaceBeaconInterval:
884
op = IEEE80211_IOC_BEACON_INTERVAL;
885
break;
886
case LEAF_wlanIfaceDtimPeriod:
887
op = IEEE80211_IOC_DTIM_PERIOD;
888
break;
889
case LEAF_wlanIfaceHideSsid:
890
op = IEEE80211_IOC_HIDESSID;
891
break;
892
case LEAF_wlanIfaceInactivityProccess:
893
op = IEEE80211_IOC_INACTIVITY;
894
break;
895
case LEAF_wlanIfaceDot11gProtMode:
896
op = IEEE80211_IOC_PROTMODE;
897
break;
898
case LEAF_wlanIfaceDot11gPureMode:
899
op = IEEE80211_IOC_PUREG;
900
break;
901
case LEAF_wlanIfaceDot11nPureMode:
902
op = IEEE80211_IOC_PUREN;
903
break;
904
case LEAF_wlanIfaceDot11nAmpdu:
905
op = IEEE80211_IOC_AMPDU;
906
break;
907
case LEAF_wlanIfaceDot11nAmpduDensity:
908
op = IEEE80211_IOC_AMPDU_DENSITY;
909
break;
910
case LEAF_wlanIfaceDot11nAmpduLimit:
911
op = IEEE80211_IOC_AMPDU_LIMIT;
912
break;
913
case LEAF_wlanIfaceDot11nAmsdu:
914
op = IEEE80211_IOC_AMSDU;
915
break;
916
case LEAF_wlanIfaceDot11nAmsduLimit:
917
op = IEEE80211_IOC_AMSDU_LIMIT;
918
break;
919
case LEAF_wlanIfaceDot11nHighThroughput:
920
op = IEEE80211_IOC_HTCONF;
921
break;
922
case LEAF_wlanIfaceDot11nHTCompatible:
923
op = IEEE80211_IOC_HTCOMPAT;
924
break;
925
case LEAF_wlanIfaceDot11nHTProtMode:
926
op = IEEE80211_IOC_HTPROTMODE;
927
break;
928
case LEAF_wlanIfaceDot11nRIFS:
929
op = IEEE80211_IOC_RIFS;
930
break;
931
case LEAF_wlanIfaceDot11nShortGI:
932
op = IEEE80211_IOC_SHORTGI;
933
break;
934
case LEAF_wlanIfaceDot11nSMPSMode:
935
op = IEEE80211_IOC_SMPS;
936
break;
937
case LEAF_wlanIfaceTdmaSlot:
938
op = IEEE80211_IOC_TDMA_SLOT;
939
break;
940
case LEAF_wlanIfaceTdmaSlotCount:
941
op = IEEE80211_IOC_TDMA_SLOTCNT;
942
break;
943
case LEAF_wlanIfaceTdmaSlotLength:
944
op = IEEE80211_IOC_TDMA_SLOTLEN;
945
break;
946
case LEAF_wlanIfaceTdmaBeaconInterval:
947
op = IEEE80211_IOC_TDMA_BINTERVAL;
948
break;
949
default:
950
op = -1;
951
}
952
953
return (op);
954
}
955
956
static enum WlanRegDomainCode
957
wlan_regdomain_to_snmp(int which)
958
{
959
enum WlanRegDomainCode reg_domain;
960
961
switch (which) {
962
case SKU_FCC:
963
reg_domain = WlanRegDomainCode_fcc;
964
break;
965
case SKU_CA:
966
reg_domain = WlanRegDomainCode_ca;
967
break;
968
case SKU_ETSI:
969
reg_domain = WlanRegDomainCode_etsi;
970
break;
971
case SKU_ETSI2:
972
reg_domain = WlanRegDomainCode_etsi2;
973
break;
974
case SKU_ETSI3:
975
reg_domain = WlanRegDomainCode_etsi3;
976
break;
977
case SKU_FCC3:
978
reg_domain = WlanRegDomainCode_fcc3;
979
break;
980
case SKU_JAPAN:
981
reg_domain = WlanRegDomainCode_japan;
982
break;
983
case SKU_KOREA:
984
reg_domain = WlanRegDomainCode_korea;
985
break;
986
case SKU_APAC:
987
reg_domain = WlanRegDomainCode_apac;
988
break;
989
case SKU_APAC2:
990
reg_domain = WlanRegDomainCode_apac2;
991
break;
992
case SKU_APAC3:
993
reg_domain = WlanRegDomainCode_apac3;
994
break;
995
case SKU_ROW:
996
reg_domain = WlanRegDomainCode_row;
997
break;
998
case SKU_NONE:
999
reg_domain = WlanRegDomainCode_none;
1000
break;
1001
case SKU_DEBUG:
1002
reg_domain = WlanRegDomainCode_debug;
1003
break;
1004
case SKU_SR9:
1005
reg_domain = WlanRegDomainCode_sr9;
1006
break;
1007
case SKU_XR9:
1008
reg_domain = WlanRegDomainCode_xr9;
1009
break;
1010
case SKU_GZ901:
1011
reg_domain = WlanRegDomainCode_gz901;
1012
break;
1013
case 0:
1014
reg_domain = WlanRegDomainCode_none;
1015
break;
1016
default:
1017
syslog(LOG_ERR, "unknown regdomain (0x%x) ", which);
1018
reg_domain = WlanRegDomainCode_none;
1019
break;
1020
}
1021
1022
return (reg_domain);
1023
}
1024
1025
static int
1026
wlan_snmp_to_regdomain(enum WlanRegDomainCode regdomain)
1027
{
1028
int which;
1029
1030
switch (regdomain) {
1031
case WlanRegDomainCode_fcc:
1032
which = SKU_FCC;
1033
break;
1034
case WlanRegDomainCode_ca:
1035
which = SKU_CA;
1036
break;
1037
case WlanRegDomainCode_etsi:
1038
which = SKU_ETSI;
1039
break;
1040
case WlanRegDomainCode_etsi2:
1041
which = SKU_ETSI2;
1042
break;
1043
case WlanRegDomainCode_etsi3:
1044
which = SKU_ETSI3;
1045
break;
1046
case WlanRegDomainCode_fcc3:
1047
which = SKU_FCC3;
1048
break;
1049
case WlanRegDomainCode_japan:
1050
which = SKU_JAPAN;
1051
break;
1052
case WlanRegDomainCode_korea:
1053
which = SKU_KOREA;
1054
break;
1055
case WlanRegDomainCode_apac:
1056
which = SKU_APAC;
1057
break;
1058
case WlanRegDomainCode_apac2:
1059
which = SKU_APAC2;
1060
break;
1061
case WlanRegDomainCode_apac3:
1062
which = SKU_APAC3;
1063
break;
1064
case WlanRegDomainCode_row:
1065
which = SKU_ROW;
1066
break;
1067
case WlanRegDomainCode_none:
1068
which = SKU_NONE;
1069
break;
1070
case WlanRegDomainCode_debug:
1071
which = SKU_DEBUG;
1072
break;
1073
case WlanRegDomainCode_sr9:
1074
which = SKU_SR9;
1075
break;
1076
case WlanRegDomainCode_xr9:
1077
which = SKU_XR9;
1078
break;
1079
case WlanRegDomainCode_gz901:
1080
which = SKU_GZ901;
1081
break;
1082
default:
1083
syslog(LOG_ERR, "unknown snmp regdomain (0x%x) ", regdomain);
1084
which = SKU_NONE;
1085
break;
1086
}
1087
1088
return (which);
1089
}
1090
1091
static int
1092
wlan_config_get_country(struct wlan_iface *wif)
1093
{
1094
int val = 0;
1095
size_t argsize;
1096
struct ieee80211_regdomain regdomain;
1097
1098
memset(&regdomain, 0, sizeof(regdomain));
1099
argsize = sizeof(regdomain);
1100
1101
if (wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, &regdomain,
1102
&argsize, 0) < 0)
1103
return (-1);
1104
1105
wif->reg_domain = wlan_regdomain_to_snmp(regdomain.regdomain);
1106
wif->country_code[0] = regdomain.isocc[0];
1107
wif->country_code[1] = regdomain.isocc[1];
1108
wif->country_code[2] = regdomain.location;
1109
1110
return (0);
1111
}
1112
1113
static int
1114
wlan_config_set_country(struct wlan_iface *wif, char *ccode, int rdomain)
1115
{
1116
int val = 0, txpowermax;
1117
uint32_t i;
1118
size_t argsize = 0;
1119
struct ieee80211_regdomain_req *regdomain;
1120
1121
if (wlan_get_channel_list(wif) < 0)
1122
return (-1);
1123
1124
if (wif->nchannels == 0) {
1125
syslog(LOG_ERR, "iface %s - set regdomain failed", wif->wname);
1126
return (-1);
1127
}
1128
1129
if (wlan_ioctl(wif->wname, IEEE80211_IOC_TXPOWMAX, &txpowermax, 0,
1130
&argsize, 0) < 0)
1131
return (-1);
1132
1133
regdomain = malloc(IEEE80211_REGDOMAIN_SIZE(wif->nchannels));
1134
if (regdomain == NULL)
1135
return (-1);
1136
memset(regdomain, 0, IEEE80211_REGDOMAIN_SIZE(wif->nchannels));
1137
argsize = IEEE80211_REGDOMAIN_SIZE(wif->nchannels);
1138
1139
/* XXX: recheck with how this is done by ifconfig(8) */
1140
regdomain->rd.regdomain = wlan_snmp_to_regdomain(rdomain);
1141
regdomain->rd.isocc[0] = ccode[0];
1142
regdomain->rd.isocc[1] = ccode[1];
1143
regdomain->rd.location = ccode[2];
1144
1145
/* XXX: fill the channel list properly */
1146
regdomain->chaninfo.ic_nchans = wif->nchannels;
1147
memcpy(regdomain->chaninfo.ic_chans, wif->chanlist,
1148
wif->nchannels * sizeof(struct ieee80211_channel));
1149
for (i = 0; i < wif->nchannels; i++)
1150
regdomain->chaninfo.ic_chans[i].ic_maxregpower = txpowermax;
1151
1152
wif->state = wlanIfaceState_down;
1153
if (wlan_config_state(wif, 1) < 0 ||
1154
wlan_ioctl(wif->wname, IEEE80211_IOC_REGDOMAIN, &val, regdomain,
1155
&argsize, 1) < 0) {
1156
free(regdomain);
1157
return (-1);
1158
}
1159
1160
wif->state = wlanIfaceState_up;
1161
(void)wlan_config_state(wif, 1);
1162
wif->reg_domain = wlan_regdomain_to_snmp(regdomain->rd.regdomain);
1163
wif->country_code[0] = regdomain->rd.isocc[0];
1164
wif->country_code[1] = regdomain->rd.isocc[1];
1165
wif->country_code[2] = regdomain->rd.location;
1166
free(regdomain);
1167
1168
return (0);
1169
}
1170
1171
int
1172
wlan_config_get_dssid(struct wlan_iface *wif)
1173
{
1174
int val = -1;
1175
size_t argsize = IEEE80211_NWID_LEN + 1;
1176
char ssid[IEEE80211_NWID_LEN + 1];
1177
1178
memset(ssid, 0, IEEE80211_NWID_LEN + 1);
1179
1180
if (wlan_ioctl(wif->wname,
1181
(wif->mode == WlanIfaceOperatingModeType_meshPoint) ?
1182
IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid,
1183
&argsize, 0) < 0)
1184
return (-1);
1185
1186
if (argsize > IEEE80211_NWID_LEN)
1187
argsize = IEEE80211_NWID_LEN;
1188
memcpy(wif->desired_ssid, ssid, argsize);
1189
wif->desired_ssid[argsize] = '\0';
1190
1191
return (0);
1192
}
1193
1194
int
1195
wlan_config_set_dssid(struct wlan_iface *wif, char *ssid, int slen)
1196
{
1197
int val = 0;
1198
size_t argsize = slen;
1199
1200
if (wlan_ioctl(wif->wname,
1201
(wif->mode == WlanIfaceOperatingModeType_meshPoint) ?
1202
IEEE80211_IOC_MESH_ID : IEEE80211_IOC_SSID, &val, ssid,
1203
&argsize, 1) < 0)
1204
return (-1);
1205
1206
if (argsize > IEEE80211_NWID_LEN)
1207
argsize = IEEE80211_NWID_LEN;
1208
memcpy(wif->desired_ssid, ssid, argsize);
1209
wif->desired_ssid[argsize] = '\0';
1210
1211
return (0);
1212
}
1213
1214
static int
1215
wlan_config_get_dchannel(struct wlan_iface *wif)
1216
{
1217
uint32_t i = 0;
1218
int val = 0;
1219
size_t argsize = sizeof(struct ieee80211_channel);
1220
struct ieee80211_channel chan;
1221
1222
if (wlan_get_channel_list(wif) < 0)
1223
return (-1);
1224
1225
memset(&chan, 0, sizeof(chan));
1226
if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan,
1227
&argsize, 0) < 0)
1228
return (-1);
1229
1230
for (i = 0; i < wif->nchannels; i++)
1231
if (chan.ic_ieee == wif->chanlist[i].ic_ieee &&
1232
chan.ic_flags == wif->chanlist[i].ic_flags) {
1233
wif->desired_channel = i + 1;
1234
break;
1235
}
1236
1237
return (0);
1238
}
1239
1240
static int
1241
wlan_config_set_dchannel(struct wlan_iface *wif, uint32_t dchannel)
1242
{
1243
int val = 0;
1244
size_t argsize = sizeof(struct ieee80211_channel);
1245
struct ieee80211_channel chan;
1246
1247
if (wlan_get_channel_list(wif) < 0)
1248
return (-1);
1249
1250
if (dchannel > wif->nchannels)
1251
return (-1);
1252
1253
memcpy(&chan, wif->chanlist + dchannel - 1, sizeof(chan));
1254
if (wlan_ioctl(wif->wname, IEEE80211_IOC_CURCHAN, &val, &chan,
1255
&argsize, 1) < 0)
1256
return (-1);
1257
1258
wif->desired_channel = dchannel;
1259
1260
return (0);
1261
}
1262
1263
static int
1264
wlan_config_get_bssid(struct wlan_iface *wif)
1265
{
1266
int val = 0;
1267
size_t argsize = IEEE80211_ADDR_LEN;
1268
char bssid[IEEE80211_ADDR_LEN];
1269
1270
memset(bssid, 0, IEEE80211_ADDR_LEN);
1271
1272
if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid,
1273
&argsize, 0) < 0 || argsize != IEEE80211_ADDR_LEN)
1274
return (-1);
1275
1276
memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN);
1277
1278
return (0);
1279
}
1280
1281
static int
1282
wlan_config_set_bssid(struct wlan_iface *wif, uint8_t *bssid)
1283
{
1284
int val = 0;
1285
size_t argsize = IEEE80211_ADDR_LEN;
1286
1287
if (wlan_ioctl(wif->wname, IEEE80211_IOC_BSSID, &val, bssid,
1288
&argsize, 1) < 0 || argsize != IEEE80211_ADDR_LEN)
1289
return (-1);
1290
1291
memcpy(wif->desired_bssid, bssid, IEEE80211_ADDR_LEN);
1292
1293
return (0);
1294
}
1295
1296
/*
1297
* Convert the value returned by the kernel to the appropriate SNMP
1298
* representation and set the corresponding interface member accordingly.
1299
*/
1300
static void
1301
wlan_config_set_snmp_intval(struct wlan_iface *wif, int op, int val)
1302
{
1303
switch (op) {
1304
case IEEE80211_IOC_BURST:
1305
if (val == 0)
1306
wif->packet_burst = TruthValue_false;
1307
else
1308
wif->packet_burst = TruthValue_true;
1309
break;
1310
case IEEE80211_IOC_DFS:
1311
if (val == 0)
1312
wif->dyn_frequency = TruthValue_false;
1313
else
1314
wif->dyn_frequency = TruthValue_true;
1315
break;
1316
case IEEE80211_IOC_FF:
1317
if (val == 0)
1318
wif->fast_frames = TruthValue_false;
1319
else
1320
wif->fast_frames = TruthValue_true;
1321
break;
1322
case IEEE80211_IOC_TURBOP:
1323
if (val == 0)
1324
wif->dturbo = TruthValue_false;
1325
else
1326
wif->dturbo = TruthValue_true;
1327
break;
1328
case IEEE80211_IOC_TXPOWER:
1329
wif->tx_power = val / 2;
1330
break;
1331
case IEEE80211_IOC_FRAGTHRESHOLD:
1332
wif->frag_threshold = val;
1333
break;
1334
case IEEE80211_IOC_RTSTHRESHOLD:
1335
wif->rts_threshold = val;
1336
break;
1337
case IEEE80211_IOC_WPS:
1338
if (val == 0)
1339
wif->priv_subscribe = TruthValue_false;
1340
else
1341
wif->priv_subscribe = TruthValue_true;
1342
break;
1343
case IEEE80211_IOC_BGSCAN:
1344
if (val == 0)
1345
wif->bg_scan = TruthValue_false;
1346
else
1347
wif->bg_scan = TruthValue_true;
1348
break;
1349
case IEEE80211_IOC_BGSCAN_IDLE:
1350
wif->bg_scan_idle = val;
1351
break;
1352
case IEEE80211_IOC_BGSCAN_INTERVAL:
1353
wif->bg_scan_interval = val;
1354
break;
1355
case IEEE80211_IOC_BMISSTHRESHOLD:
1356
wif->beacons_missed = val;
1357
break;
1358
case IEEE80211_IOC_ROAMING:
1359
switch (val) {
1360
case IEEE80211_ROAMING_DEVICE:
1361
wif->roam_mode = wlanIfaceRoamingMode_device;
1362
break;
1363
case IEEE80211_ROAMING_MANUAL:
1364
wif->roam_mode = wlanIfaceRoamingMode_manual;
1365
break;
1366
case IEEE80211_ROAMING_AUTO:
1367
/* FALTHROUGH */
1368
default:
1369
wif->roam_mode = wlanIfaceRoamingMode_auto;
1370
break;
1371
}
1372
break;
1373
case IEEE80211_IOC_DOTD:
1374
if (val == 0)
1375
wif->dot11d = TruthValue_false;
1376
else
1377
wif->dot11d = TruthValue_true;
1378
break;
1379
case IEEE80211_IOC_DOTH:
1380
if (val == 0)
1381
wif->dot11h = TruthValue_false;
1382
else
1383
wif->dot11h = TruthValue_true;
1384
break;
1385
case IEEE80211_IOC_DWDS:
1386
if (val == 0)
1387
wif->dynamic_wds = TruthValue_false;
1388
else
1389
wif->dynamic_wds = TruthValue_true;
1390
break;
1391
case IEEE80211_IOC_POWERSAVE:
1392
if (val == 0)
1393
wif->power_save = TruthValue_false;
1394
else
1395
wif->power_save = TruthValue_true;
1396
break;
1397
case IEEE80211_IOC_APBRIDGE:
1398
if (val == 0)
1399
wif->ap_bridge = TruthValue_false;
1400
else
1401
wif->ap_bridge = TruthValue_true;
1402
break;
1403
case IEEE80211_IOC_BEACON_INTERVAL:
1404
wif->beacon_interval = val;
1405
break;
1406
case IEEE80211_IOC_DTIM_PERIOD:
1407
wif->dtim_period = val;
1408
break;
1409
case IEEE80211_IOC_HIDESSID:
1410
if (val == 0)
1411
wif->hide_ssid = TruthValue_false;
1412
else
1413
wif->hide_ssid = TruthValue_true;
1414
break;
1415
case IEEE80211_IOC_INACTIVITY:
1416
if (val == 0)
1417
wif->inact_process = TruthValue_false;
1418
else
1419
wif->inact_process = TruthValue_true;
1420
break;
1421
case IEEE80211_IOC_PROTMODE:
1422
switch (val) {
1423
case IEEE80211_PROTMODE_CTS:
1424
wif->do11g_protect = wlanIfaceDot11gProtMode_cts;
1425
break;
1426
case IEEE80211_PROTMODE_RTSCTS:
1427
wif->do11g_protect = wlanIfaceDot11gProtMode_rtscts;
1428
break;
1429
case IEEE80211_PROTMODE_OFF:
1430
/* FALLTHROUGH */
1431
default:
1432
wif->do11g_protect = wlanIfaceDot11gProtMode_off;
1433
break;
1434
}
1435
break;
1436
case IEEE80211_IOC_PUREG:
1437
if (val == 0)
1438
wif->dot11g_pure = TruthValue_false;
1439
else
1440
wif->dot11g_pure = TruthValue_true;
1441
break;
1442
case IEEE80211_IOC_PUREN:
1443
if (val == 0)
1444
wif->dot11n_pure = TruthValue_false;
1445
else
1446
wif->dot11n_pure = TruthValue_true;
1447
break;
1448
case IEEE80211_IOC_AMPDU:
1449
switch (val) {
1450
case 0:
1451
wif->ampdu = WlanIfaceDot11nPduType_disabled;
1452
break;
1453
case 1:
1454
wif->ampdu = WlanIfaceDot11nPduType_txOnly;
1455
break;
1456
case 2:
1457
wif->ampdu = WlanIfaceDot11nPduType_rxOnly;
1458
break;
1459
case 3:
1460
/* FALLTHROUGH */
1461
default:
1462
wif->ampdu = WlanIfaceDot11nPduType_txAndRx;
1463
break;
1464
}
1465
break;
1466
case IEEE80211_IOC_AMPDU_DENSITY:
1467
switch (val) {
1468
case IEEE80211_HTCAP_MPDUDENSITY_025:
1469
wif->ampdu_density = 25;
1470
break;
1471
case IEEE80211_HTCAP_MPDUDENSITY_05:
1472
wif->ampdu_density = 50;
1473
break;
1474
case IEEE80211_HTCAP_MPDUDENSITY_1:
1475
wif->ampdu_density = 100;
1476
break;
1477
case IEEE80211_HTCAP_MPDUDENSITY_2:
1478
wif->ampdu_density = 200;
1479
break;
1480
case IEEE80211_HTCAP_MPDUDENSITY_4:
1481
wif->ampdu_density = 400;
1482
break;
1483
case IEEE80211_HTCAP_MPDUDENSITY_8:
1484
wif->ampdu_density = 800;
1485
break;
1486
case IEEE80211_HTCAP_MPDUDENSITY_16:
1487
wif->ampdu_density = 1600;
1488
break;
1489
case IEEE80211_HTCAP_MPDUDENSITY_NA:
1490
default:
1491
wif->ampdu_density = 0;
1492
break;
1493
}
1494
break;
1495
case IEEE80211_IOC_AMPDU_LIMIT:
1496
switch (val) {
1497
case IEEE80211_HTCAP_MAXRXAMPDU_8K:
1498
wif->ampdu_limit = 8192;
1499
break;
1500
case IEEE80211_HTCAP_MAXRXAMPDU_16K:
1501
wif->ampdu_limit = 16384;
1502
break;
1503
case IEEE80211_HTCAP_MAXRXAMPDU_32K:
1504
wif->ampdu_limit = 32768;
1505
break;
1506
case IEEE80211_HTCAP_MAXRXAMPDU_64K:
1507
default:
1508
wif->ampdu_limit = 65536;
1509
break;
1510
}
1511
break;
1512
case IEEE80211_IOC_AMSDU:
1513
switch (val) {
1514
case 0:
1515
wif->amsdu = WlanIfaceDot11nPduType_disabled;
1516
break;
1517
case 1:
1518
wif->amsdu = WlanIfaceDot11nPduType_txOnly;
1519
break;
1520
case 3:
1521
wif->amsdu = WlanIfaceDot11nPduType_txAndRx;
1522
break;
1523
case 2:
1524
default:
1525
/* FALLTHROUGH */
1526
wif->amsdu = WlanIfaceDot11nPduType_rxOnly;
1527
break;
1528
}
1529
break;
1530
case IEEE80211_IOC_AMSDU_LIMIT:
1531
wif->amsdu_limit = val;
1532
break;
1533
case IEEE80211_IOC_HTCONF:
1534
if (val == 0) /* XXX */
1535
wif->ht_enabled = TruthValue_false;
1536
else
1537
wif->ht_enabled = TruthValue_true;
1538
break;
1539
case IEEE80211_IOC_HTCOMPAT:
1540
if (val == 0)
1541
wif->ht_compatible = TruthValue_false;
1542
else
1543
wif->ht_compatible = TruthValue_true;
1544
break;
1545
case IEEE80211_IOC_HTPROTMODE:
1546
if (val == IEEE80211_PROTMODE_RTSCTS)
1547
wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_rts;
1548
else
1549
wif->ht_prot_mode = wlanIfaceDot11nHTProtMode_off;
1550
break;
1551
case IEEE80211_IOC_RIFS:
1552
if (val == 0)
1553
wif->rifs = TruthValue_false;
1554
else
1555
wif->rifs = TruthValue_true;
1556
break;
1557
case IEEE80211_IOC_SHORTGI:
1558
if (val == 0)
1559
wif->short_gi = TruthValue_false;
1560
else
1561
wif->short_gi = TruthValue_true;
1562
break;
1563
case IEEE80211_IOC_SMPS:
1564
switch (val) {
1565
case IEEE80211_HTCAP_SMPS_DYNAMIC:
1566
wif->smps_mode = wlanIfaceDot11nSMPSMode_dynamic;
1567
break;
1568
case IEEE80211_HTCAP_SMPS_ENA:
1569
wif->smps_mode = wlanIfaceDot11nSMPSMode_static;
1570
break;
1571
case IEEE80211_HTCAP_SMPS_OFF:
1572
/* FALLTHROUGH */
1573
default:
1574
wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled;
1575
break;
1576
}
1577
break;
1578
case IEEE80211_IOC_TDMA_SLOT:
1579
wif->tdma_slot = val;
1580
break;
1581
case IEEE80211_IOC_TDMA_SLOTCNT:
1582
wif->tdma_slot_count = val;
1583
break;
1584
case IEEE80211_IOC_TDMA_SLOTLEN:
1585
wif->tdma_slot_length = val;
1586
break;
1587
case IEEE80211_IOC_TDMA_BINTERVAL:
1588
wif->tdma_binterval = val;
1589
break;
1590
default:
1591
break;
1592
}
1593
}
1594
1595
/*
1596
* Convert an SNMP value to the kernel equivalent and also do sanity check
1597
* for each specific type.
1598
*/
1599
static int
1600
wlan_config_snmp2value(int which, int sval, int *value)
1601
{
1602
*value = 0;
1603
1604
switch (which) {
1605
case IEEE80211_IOC_BURST:
1606
case IEEE80211_IOC_DFS:
1607
case IEEE80211_IOC_FF:
1608
case IEEE80211_IOC_TURBOP:
1609
case IEEE80211_IOC_WPS:
1610
case IEEE80211_IOC_BGSCAN:
1611
case IEEE80211_IOC_DOTD:
1612
case IEEE80211_IOC_DOTH:
1613
case IEEE80211_IOC_DWDS:
1614
case IEEE80211_IOC_POWERSAVE:
1615
case IEEE80211_IOC_APBRIDGE:
1616
case IEEE80211_IOC_HIDESSID:
1617
case IEEE80211_IOC_INACTIVITY:
1618
case IEEE80211_IOC_PUREG:
1619
case IEEE80211_IOC_PUREN:
1620
case IEEE80211_IOC_HTCONF:
1621
case IEEE80211_IOC_HTCOMPAT:
1622
case IEEE80211_IOC_RIFS:
1623
if (sval == TruthValue_true)
1624
*value = 1;
1625
else if (sval != TruthValue_false)
1626
return (SNMP_ERR_INCONS_VALUE);
1627
break;
1628
case IEEE80211_IOC_REGDOMAIN:
1629
break;
1630
case IEEE80211_IOC_SSID:
1631
break;
1632
case IEEE80211_IOC_CURCHAN:
1633
break;
1634
case IEEE80211_IOC_TXPOWER:
1635
*value = sval * 2;
1636
break;
1637
case IEEE80211_IOC_FRAGTHRESHOLD:
1638
if (sval < IEEE80211_FRAG_MIN || sval > IEEE80211_FRAG_MAX)
1639
return (SNMP_ERR_INCONS_VALUE);
1640
*value = sval;
1641
break;
1642
case IEEE80211_IOC_RTSTHRESHOLD:
1643
if (sval < IEEE80211_RTS_MIN || sval > IEEE80211_RTS_MAX)
1644
return (SNMP_ERR_INCONS_VALUE);
1645
*value = sval;
1646
break;
1647
case IEEE80211_IOC_BGSCAN_IDLE:
1648
if (sval < WLAN_BGSCAN_IDLE_MIN)
1649
return (SNMP_ERR_INCONS_VALUE);
1650
*value = sval;
1651
break;
1652
case IEEE80211_IOC_BGSCAN_INTERVAL:
1653
if (sval < WLAN_SCAN_VALID_MIN)
1654
return (SNMP_ERR_INCONS_VALUE);
1655
*value = sval;
1656
break;
1657
case IEEE80211_IOC_BMISSTHRESHOLD:
1658
if (sval < IEEE80211_HWBMISS_MIN || sval > IEEE80211_HWBMISS_MAX)
1659
return (SNMP_ERR_INCONS_VALUE);
1660
*value = sval;
1661
break;
1662
case IEEE80211_IOC_BSSID:
1663
break;
1664
case IEEE80211_IOC_ROAMING:
1665
switch (sval) {
1666
case wlanIfaceRoamingMode_device:
1667
*value = IEEE80211_ROAMING_DEVICE;
1668
break;
1669
case wlanIfaceRoamingMode_manual:
1670
*value = IEEE80211_ROAMING_MANUAL;
1671
break;
1672
case wlanIfaceRoamingMode_auto:
1673
*value = IEEE80211_ROAMING_AUTO;
1674
break;
1675
default:
1676
return (SNMP_ERR_INCONS_VALUE);
1677
}
1678
break;
1679
case IEEE80211_IOC_BEACON_INTERVAL:
1680
if (sval < IEEE80211_BINTVAL_MIN || sval > IEEE80211_BINTVAL_MAX)
1681
return (SNMP_ERR_INCONS_VALUE);
1682
*value = sval;
1683
break;
1684
case IEEE80211_IOC_DTIM_PERIOD:
1685
if (sval < IEEE80211_DTIM_MIN || sval > IEEE80211_DTIM_MAX)
1686
return (SNMP_ERR_INCONS_VALUE);
1687
*value = sval;
1688
break;
1689
case IEEE80211_IOC_PROTMODE:
1690
switch (sval) {
1691
case wlanIfaceDot11gProtMode_cts:
1692
*value = IEEE80211_PROTMODE_CTS;
1693
break;
1694
case wlanIfaceDot11gProtMode_rtscts:
1695
*value = IEEE80211_PROTMODE_RTSCTS;
1696
break;
1697
case wlanIfaceDot11gProtMode_off:
1698
*value = IEEE80211_PROTMODE_OFF;
1699
break;
1700
default:
1701
return (SNMP_ERR_INCONS_VALUE);
1702
}
1703
break;
1704
case IEEE80211_IOC_AMPDU:
1705
switch (sval) {
1706
case WlanIfaceDot11nPduType_disabled:
1707
break;
1708
case WlanIfaceDot11nPduType_txOnly:
1709
*value = 1;
1710
break;
1711
case WlanIfaceDot11nPduType_rxOnly:
1712
*value = 2;
1713
break;
1714
case WlanIfaceDot11nPduType_txAndRx:
1715
*value = 3;
1716
break;
1717
default:
1718
return (SNMP_ERR_INCONS_VALUE);
1719
}
1720
break;
1721
case IEEE80211_IOC_AMPDU_DENSITY:
1722
switch (sval) {
1723
case 0:
1724
*value = IEEE80211_HTCAP_MPDUDENSITY_NA;
1725
break;
1726
case 25:
1727
*value = IEEE80211_HTCAP_MPDUDENSITY_025;
1728
break;
1729
case 50:
1730
*value = IEEE80211_HTCAP_MPDUDENSITY_05;
1731
break;
1732
case 100:
1733
*value = IEEE80211_HTCAP_MPDUDENSITY_1;
1734
break;
1735
case 200:
1736
*value = IEEE80211_HTCAP_MPDUDENSITY_2;
1737
break;
1738
case 400:
1739
*value = IEEE80211_HTCAP_MPDUDENSITY_4;
1740
break;
1741
case 800:
1742
*value = IEEE80211_HTCAP_MPDUDENSITY_8;
1743
break;
1744
case 1600:
1745
*value = IEEE80211_HTCAP_MPDUDENSITY_16;
1746
break;
1747
default:
1748
return (SNMP_ERR_INCONS_VALUE);
1749
}
1750
break;
1751
case IEEE80211_IOC_AMPDU_LIMIT:
1752
switch (sval) {
1753
case 8192:
1754
*value = IEEE80211_HTCAP_MAXRXAMPDU_8K;
1755
break;
1756
case 16384:
1757
*value = IEEE80211_HTCAP_MAXRXAMPDU_16K;
1758
break;
1759
case 32768:
1760
*value = IEEE80211_HTCAP_MAXRXAMPDU_32K;
1761
break;
1762
case 65536:
1763
*value = IEEE80211_HTCAP_MAXRXAMPDU_64K;
1764
break;
1765
default:
1766
return (SNMP_ERR_INCONS_VALUE);
1767
}
1768
break;
1769
case IEEE80211_IOC_AMSDU:
1770
switch (sval) {
1771
case WlanIfaceDot11nPduType_disabled:
1772
break;
1773
case WlanIfaceDot11nPduType_txOnly:
1774
*value = 1;
1775
break;
1776
case WlanIfaceDot11nPduType_rxOnly:
1777
*value = 2;
1778
break;
1779
case WlanIfaceDot11nPduType_txAndRx:
1780
*value = 3;
1781
break;
1782
default:
1783
return (SNMP_ERR_INCONS_VALUE);
1784
}
1785
break;
1786
case IEEE80211_IOC_AMSDU_LIMIT:
1787
if (sval == 3839 || sval == 0)
1788
*value = IEEE80211_HTCAP_MAXAMSDU_3839;
1789
else if (sval == 7935)
1790
*value = IEEE80211_HTCAP_MAXAMSDU_7935;
1791
else
1792
return (SNMP_ERR_INCONS_VALUE);
1793
break;
1794
case IEEE80211_IOC_HTPROTMODE:
1795
switch (sval) {
1796
case wlanIfaceDot11nHTProtMode_rts:
1797
*value = IEEE80211_PROTMODE_RTSCTS;
1798
break;
1799
case wlanIfaceDot11nHTProtMode_off:
1800
break;
1801
default:
1802
return (SNMP_ERR_INCONS_VALUE);
1803
}
1804
break;
1805
case IEEE80211_IOC_SHORTGI:
1806
if (sval == TruthValue_true)
1807
*value = IEEE80211_HTCAP_SHORTGI20 |
1808
IEEE80211_HTCAP_SHORTGI40;
1809
else if (sval != TruthValue_false)
1810
return (SNMP_ERR_INCONS_VALUE);
1811
break;
1812
case IEEE80211_IOC_SMPS:
1813
switch (sval) {
1814
case wlanIfaceDot11nSMPSMode_disabled:
1815
*value = IEEE80211_HTCAP_SMPS_OFF;
1816
break;
1817
case wlanIfaceDot11nSMPSMode_static:
1818
*value = IEEE80211_HTCAP_SMPS_ENA;
1819
break;
1820
case wlanIfaceDot11nSMPSMode_dynamic:
1821
*value = IEEE80211_HTCAP_SMPS_DYNAMIC;
1822
break;
1823
default:
1824
return (SNMP_ERR_INCONS_VALUE);
1825
}
1826
break;
1827
case IEEE80211_IOC_TDMA_SLOT:
1828
if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */
1829
return (SNMP_ERR_INCONS_VALUE);
1830
*value = sval;
1831
break;
1832
case IEEE80211_IOC_TDMA_SLOTCNT:
1833
if (sval < 0 || sval > WLAN_TDMA_MAXSLOTS) /* XXX */
1834
return (SNMP_ERR_INCONS_VALUE);
1835
*value = sval;
1836
break;
1837
case IEEE80211_IOC_TDMA_SLOTLEN:
1838
if (sval < 2*100 || sval > 0xfffff) /* XXX */
1839
return (SNMP_ERR_INCONS_VALUE);
1840
*value = sval;
1841
break;
1842
case IEEE80211_IOC_TDMA_BINTERVAL:
1843
if (sval < 1) /* XXX */
1844
return (SNMP_ERR_INCONS_VALUE);
1845
*value = sval;
1846
break;
1847
default:
1848
return (SNMP_ERR_INCONS_VALUE);
1849
}
1850
1851
return (SNMP_ERR_NOERROR);
1852
}
1853
1854
/*
1855
* Sanity checks for the wlanIfaceConfigTable.
1856
*/
1857
static int
1858
wlan_config_check(struct wlan_iface *wif, int op)
1859
{
1860
switch (op) {
1861
case IEEE80211_IOC_BURST:
1862
if ((wif->drivercaps & (0x1 << WlanDriverCaps_burst)) == 0) {
1863
wif->packet_burst = TruthValue_false;
1864
return (-1);
1865
}
1866
break;
1867
case IEEE80211_IOC_DFS:
1868
if ((wif->drivercaps & (0x1 << WlanDriverCaps_dfs)) == 0) {
1869
wif->dyn_frequency = TruthValue_false;
1870
return (-1);
1871
}
1872
break;
1873
case IEEE80211_IOC_FF:
1874
if ((wif->drivercaps & (0x1 << WlanDriverCaps_athFastFrames))
1875
== 0) {
1876
wif->fast_frames = TruthValue_false;
1877
return (-1);
1878
}
1879
break;
1880
case IEEE80211_IOC_TURBOP:
1881
if ((wif->drivercaps & (0x1 << WlanDriverCaps_athTurbo)) == 0) {
1882
wif->dturbo = TruthValue_false;
1883
return (-1);
1884
}
1885
break;
1886
case IEEE80211_IOC_TXPOWER:
1887
if ((wif->drivercaps & (0x1 << WlanDriverCaps_txPmgt)) == 0) {
1888
wif->tx_power = 0;
1889
return (-1);
1890
}
1891
break;
1892
case IEEE80211_IOC_FRAGTHRESHOLD:
1893
if ((wif->drivercaps & (0x1 << WlanDriverCaps_txFrag)) == 0) {
1894
wif->frag_threshold = IEEE80211_FRAG_MAX;
1895
return (-1);
1896
}
1897
break;
1898
case IEEE80211_IOC_DWDS:
1899
if ((wif->drivercaps & (0x1 << WlanDriverCaps_wds)) == 0) {
1900
wif->dynamic_wds = TruthValue_false;
1901
return (-1);
1902
}
1903
break;
1904
case IEEE80211_IOC_POWERSAVE:
1905
if ((wif->drivercaps & (0x1 << WlanDriverCaps_pmgt)) == 0) {
1906
wif->power_save = TruthValue_false;
1907
return (-1);
1908
}
1909
break;
1910
case IEEE80211_IOC_BEACON_INTERVAL:
1911
if (wif->mode != WlanIfaceOperatingModeType_hostAp &&
1912
wif->mode != WlanIfaceOperatingModeType_meshPoint &&
1913
wif->mode != WlanIfaceOperatingModeType_ibss) {
1914
wif->beacon_interval = 100; /* XXX */
1915
return (-1);
1916
}
1917
break;
1918
case IEEE80211_IOC_DTIM_PERIOD:
1919
if (wif->mode != WlanIfaceOperatingModeType_hostAp &&
1920
wif->mode != WlanIfaceOperatingModeType_meshPoint &&
1921
wif->mode != WlanIfaceOperatingModeType_ibss) {
1922
wif->dtim_period = 1; /* XXX */
1923
return (-1);
1924
}
1925
break;
1926
case IEEE80211_IOC_PUREN:
1927
if ((wif->htcaps & (0x1 << WlanHTCaps_htcHt)) == 0) {
1928
wif->dot11n_pure = TruthValue_false;
1929
return (-1);
1930
}
1931
break;
1932
case IEEE80211_IOC_AMPDU:
1933
if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmpdu)) == 0) {
1934
wif->ampdu = WlanIfaceDot11nPduType_disabled;
1935
return (-1);
1936
}
1937
break;
1938
case IEEE80211_IOC_AMSDU:
1939
if ((wif->htcaps & (0x1 << WlanHTCaps_htcAmsdu)) == 0) {
1940
wif->amsdu = WlanIfaceDot11nPduType_disabled;
1941
return (-1);
1942
}
1943
break;
1944
case IEEE80211_IOC_RIFS:
1945
if ((wif->htcaps & (0x1 << WlanHTCaps_htcRifs)) == 0) {
1946
wif->rifs = TruthValue_false;
1947
return (-1);
1948
}
1949
break;
1950
case IEEE80211_IOC_SHORTGI:
1951
if ((wif->htcaps & (0x1 << WlanHTCaps_shortGi20 |
1952
0x1 << WlanHTCaps_shortGi40)) == 0) {
1953
wif->short_gi = TruthValue_false;
1954
return (-1);
1955
}
1956
break;
1957
case IEEE80211_IOC_SMPS:
1958
if ((wif->htcaps & (0x1 << WlanHTCaps_htcSmps)) == 0) {
1959
wif->smps_mode = wlanIfaceDot11nSMPSMode_disabled;
1960
return (-1);
1961
}
1962
break;
1963
case IEEE80211_IOC_TDMA_SLOT:
1964
if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
1965
wif->tdma_slot = 0;
1966
return (-1);
1967
}
1968
break;
1969
case IEEE80211_IOC_TDMA_SLOTCNT:
1970
if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
1971
wif->tdma_slot_count = 0;
1972
return (-1);
1973
}
1974
break;
1975
case IEEE80211_IOC_TDMA_SLOTLEN:
1976
if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
1977
wif->tdma_slot_length = 0;
1978
return (-1);
1979
}
1980
break;
1981
case IEEE80211_IOC_TDMA_BINTERVAL:
1982
if ((wif->drivercaps & (0x1 << WlanDriverCaps_tdma)) == 0) {
1983
wif->tdma_binterval = 0;
1984
return (-1);
1985
}
1986
break;
1987
default:
1988
break;
1989
}
1990
1991
return (0);
1992
}
1993
1994
static int
1995
wlan_config_get_intval(struct wlan_iface *wif, int op)
1996
{
1997
int val = 0;
1998
size_t argsize = 0;
1999
2000
if (wlan_config_check(wif, op) < 0)
2001
return (0);
2002
if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0)
2003
return (-1);
2004
wlan_config_set_snmp_intval(wif, op, val);
2005
2006
return (0);
2007
}
2008
2009
static int
2010
wlan_config_set_intval(struct wlan_iface *wif, int op, int sval)
2011
{
2012
size_t argsize = 0;
2013
int val;
2014
2015
if (wlan_config_check(wif, op) < 0)
2016
return (-1);
2017
if (wlan_config_snmp2value(op, sval, &val) != SNMP_ERR_NOERROR)
2018
return (-1);
2019
if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0)
2020
return (-1);
2021
wlan_config_set_snmp_intval(wif, op, val);
2022
2023
return (0);
2024
}
2025
2026
int
2027
wlan_config_get_ioctl(struct wlan_iface *wif, int which)
2028
{
2029
int op;
2030
2031
switch (which) {
2032
case LEAF_wlanIfaceCountryCode:
2033
/* FALLTHROUGH */
2034
case LEAF_wlanIfaceRegDomain:
2035
return (wlan_config_get_country(wif));
2036
case LEAF_wlanIfaceDesiredSsid:
2037
return (wlan_config_get_dssid(wif));
2038
case LEAF_wlanIfaceDesiredChannel:
2039
return (wlan_config_get_dchannel(wif));
2040
case LEAF_wlanIfaceDesiredBssid:
2041
return (wlan_config_get_bssid(wif));
2042
default:
2043
op = wlan_config_snmp2ioctl(which);
2044
return (wlan_config_get_intval(wif, op));
2045
}
2046
2047
return (-1);
2048
}
2049
2050
int
2051
wlan_config_set_ioctl(struct wlan_iface *wif, int which, int val,
2052
char *strval, int len)
2053
{
2054
int op;
2055
2056
switch (which) {
2057
case LEAF_wlanIfaceCountryCode:
2058
return (wlan_config_set_country(wif, strval,
2059
wif->reg_domain));
2060
case LEAF_wlanIfaceRegDomain:
2061
return (wlan_config_set_country(wif, wif->country_code,
2062
val));
2063
case LEAF_wlanIfaceDesiredSsid:
2064
return (wlan_config_set_dssid(wif, strval, len));
2065
case LEAF_wlanIfaceDesiredChannel:
2066
return (wlan_config_set_dchannel(wif, val));
2067
case LEAF_wlanIfaceDesiredBssid:
2068
return (wlan_config_set_bssid(wif, strval));
2069
default:
2070
op = wlan_config_snmp2ioctl(which);
2071
return (wlan_config_set_intval(wif, op, val));
2072
}
2073
2074
return (-1);
2075
}
2076
2077
static uint32_t
2078
wlan_snmp_to_scan_flags(int flags)
2079
{
2080
int sr_flags = 0;
2081
2082
if ((flags & (0x1 << WlanScanFlagsType_noSelection)) != 0)
2083
sr_flags |= IEEE80211_IOC_SCAN_NOPICK;
2084
if ((flags & (0x1 << WlanScanFlagsType_activeScan)) != 0)
2085
sr_flags |= IEEE80211_IOC_SCAN_ACTIVE;
2086
if ((flags & (0x1 << WlanScanFlagsType_pickFirst)) != 0)
2087
sr_flags |= IEEE80211_IOC_SCAN_PICK1ST;
2088
if ((flags & (0x1 << WlanScanFlagsType_backgroundScan)) != 0)
2089
sr_flags |= IEEE80211_IOC_SCAN_BGSCAN;
2090
if ((flags & (0x1 << WlanScanFlagsType_once)) != 0)
2091
sr_flags |= IEEE80211_IOC_SCAN_ONCE;
2092
if ((flags & (0x1 << WlanScanFlagsType_noBroadcast)) != 0)
2093
sr_flags |= IEEE80211_IOC_SCAN_NOBCAST;
2094
if ((flags & (0x1 << WlanScanFlagsType_noAutoSequencing)) != 0)
2095
sr_flags |= IEEE80211_IOC_SCAN_NOJOIN;
2096
if ((flags & (0x1 << WlanScanFlagsType_flushCashe)) != 0)
2097
sr_flags |= IEEE80211_IOC_SCAN_FLUSH;
2098
if ((flags & (0x1 << WlanScanFlagsType_chechCashe)) != 0)
2099
sr_flags |= IEEE80211_IOC_SCAN_CHECK;
2100
2101
return (sr_flags);
2102
}
2103
2104
int
2105
wlan_set_scan_config(struct wlan_iface *wif)
2106
{
2107
int val = 0;
2108
size_t argsize;
2109
struct ieee80211_scan_req sr;
2110
2111
2112
memset(&sr, 0, sizeof(sr));
2113
argsize = sizeof(struct ieee80211_scan_req);
2114
sr.sr_flags = wlan_snmp_to_scan_flags(wif->scan_flags);
2115
sr.sr_flags |= IEEE80211_IOC_SCAN_BGSCAN;
2116
sr.sr_duration = wif->scan_duration;
2117
sr.sr_mindwell = wif->scan_mindwell;
2118
sr.sr_maxdwell = wif->scan_maxdwell;
2119
sr.sr_nssid = 0;
2120
2121
if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_REQ,
2122
&val, &sr, &argsize, 1) < 0)
2123
return (-1);
2124
2125
wif->scan_status = wlanScanConfigStatus_running;
2126
return (0);
2127
}
2128
2129
static uint32_t
2130
wlan_peercaps_to_snmp(uint32_t pcaps)
2131
{
2132
uint32_t scaps = 0;
2133
2134
if ((pcaps & IEEE80211_CAPINFO_ESS) != 0)
2135
scaps |= (0x1 << WlanPeerCapabilityFlags_ess);
2136
if ((pcaps & IEEE80211_CAPINFO_IBSS) != 0)
2137
scaps |= (0x1 << WlanPeerCapabilityFlags_ibss);
2138
if ((pcaps & IEEE80211_CAPINFO_CF_POLLABLE) != 0)
2139
scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollable);
2140
if ((pcaps & IEEE80211_CAPINFO_CF_POLLREQ) != 0)
2141
scaps |= (0x1 << WlanPeerCapabilityFlags_cfPollRequest);
2142
if ((pcaps & IEEE80211_CAPINFO_PRIVACY) != 0)
2143
scaps |= (0x1 << WlanPeerCapabilityFlags_privacy);
2144
if ((pcaps & IEEE80211_CAPINFO_SHORT_PREAMBLE) != 0)
2145
scaps |= (0x1 << WlanPeerCapabilityFlags_shortPreamble);
2146
if ((pcaps & IEEE80211_CAPINFO_PBCC) != 0)
2147
scaps |= (0x1 << WlanPeerCapabilityFlags_pbcc);
2148
if ((pcaps & IEEE80211_CAPINFO_CHNL_AGILITY) != 0)
2149
scaps |= (0x1 << WlanPeerCapabilityFlags_channelAgility);
2150
if ((pcaps & IEEE80211_CAPINFO_SHORT_SLOTTIME) != 0)
2151
scaps |= (0x1 << WlanPeerCapabilityFlags_shortSlotTime);
2152
if ((pcaps & IEEE80211_CAPINFO_RSN) != 0)
2153
scaps |= (0x1 << WlanPeerCapabilityFlags_rsn);
2154
if ((pcaps & IEEE80211_CAPINFO_DSSSOFDM) != 0)
2155
scaps |= (0x1 << WlanPeerCapabilityFlags_dsssofdm);
2156
2157
return (scaps);
2158
}
2159
2160
static int
2161
wlan_add_new_scan_result(struct wlan_iface *wif,
2162
const struct ieee80211req_scan_result *isr, uint8_t *ssid)
2163
{
2164
struct wlan_scan_result *sr;
2165
2166
if ((sr = wlan_scan_new_result(ssid, isr->isr_bssid)) == NULL)
2167
return (-1);
2168
2169
sr->opchannel = wlan_channel_flags_to_snmp_phy(isr->isr_flags);
2170
sr->rssi = (isr->isr_rssi / 2) - isr->isr_noise;
2171
sr->frequency = isr->isr_freq;
2172
sr->noise = isr->isr_noise;
2173
sr->bintval = isr->isr_intval;
2174
sr->capinfo = wlan_peercaps_to_snmp(isr->isr_capinfo);
2175
2176
if (wlan_scan_add_result(wif, sr) < 0) {
2177
wlan_scan_free_result(sr);
2178
return (-1);
2179
}
2180
2181
return (0);
2182
}
2183
2184
int
2185
wlan_get_scan_results(struct wlan_iface *wif)
2186
{
2187
int ssidlen, val = 0;
2188
uint8_t buf[24 * 1024];
2189
size_t argsize;
2190
const uint8_t *cp, *idp;
2191
uint8_t ssid[IEEE80211_NWID_LEN + 1];
2192
struct ieee80211req_scan_result isr;
2193
2194
argsize = sizeof(buf);
2195
if (wlan_ioctl(wif->wname, IEEE80211_IOC_SCAN_RESULTS, &val, &buf,
2196
&argsize, 0) < 0)
2197
return (-1);
2198
2199
if (argsize < sizeof(struct ieee80211req_scan_result))
2200
return (0);
2201
2202
cp = buf;
2203
do {
2204
memcpy(&isr, cp, sizeof(struct ieee80211req_scan_result));
2205
memset(ssid, 0, IEEE80211_NWID_LEN + 1);
2206
2207
if (isr.isr_meshid_len) {
2208
idp = cp + isr.isr_ie_off + isr.isr_ssid_len;
2209
ssidlen = isr.isr_meshid_len;
2210
} else {
2211
idp = cp + isr.isr_ie_off;
2212
ssidlen = isr.isr_ssid_len;
2213
}
2214
if (ssidlen > IEEE80211_NWID_LEN)
2215
ssidlen = IEEE80211_NWID_LEN;
2216
memcpy(ssid, idp, ssidlen);
2217
ssid[IEEE80211_NWID_LEN] = '\0';
2218
(void)wlan_add_new_scan_result(wif, &isr, ssid);
2219
cp += isr.isr_len;
2220
argsize -= isr.isr_len;
2221
} while (argsize >= sizeof(struct ieee80211req_scan_result));
2222
2223
return (0);
2224
}
2225
2226
int
2227
wlan_get_stats(struct wlan_iface *wif)
2228
{
2229
struct ifreq ifr;
2230
2231
memset(&ifr, 0, sizeof(struct ifreq));
2232
strlcpy(ifr.ifr_name, wif->wname, IFNAMSIZ);
2233
2234
ifr.ifr_data = (caddr_t) &wif->stats;
2235
2236
if (ioctl(sock, SIOCG80211STATS, &ifr) < 0) {
2237
syslog(LOG_ERR, "iface %s - ioctl(SIOCG80211STATS) failed: %s",
2238
wif->wname, strerror(errno));
2239
return (-1);
2240
}
2241
2242
return (0);
2243
}
2244
2245
int
2246
wlan_get_wepmode(struct wlan_iface *wif)
2247
{
2248
int val = 0;
2249
size_t argsize = 0;
2250
2251
if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL,
2252
&argsize, 0) < 0 || val == IEEE80211_WEP_NOSUP) {
2253
wif->wepsupported = 0; /* XXX */
2254
wif->wepmode = wlanWepMode_off;
2255
wif->weptxkey = 0;
2256
return (-1);
2257
}
2258
2259
wif->wepsupported = 1;
2260
2261
switch (val) {
2262
case IEEE80211_WEP_ON:
2263
wif->wepmode = wlanWepMode_on;
2264
break;
2265
case IEEE80211_WEP_MIXED:
2266
wif->wepmode = wlanWepMode_mixed;
2267
break;
2268
case IEEE80211_WEP_OFF:
2269
/* FALLTHROUGH */
2270
default:
2271
wif->wepmode = wlanWepMode_off;
2272
break;
2273
}
2274
2275
return (0);
2276
}
2277
2278
int
2279
wlan_set_wepmode(struct wlan_iface *wif)
2280
{
2281
int val;
2282
size_t argsize = 0;
2283
2284
if (!wif->wepsupported)
2285
return (-1);
2286
2287
switch (wif->wepmode) {
2288
case wlanWepMode_off:
2289
val = IEEE80211_WEP_OFF;
2290
break;
2291
case wlanWepMode_on:
2292
val = IEEE80211_WEP_ON;
2293
break;
2294
case wlanWepMode_mixed:
2295
val = IEEE80211_WEP_MIXED;
2296
break;
2297
default:
2298
return (-1);
2299
}
2300
2301
if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEP, &val, NULL,
2302
&argsize, 1) < 0)
2303
return (-1);
2304
2305
return (0);
2306
}
2307
2308
int
2309
wlan_get_weptxkey(struct wlan_iface *wif)
2310
{
2311
int val;
2312
size_t argsize = 0;
2313
2314
if (!wif->wepsupported)
2315
return (0);
2316
2317
if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL,
2318
&argsize, 0) < 0)
2319
return (-1);
2320
2321
if (val == IEEE80211_KEYIX_NONE)
2322
wif->weptxkey = 0;
2323
else
2324
wif->weptxkey = val + 1;
2325
2326
return (0);
2327
}
2328
2329
int
2330
wlan_set_weptxkey(struct wlan_iface *wif)
2331
{
2332
int val;
2333
size_t argsize = 0;
2334
2335
if (!wif->wepsupported)
2336
return (0);
2337
2338
if (wif->weptxkey >= IEEE80211_WEP_NKID)
2339
return (-1);
2340
2341
if (wif->weptxkey == 0)
2342
val = IEEE80211_KEYIX_NONE;
2343
else
2344
val = wif->weptxkey - 1;
2345
if (wlan_ioctl(wif->wname, IEEE80211_IOC_WEPTXKEY, &val, NULL,
2346
&argsize, 1) < 0)
2347
return (-1);
2348
2349
return (0);
2350
}
2351
2352
int
2353
wlan_get_wepkeys(struct wlan_iface *wif __unused)
2354
{
2355
/* XXX: should they be visible via SNMP */
2356
return (0);
2357
}
2358
2359
int
2360
wlan_set_wepkeys(struct wlan_iface *wif __unused)
2361
{
2362
/* XXX: should they be configurable via SNMP */
2363
return (0);
2364
}
2365
2366
int
2367
wlan_get_mac_policy(struct wlan_iface *wif)
2368
{
2369
int val = IEEE80211_MACCMD_POLICY;
2370
size_t argsize = 0;
2371
struct ieee80211req ireq;
2372
2373
memset(&ireq, 0, sizeof(struct ieee80211req));
2374
strlcpy(ireq.i_name, wif->wname, IFNAMSIZ);
2375
ireq.i_type = IEEE80211_IOC_MACCMD;
2376
ireq.i_val = IEEE80211_MACCMD_POLICY;
2377
2378
if (ioctl(sock, SIOCG80211, &ireq) < 0) {
2379
if (errno != EINVAL) {
2380
syslog(LOG_ERR, "iface %s - get param: ioctl(%d) "
2381
"failed: %s", wif->wname, ireq.i_type,
2382
strerror(errno));
2383
wif->macsupported = 0;
2384
return (-1);
2385
} else {
2386
wif->macsupported = 1;
2387
wif->mac_policy = wlanMACAccessControlPolicy_open;
2388
return (0);
2389
}
2390
2391
}
2392
2393
wif->macsupported = 1;
2394
2395
switch (val) {
2396
case IEEE80211_MACCMD_POLICY_ALLOW:
2397
wif->mac_policy = wlanMACAccessControlPolicy_allow;
2398
break;
2399
case IEEE80211_MACCMD_POLICY_DENY:
2400
wif->mac_policy = wlanMACAccessControlPolicy_deny;
2401
break;
2402
case IEEE80211_MACCMD_POLICY_RADIUS:
2403
wif->mac_policy = wlanMACAccessControlPolicy_radius;
2404
break;
2405
case IEEE80211_MACCMD_POLICY_OPEN:
2406
/* FALLTHROUGH */
2407
default:
2408
wif->mac_policy = wlanMACAccessControlPolicy_open;
2409
break;
2410
}
2411
2412
argsize = 0;
2413
val = IEEE80211_MACCMD_LIST;
2414
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL,
2415
&argsize, 0) < 0)
2416
return (-1);
2417
2418
wif->mac_nacls = argsize / sizeof(struct ieee80211req_maclist *);
2419
return (0);
2420
}
2421
2422
int
2423
wlan_set_mac_policy(struct wlan_iface *wif)
2424
{
2425
int val;
2426
size_t argsize = 0;
2427
2428
if (!wif->macsupported)
2429
return (-1);
2430
2431
switch (wif->mac_policy) {
2432
case wlanMACAccessControlPolicy_allow:
2433
val = IEEE80211_MACCMD_POLICY_ALLOW;
2434
break;
2435
case wlanMACAccessControlPolicy_deny:
2436
val = IEEE80211_MACCMD_POLICY_DENY;
2437
break;
2438
case wlanMACAccessControlPolicy_radius:
2439
val = IEEE80211_MACCMD_POLICY_RADIUS;
2440
break;
2441
case wlanMACAccessControlPolicy_open:
2442
val = IEEE80211_MACCMD_POLICY_OPEN;
2443
break;
2444
default:
2445
return (-1);
2446
}
2447
2448
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL,
2449
&argsize, 1) < 0)
2450
return (-1);
2451
2452
return (0);
2453
}
2454
2455
int
2456
wlan_flush_mac_mac(struct wlan_iface *wif)
2457
{
2458
int val = IEEE80211_MACCMD_FLUSH;
2459
size_t argsize = 0;
2460
2461
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, NULL,
2462
&argsize, 1) < 0)
2463
return (-1);
2464
2465
return (0);
2466
}
2467
2468
static int
2469
wlan_add_mac_macinfo(struct wlan_iface *wif,
2470
const struct ieee80211req_maclist *ml)
2471
{
2472
struct wlan_mac_mac *mmac;
2473
2474
if ((mmac = wlan_mac_new_mac(ml->ml_macaddr)) == NULL)
2475
return (-1);
2476
2477
mmac->mac_status = RowStatus_active;
2478
if (wlan_mac_add_mac(wif, mmac) < 0) {
2479
wlan_mac_free_mac(mmac);
2480
return (-1);
2481
}
2482
2483
return (0);
2484
}
2485
2486
int
2487
wlan_get_mac_acl_macs(struct wlan_iface *wif)
2488
{
2489
int i, nacls, val = IEEE80211_MACCMD_LIST;
2490
size_t argsize = 0;
2491
uint8_t *data;
2492
struct ieee80211req ireq;
2493
const struct ieee80211req_maclist *acllist;
2494
2495
if (wif->mac_policy == wlanMACAccessControlPolicy_radius) {
2496
wif->mac_nacls = 0;
2497
return (0);
2498
}
2499
2500
memset(&ireq, 0, sizeof(struct ieee80211req));
2501
strlcpy(ireq.i_name, wif->wname, IFNAMSIZ);
2502
ireq.i_type = IEEE80211_IOC_MACCMD;
2503
ireq.i_val = IEEE80211_MACCMD_LIST;
2504
2505
2506
if (ioctl(sock, SIOCG80211, &ireq) < 0) {
2507
if (errno != EINVAL) {
2508
syslog(LOG_ERR, "iface %s - get param: ioctl(%d) "
2509
"failed: %s", wif->wname, ireq.i_type,
2510
strerror(errno));
2511
wif->macsupported = 0;
2512
return (-1);
2513
}
2514
}
2515
2516
if (argsize == 0) {
2517
wif->mac_nacls = 0;
2518
return (0);
2519
}
2520
2521
if ((data = (uint8_t *)malloc(argsize)) == NULL)
2522
return (-1);
2523
2524
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MACCMD, &val, data,
2525
&argsize, 0) < 0)
2526
return (-1);
2527
2528
nacls = argsize / sizeof(*acllist);
2529
acllist = (struct ieee80211req_maclist *) data;
2530
for (i = 0; i < nacls; i++)
2531
(void)wlan_add_mac_macinfo(wif, acllist + i);
2532
2533
wif->mac_nacls = nacls;
2534
return (0);
2535
}
2536
2537
int
2538
wlan_add_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac)
2539
{
2540
int val = 0;
2541
size_t argsize = IEEE80211_ADDR_LEN;
2542
struct ieee80211req_mlme mlme;
2543
2544
if (wlan_ioctl(wif->wname, IEEE80211_IOC_ADDMAC, &val,
2545
mmac->mac, &argsize, 1) < 0)
2546
return (-1);
2547
2548
mmac->mac_status = RowStatus_active;
2549
2550
/* If policy is deny, try to kick the station just in case. */
2551
if (wif->mac_policy != wlanMACAccessControlPolicy_deny)
2552
return (0);
2553
2554
memset(&mlme, 0, sizeof(mlme));
2555
mlme.im_op = IEEE80211_MLME_DEAUTH;
2556
mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE;
2557
memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN);
2558
argsize = sizeof(struct ieee80211req_mlme);
2559
2560
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme,
2561
&argsize, 1) < 0 && errno != ENOENT)
2562
return (-1);
2563
2564
return (0);
2565
}
2566
2567
int
2568
wlan_del_mac_acl_mac(struct wlan_iface *wif, struct wlan_mac_mac *mmac)
2569
{
2570
int val = 0;
2571
size_t argsize = IEEE80211_ADDR_LEN;
2572
struct ieee80211req_mlme mlme;
2573
2574
if (wlan_ioctl(wif->wname, IEEE80211_IOC_DELMAC, &val,
2575
mmac->mac, &argsize, 1) < 0)
2576
return (-1);
2577
2578
mmac->mac_status = RowStatus_active;
2579
2580
/* If policy is allow, try to kick the station just in case. */
2581
if (wif->mac_policy != wlanMACAccessControlPolicy_allow)
2582
return (0);
2583
2584
memset(&mlme, 0, sizeof(mlme));
2585
mlme.im_op = IEEE80211_MLME_DEAUTH;
2586
mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE;
2587
memcpy(mlme.im_macaddr, mmac->mac, IEEE80211_ADDR_LEN);
2588
argsize = sizeof(struct ieee80211req_mlme);
2589
2590
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MLME, &val, &mlme,
2591
&argsize, 1) < 0 && errno != ENOENT)
2592
return (-1);
2593
2594
return (0);
2595
}
2596
2597
int
2598
wlan_peer_set_vlan(struct wlan_iface *wif, struct wlan_peer *wip, int vlan)
2599
{
2600
int val = 0;
2601
size_t argsize;
2602
struct ieee80211req_sta_vlan vreq;
2603
2604
memcpy(vreq.sv_macaddr, wip->pmac, IEEE80211_ADDR_LEN);
2605
vreq.sv_vlan = vlan;
2606
argsize = sizeof(struct ieee80211req_sta_vlan);
2607
2608
if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_VLAN,
2609
&val, &vreq, &argsize, 1) < 0)
2610
return (-1);
2611
2612
wip->vlan = vlan;
2613
2614
return (0);
2615
}
2616
2617
/* XXX */
2618
#ifndef IEEE80211_NODE_AUTH
2619
#define IEEE80211_NODE_AUTH 0x000001 /* authorized for data */
2620
#define IEEE80211_NODE_QOS 0x000002 /* QoS enabled */
2621
#define IEEE80211_NODE_ERP 0x000004 /* ERP enabled */
2622
#define IEEE80211_NODE_PWR_MGT 0x000010 /* power save mode enabled */
2623
#define IEEE80211_NODE_AREF 0x000020 /* authentication ref held */
2624
#define IEEE80211_NODE_HT 0x000040 /* HT enabled */
2625
#define IEEE80211_NODE_HTCOMPAT 0x000080 /* HT setup w/ vendor OUI's */
2626
#define IEEE80211_NODE_WPS 0x000100 /* WPS association */
2627
#define IEEE80211_NODE_TSN 0x000200 /* TSN association */
2628
#define IEEE80211_NODE_AMPDU_RX 0x000400 /* AMPDU rx enabled */
2629
#define IEEE80211_NODE_AMPDU_TX 0x000800 /* AMPDU tx enabled */
2630
#define IEEE80211_NODE_MIMO_PS 0x001000 /* MIMO power save enabled */
2631
#define IEEE80211_NODE_MIMO_RTS 0x002000 /* send RTS in MIMO PS */
2632
#define IEEE80211_NODE_RIFS 0x004000 /* RIFS enabled */
2633
#define IEEE80211_NODE_SGI20 0x008000 /* Short GI in HT20 enabled */
2634
#define IEEE80211_NODE_SGI40 0x010000 /* Short GI in HT40 enabled */
2635
#define IEEE80211_NODE_ASSOCID 0x020000 /* xmit requires associd */
2636
#define IEEE80211_NODE_AMSDU_RX 0x040000 /* AMSDU rx enabled */
2637
#define IEEE80211_NODE_AMSDU_TX 0x080000 /* AMSDU tx enabled */
2638
#endif
2639
2640
static uint32_t
2641
wlan_peerstate_to_snmp(uint32_t pstate)
2642
{
2643
uint32_t sstate = 0;
2644
2645
if ((pstate & IEEE80211_NODE_AUTH) != 0)
2646
sstate |= (0x1 << WlanIfacePeerFlagsType_authorizedForData);
2647
if ((pstate & IEEE80211_NODE_QOS) != 0)
2648
sstate |= (0x1 << WlanIfacePeerFlagsType_qosEnabled);
2649
if ((pstate & IEEE80211_NODE_ERP) != 0)
2650
sstate |= (0x1 << WlanIfacePeerFlagsType_erpEnabled);
2651
if ((pstate & IEEE80211_NODE_PWR_MGT) != 0)
2652
sstate |= (0x1 << WlanIfacePeerFlagsType_powerSaveMode);
2653
if ((pstate & IEEE80211_NODE_AREF) != 0)
2654
sstate |= (0x1 << WlanIfacePeerFlagsType_authRefHeld);
2655
if ((pstate & IEEE80211_NODE_HT) != 0)
2656
sstate |= (0x1 << WlanIfacePeerFlagsType_htEnabled);
2657
if ((pstate & IEEE80211_NODE_HTCOMPAT) != 0)
2658
sstate |= (0x1 << WlanIfacePeerFlagsType_htCompat);
2659
if ((pstate & IEEE80211_NODE_WPS) != 0)
2660
sstate |= (0x1 << WlanIfacePeerFlagsType_wpsAssoc);
2661
if ((pstate & IEEE80211_NODE_TSN) != 0)
2662
sstate |= (0x1 << WlanIfacePeerFlagsType_tsnAssoc);
2663
if ((pstate & IEEE80211_NODE_AMPDU_RX) != 0)
2664
sstate |= (0x1 << WlanIfacePeerFlagsType_ampduRx);
2665
if ((pstate & IEEE80211_NODE_AMPDU_TX) != 0)
2666
sstate |= (0x1 << WlanIfacePeerFlagsType_ampduTx);
2667
if ((pstate & IEEE80211_NODE_MIMO_PS) != 0)
2668
sstate |= (0x1 << WlanIfacePeerFlagsType_mimoPowerSave);
2669
if ((pstate & IEEE80211_NODE_MIMO_RTS) != 0)
2670
sstate |= (0x1 << WlanIfacePeerFlagsType_sendRts);
2671
if ((pstate & IEEE80211_NODE_RIFS) != 0)
2672
sstate |= (0x1 << WlanIfacePeerFlagsType_rifs);
2673
if ((pstate & IEEE80211_NODE_SGI20) != 0)
2674
sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT20);
2675
if ((pstate & IEEE80211_NODE_SGI40) != 0)
2676
sstate |= (0x1 << WlanIfacePeerFlagsType_shortGiHT40);
2677
if ((pstate & IEEE80211_NODE_AMSDU_RX) != 0)
2678
sstate |= (0x1 << WlanIfacePeerFlagsType_amsduRx);
2679
if ((pstate & IEEE80211_NODE_AMSDU_TX) != 0)
2680
sstate |= (0x1 << WlanIfacePeerFlagsType_amsduTx);
2681
2682
return (sstate);
2683
}
2684
2685
static struct wlan_peer *
2686
wlan_add_peerinfo(const struct ieee80211req_sta_info *si)
2687
{
2688
struct wlan_peer *wip;
2689
2690
if ((wip = wlan_new_peer(si->isi_macaddr))== NULL)
2691
return (NULL);
2692
2693
wip->associd = IEEE80211_AID(si->isi_associd);
2694
wip->vlan = si->isi_vlan;
2695
wip->frequency = si->isi_freq;
2696
wip->fflags = si->isi_flags;
2697
wip->txrate = si->isi_txrate;
2698
wip->rssi = si->isi_rssi;
2699
wip->idle = si->isi_inact;
2700
wip->txseqs = si->isi_txseqs[0]; /* XXX */
2701
wip->rxseqs = si->isi_rxseqs[0]; /* XXX */
2702
wip->txpower = si->isi_txpower;
2703
wip->capinfo = wlan_peercaps_to_snmp(si->isi_capinfo);
2704
wip->state = wlan_peerstate_to_snmp(si->isi_state);
2705
wip->local_id = si->isi_localid;
2706
wip->peer_id = si->isi_peerid;
2707
2708
return (wip);
2709
}
2710
2711
int
2712
wlan_get_peerinfo(struct wlan_iface *wif)
2713
{
2714
union {
2715
struct ieee80211req_sta_req req;
2716
uint8_t buf[24 * 1024];
2717
} u;
2718
const uint8_t *cp;
2719
int val = 0;
2720
size_t len;
2721
struct ieee80211req_sta_info si;
2722
struct wlan_peer *wip;
2723
2724
/* Get all stations - broadcast address */
2725
(void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN);
2726
len = sizeof(u);
2727
2728
if (wlan_ioctl(wif->wname, IEEE80211_IOC_STA_INFO,
2729
& val, &u, &len, 0) < 0)
2730
return (-1);
2731
2732
if (len < sizeof(struct ieee80211req_sta_info))
2733
return (-1);
2734
2735
cp = (const uint8_t *) u.req.info;
2736
do {
2737
memcpy(&si, cp, sizeof(struct ieee80211req_sta_info));
2738
if ((wip = wlan_add_peerinfo(&si)) != NULL &&
2739
wlan_add_peer(wif, wip) < 0)
2740
wlan_free_peer(wip);
2741
cp += si.isi_len, len -= si.isi_len;
2742
} while (len >= sizeof(struct ieee80211req_sta_info));
2743
2744
return (0);
2745
}
2746
2747
/************************************************************************
2748
* Wireless MESH & HWMP sysctl config.
2749
*/
2750
const char wlan_sysctl_name[] = "net.wlan.";
2751
2752
static const char *wlan_sysctl[] = {
2753
"mesh.retrytimeout",
2754
"mesh.holdingtimeout",
2755
"mesh.confirmtimeout",
2756
"mesh.maxretries",
2757
"hwmp.targetonly",
2758
"hwmp.replyforward",
2759
"hwmp.pathlifetime",
2760
"hwmp.roottimeout",
2761
"hwmp.rootint",
2762
"hwmp.rannint",
2763
"hwmp.inact",
2764
};
2765
2766
int32_t
2767
wlan_do_sysctl(struct wlan_config *cfg, enum wlan_syscl which, int set)
2768
{
2769
char mib_name[100];
2770
int val, sval;
2771
size_t len, vlen;
2772
2773
if (set) {
2774
vlen = sizeof(sval);
2775
switch (which) {
2776
case WLAN_MESH_RETRY_TO:
2777
sval = cfg->mesh_retryto;
2778
break;
2779
case WLAN_MESH_HOLDING_TO:
2780
sval = cfg->mesh_holdingto;
2781
break;
2782
case WLAN_MESH_CONFIRM_TO:
2783
sval = cfg->mesh_confirmto;
2784
break;
2785
case WLAN_MESH_MAX_RETRIES:
2786
sval = cfg->mesh_maxretries;
2787
break;
2788
case WLAN_HWMP_TARGET_ONLY:
2789
sval = cfg->hwmp_targetonly;
2790
break;
2791
case WLAN_HWMP_REPLY_FORWARD:
2792
sval = cfg->hwmp_replyforward;
2793
break;
2794
case WLAN_HWMP_PATH_LIFETIME:
2795
sval = cfg->hwmp_pathlifetime;
2796
break;
2797
case WLAN_HWMP_ROOT_TO:
2798
sval = cfg->hwmp_roottimeout;
2799
break;
2800
case WLAN_HWMP_ROOT_INT:
2801
sval = cfg->hwmp_rootint;
2802
break;
2803
case WLAN_HWMP_RANN_INT:
2804
sval = cfg->hwmp_rannint;
2805
break;
2806
case WLAN_HWMP_INACTIVITY_TO:
2807
sval = cfg->hwmp_inact;
2808
break;
2809
default:
2810
return (-1);
2811
}
2812
} else {
2813
if (which >= WLAN_SYSCTL_MAX)
2814
return (-1);
2815
vlen = 0;
2816
}
2817
2818
strlcpy(mib_name, wlan_sysctl_name, sizeof(mib_name));
2819
strlcat(mib_name, wlan_sysctl[which], sizeof(mib_name));
2820
len = sizeof (val);
2821
2822
if (sysctlbyname(mib_name, &val, &len, (set? &sval : NULL), vlen) < 0) {
2823
syslog(LOG_ERR, "sysctl(%s) failed - %s", mib_name,
2824
strerror(errno));
2825
return (-1);
2826
}
2827
2828
switch (which) {
2829
case WLAN_MESH_RETRY_TO:
2830
cfg->mesh_retryto = val;
2831
break;
2832
case WLAN_MESH_HOLDING_TO:
2833
cfg->mesh_holdingto = val;
2834
break;
2835
case WLAN_MESH_CONFIRM_TO:
2836
cfg->mesh_confirmto = val;
2837
break;
2838
case WLAN_MESH_MAX_RETRIES:
2839
cfg->mesh_maxretries = val;
2840
break;
2841
case WLAN_HWMP_TARGET_ONLY:
2842
cfg->hwmp_targetonly = val;
2843
break;
2844
case WLAN_HWMP_REPLY_FORWARD:
2845
cfg->hwmp_replyforward = val;
2846
break;
2847
case WLAN_HWMP_PATH_LIFETIME:
2848
cfg->hwmp_pathlifetime = val;
2849
break;
2850
case WLAN_HWMP_ROOT_TO:
2851
cfg->hwmp_roottimeout = val;
2852
break;
2853
case WLAN_HWMP_ROOT_INT:
2854
cfg->hwmp_rootint = val;
2855
break;
2856
case WLAN_HWMP_RANN_INT:
2857
cfg->hwmp_rannint = val;
2858
break;
2859
case WLAN_HWMP_INACTIVITY_TO:
2860
cfg->hwmp_inact = val;
2861
break;
2862
default:
2863
/* NOTREACHED */
2864
abort();
2865
}
2866
2867
return (0);
2868
}
2869
2870
int
2871
wlan_mesh_config_get(struct wlan_iface *wif, int which)
2872
{
2873
int op, val = 0;
2874
size_t argsize = 0;
2875
uint8_t data[32], *pd = NULL;
2876
2877
switch (which) {
2878
case LEAF_wlanMeshTTL:
2879
op = IEEE80211_IOC_MESH_TTL;
2880
break;
2881
case LEAF_wlanMeshPeeringEnabled:
2882
op = IEEE80211_IOC_MESH_AP;
2883
break;
2884
case LEAF_wlanMeshForwardingEnabled:
2885
op = IEEE80211_IOC_MESH_FWRD;
2886
break;
2887
case LEAF_wlanMeshMetric:
2888
op = IEEE80211_IOC_MESH_PR_METRIC;
2889
pd = data;
2890
argsize = sizeof(data);
2891
break;
2892
case LEAF_wlanMeshPath:
2893
op = IEEE80211_IOC_MESH_PR_PATH;
2894
pd = data;
2895
argsize = sizeof(data);
2896
break;
2897
case LEAF_wlanMeshRoutesFlush:
2898
return (0);
2899
default:
2900
return (-1);
2901
}
2902
2903
if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 0) < 0)
2904
return (-1);
2905
2906
switch (which) {
2907
case LEAF_wlanMeshTTL:
2908
wif->mesh_ttl = val;
2909
break;
2910
case LEAF_wlanMeshPeeringEnabled:
2911
if (val)
2912
wif->mesh_peering = wlanMeshPeeringEnabled_true;
2913
else
2914
wif->mesh_peering = wlanMeshPeeringEnabled_false;
2915
break;
2916
case LEAF_wlanMeshForwardingEnabled:
2917
if (val)
2918
wif->mesh_forwarding = wlanMeshForwardingEnabled_true;
2919
else
2920
wif->mesh_forwarding = wlanMeshForwardingEnabled_false;
2921
break;
2922
case LEAF_wlanMeshMetric:
2923
data[argsize] = '\0';
2924
if (strcmp(data, "AIRTIME") == 0)
2925
wif->mesh_metric = wlanMeshMetric_airtime;
2926
else
2927
wif->mesh_metric = wlanMeshMetric_unknown;
2928
break;
2929
case LEAF_wlanMeshPath:
2930
data[argsize] = '\0';
2931
if (strcmp(data, "HWMP") == 0)
2932
wif->mesh_path = wlanMeshPath_hwmp;
2933
else
2934
wif->mesh_path = wlanMeshPath_unknown;
2935
}
2936
2937
return (0);
2938
}
2939
2940
int
2941
wlan_mesh_config_set(struct wlan_iface *wif, int which)
2942
{
2943
int op, val = 0;
2944
size_t argsize = 0;
2945
uint8_t data[32], *pd = NULL;
2946
2947
switch (which) {
2948
case LEAF_wlanMeshTTL:
2949
op = IEEE80211_IOC_MESH_TTL;
2950
val = wif->mesh_ttl;
2951
break;
2952
case LEAF_wlanMeshPeeringEnabled:
2953
op = IEEE80211_IOC_MESH_AP;
2954
if (wif->mesh_peering == wlanMeshPeeringEnabled_true)
2955
val = 1;
2956
break;
2957
case LEAF_wlanMeshForwardingEnabled:
2958
if (wif->mesh_forwarding == wlanMeshForwardingEnabled_true)
2959
val = 1;
2960
op = IEEE80211_IOC_MESH_FWRD;
2961
break;
2962
case LEAF_wlanMeshMetric:
2963
op = IEEE80211_IOC_MESH_PR_METRIC;
2964
if (wif->mesh_metric == wlanMeshMetric_airtime)
2965
strcpy(data, "AIRTIME");
2966
else
2967
return (-1);
2968
pd = data;
2969
argsize = sizeof(data);
2970
break;
2971
case LEAF_wlanMeshPath:
2972
op = IEEE80211_IOC_MESH_PR_PATH;
2973
if (wif->mesh_path == wlanMeshPath_hwmp)
2974
strcpy(data, "HWMP");
2975
else
2976
return (-1);
2977
pd = data;
2978
argsize = sizeof(data);
2979
break;
2980
default:
2981
return (-1);
2982
}
2983
2984
if (wlan_ioctl(wif->wname, op, &val, pd, &argsize, 1) < 0)
2985
return (-1);
2986
2987
return(0);
2988
}
2989
2990
int
2991
wlan_mesh_flush_routes(struct wlan_iface *wif)
2992
{
2993
int val = IEEE80211_MESH_RTCMD_FLUSH;
2994
size_t argsize = 0;
2995
2996
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, NULL,
2997
&argsize, 1) < 0)
2998
return (-1);
2999
3000
return (0);
3001
}
3002
3003
int
3004
wlan_mesh_add_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr)
3005
{
3006
int val = IEEE80211_MESH_RTCMD_ADD;
3007
size_t argsize = IEEE80211_ADDR_LEN;
3008
3009
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val,
3010
wmr->imroute.imr_dest, &argsize, 1) < 0)
3011
return (-1);
3012
3013
wmr->mroute_status = RowStatus_active;
3014
3015
return (0);
3016
}
3017
3018
int
3019
wlan_mesh_del_route(struct wlan_iface *wif, struct wlan_mesh_route *wmr)
3020
{
3021
int val = IEEE80211_MESH_RTCMD_DELETE;
3022
size_t argsize = IEEE80211_ADDR_LEN;
3023
3024
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val,
3025
wmr->imroute.imr_dest, &argsize, 1) < 0)
3026
return (-1);
3027
3028
wmr->mroute_status = RowStatus_destroy;
3029
3030
return (0);
3031
}
3032
3033
int
3034
wlan_mesh_get_routelist(struct wlan_iface *wif)
3035
{
3036
int i, nroutes, val = IEEE80211_MESH_RTCMD_LIST;
3037
size_t argsize;
3038
struct ieee80211req_mesh_route routes[128];
3039
struct ieee80211req_mesh_route *rt;
3040
struct wlan_mesh_route *wmr;
3041
3042
argsize = sizeof(routes);
3043
if (wlan_ioctl(wif->wname, IEEE80211_IOC_MESH_RTCMD, &val, routes,
3044
&argsize, 0) < 0) /* XXX: ENOMEM? */
3045
return (-1);
3046
3047
nroutes = argsize / sizeof(*rt);
3048
for (i = 0; i < nroutes; i++) {
3049
rt = routes + i;
3050
if ((wmr = wlan_mesh_new_route(rt->imr_dest)) == NULL)
3051
return (-1);
3052
memcpy(&wmr->imroute, rt, sizeof(*rt));
3053
wmr->mroute_status = RowStatus_active;
3054
if (wlan_mesh_add_rtentry(wif, wmr) < 0)
3055
wlan_mesh_free_route(wmr);
3056
}
3057
3058
return (0);
3059
}
3060
3061
int
3062
wlan_hwmp_config_get(struct wlan_iface *wif, int which)
3063
{
3064
int op, val = 0;
3065
size_t argsize = 0;
3066
3067
switch (which) {
3068
case LEAF_wlanHWMPRootMode:
3069
op = IEEE80211_IOC_HWMP_ROOTMODE;
3070
break;
3071
case LEAF_wlanHWMPMaxHops:
3072
op = IEEE80211_IOC_HWMP_MAXHOPS;
3073
break;
3074
default:
3075
return (-1);
3076
}
3077
3078
if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 0) < 0)
3079
return (-1);
3080
3081
switch (which) {
3082
case LEAF_wlanHWMPRootMode:
3083
switch (val) {
3084
case IEEE80211_HWMP_ROOTMODE_NORMAL:
3085
wif->hwmp_root_mode = wlanHWMPRootMode_normal;
3086
break;
3087
case IEEE80211_HWMP_ROOTMODE_PROACTIVE:
3088
wif->hwmp_root_mode = wlanHWMPRootMode_proactive;
3089
break;
3090
case IEEE80211_HWMP_ROOTMODE_RANN:
3091
wif->hwmp_root_mode = wlanHWMPRootMode_rann;
3092
break;
3093
case IEEE80211_HWMP_ROOTMODE_DISABLED:
3094
default:
3095
wif->hwmp_root_mode = wlanHWMPRootMode_disabled;
3096
break;
3097
}
3098
break;
3099
case LEAF_wlanHWMPMaxHops:
3100
wif->hwmp_max_hops = val;
3101
break;
3102
}
3103
3104
return (0);
3105
}
3106
3107
int
3108
wlan_hwmp_config_set(struct wlan_iface *wif, int which)
3109
{
3110
int op, val = 0;
3111
size_t argsize = 0;
3112
3113
switch (which) {
3114
case LEAF_wlanHWMPRootMode:
3115
op = IEEE80211_IOC_HWMP_ROOTMODE;
3116
switch (wif->hwmp_root_mode) {
3117
case wlanHWMPRootMode_disabled:
3118
val = IEEE80211_HWMP_ROOTMODE_DISABLED;
3119
break;
3120
case wlanHWMPRootMode_normal:
3121
val = IEEE80211_HWMP_ROOTMODE_NORMAL;
3122
break;
3123
case wlanHWMPRootMode_proactive:
3124
val = IEEE80211_HWMP_ROOTMODE_PROACTIVE;
3125
break;
3126
case wlanHWMPRootMode_rann:
3127
val = IEEE80211_HWMP_ROOTMODE_RANN;
3128
break;
3129
default:
3130
return (-1);
3131
}
3132
break;
3133
case LEAF_wlanHWMPMaxHops:
3134
op = IEEE80211_IOC_HWMP_MAXHOPS;
3135
val = wif->hwmp_max_hops;
3136
break;
3137
default:
3138
return (-1);
3139
}
3140
3141
if (wlan_ioctl(wif->wname, op, &val, NULL, &argsize, 1) < 0)
3142
return (-1);
3143
3144
return (0);
3145
}
3146
3147