Deleted Added
full compact
ifieee80211.c (170588) ifieee80211.c (173275)
1/*
2 * Copyright 2001 The Aerospace Corporation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
1/*
2 * Copyright 2001 The Aerospace Corporation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sbin/ifconfig/ifieee80211.c 170588 2007-06-12 00:52:40Z thompsa $
27 * $FreeBSD: head/sbin/ifconfig/ifieee80211.c 173275 2007-11-02 05:24:57Z sam $
28 */
29
30/*-
31 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
32 * All rights reserved.
33 *
34 * This code is derived from software contributed to The NetBSD Foundation
35 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,

--- 50 unchanged lines hidden (view full) ---

86#include <errno.h>
87#include <fcntl.h>
88#include <inttypes.h>
89#include <stdio.h>
90#include <stdlib.h>
91#include <string.h>
92#include <unistd.h>
93#include <stdarg.h>
28 */
29
30/*-
31 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
32 * All rights reserved.
33 *
34 * This code is derived from software contributed to The NetBSD Foundation
35 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,

--- 50 unchanged lines hidden (view full) ---

86#include <errno.h>
87#include <fcntl.h>
88#include <inttypes.h>
89#include <stdio.h>
90#include <stdlib.h>
91#include <string.h>
92#include <unistd.h>
93#include <stdarg.h>
94#include <stddef.h> /* NB: for offsetof */
94
95#include "ifconfig.h"
96
95
96#include "ifconfig.h"
97
98#define MAXCOL 78
99static int col;
100static char spacer;
101
102static void LINE_INIT(char c);
103static void LINE_BREAK(void);
104static void LINE_CHECK(const char *fmt, ...);
105
106/* XXX need max array size */
107static const int htrates[16] = {
108 13, /* IFM_IEEE80211_MCS0 */
109 26, /* IFM_IEEE80211_MCS1 */
110 39, /* IFM_IEEE80211_MCS2 */
111 52, /* IFM_IEEE80211_MCS3 */
112 78, /* IFM_IEEE80211_MCS4 */
113 104, /* IFM_IEEE80211_MCS5 */
114 117, /* IFM_IEEE80211_MCS6 */
115 130, /* IFM_IEEE80211_MCS7 */
116 26, /* IFM_IEEE80211_MCS8 */
117 52, /* IFM_IEEE80211_MCS9 */
118 78, /* IFM_IEEE80211_MCS10 */
119 104, /* IFM_IEEE80211_MCS11 */
120 156, /* IFM_IEEE80211_MCS12 */
121 208, /* IFM_IEEE80211_MCS13 */
122 234, /* IFM_IEEE80211_MCS14 */
123 260, /* IFM_IEEE80211_MCS15 */
124};
125
126static int get80211(int s, int type, void *data, int len);
127static int get80211len(int s, int type, void *data, int len, int *plen);
128static int get80211val(int s, int type, int *val);
97static void set80211(int s, int type, int val, int len, void *data);
98static const char *get_string(const char *val, const char *sep,
99 u_int8_t *buf, int *lenp);
100static void print_string(const u_int8_t *buf, int len);
101
102static struct ieee80211req_chaninfo chaninfo;
103static struct ifmediareq *ifmr;
129static void set80211(int s, int type, int val, int len, void *data);
130static const char *get_string(const char *val, const char *sep,
131 u_int8_t *buf, int *lenp);
132static void print_string(const u_int8_t *buf, int len);
133
134static struct ieee80211req_chaninfo chaninfo;
135static struct ifmediareq *ifmr;
136static struct ieee80211_channel curchan;
137static int gotcurchan = 0;
138static int htconf = 0;
139static int gothtconf = 0;
104
140
141static void
142gethtconf(int s)
143{
144 if (gothtconf)
145 return;
146 if (get80211val(s, IEEE80211_IOC_HTCONF, &htconf) < 0)
147 warn("unable to get HT configuration information");
148 gothtconf = 1;
149}
150
105/*
106 * Collect channel info from the kernel. We use this (mostly)
107 * to handle mapping between frequency and IEEE channel number.
108 */
109static void
110getchaninfo(int s)
111{
151/*
152 * Collect channel info from the kernel. We use this (mostly)
153 * to handle mapping between frequency and IEEE channel number.
154 */
155static void
156getchaninfo(int s)
157{
112 struct ieee80211req ireq;
113
114 if (chaninfo.ic_nchans != 0)
115 return;
158 if (chaninfo.ic_nchans != 0)
159 return;
116 (void) memset(&ireq, 0, sizeof(ireq));
117 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
118 ireq.i_type = IEEE80211_IOC_CHANINFO;
119 ireq.i_data = &chaninfo;
120 ireq.i_len = sizeof(chaninfo);
121 if (ioctl(s, SIOCG80211, &ireq) < 0)
160 if (get80211(s, IEEE80211_IOC_CHANINFO, &chaninfo, sizeof(chaninfo)) < 0)
122 errx(1, "unable to get channel information");
123
124 ifmr = ifmedia_getstate(s);
161 errx(1, "unable to get channel information");
162
163 ifmr = ifmedia_getstate(s);
164 gethtconf(s);
125}
126
127/*
128 * Given the channel at index i with attributes from,
129 * check if there is a channel with attributes to in
130 * the channel table. With suitable attributes this
131 * allows the caller to look for promotion; e.g. from
132 * 11b > 11g.

--- 50 unchanged lines hidden (view full) ---

183 * the ifmedia_getstate call ourselves.
184 */
185 int chanmode = ifmr != NULL ? IFM_MODE(ifmr->ifm_current) : IFM_AUTO;
186
187 /* when ambiguous promote to ``best'' */
188 /* NB: we abitrarily pick HT40+ over HT40- */
189 if (chanmode != IFM_IEEE80211_11B)
190 i = canpromote(i, IEEE80211_CHAN_B, IEEE80211_CHAN_G);
165}
166
167/*
168 * Given the channel at index i with attributes from,
169 * check if there is a channel with attributes to in
170 * the channel table. With suitable attributes this
171 * allows the caller to look for promotion; e.g. from
172 * 11b > 11g.

--- 50 unchanged lines hidden (view full) ---

223 * the ifmedia_getstate call ourselves.
224 */
225 int chanmode = ifmr != NULL ? IFM_MODE(ifmr->ifm_current) : IFM_AUTO;
226
227 /* when ambiguous promote to ``best'' */
228 /* NB: we abitrarily pick HT40+ over HT40- */
229 if (chanmode != IFM_IEEE80211_11B)
230 i = canpromote(i, IEEE80211_CHAN_B, IEEE80211_CHAN_G);
191 if (chanmode != IFM_IEEE80211_11G) {
231 if (chanmode != IFM_IEEE80211_11G && (htconf & 1)) {
192 i = canpromote(i, IEEE80211_CHAN_G,
193 IEEE80211_CHAN_G | IEEE80211_CHAN_HT20);
232 i = canpromote(i, IEEE80211_CHAN_G,
233 IEEE80211_CHAN_G | IEEE80211_CHAN_HT20);
194 i = canpromote(i, IEEE80211_CHAN_G,
195 IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D);
196 i = canpromote(i, IEEE80211_CHAN_G,
197 IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U);
234 if (htconf & 2) {
235 i = canpromote(i, IEEE80211_CHAN_G,
236 IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D);
237 i = canpromote(i, IEEE80211_CHAN_G,
238 IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U);
239 }
198 }
240 }
199 if (chanmode != IFM_IEEE80211_11A) {
241 if (chanmode != IFM_IEEE80211_11A && (htconf & 1)) {
200 i = canpromote(i, IEEE80211_CHAN_A,
201 IEEE80211_CHAN_A | IEEE80211_CHAN_HT20);
242 i = canpromote(i, IEEE80211_CHAN_A,
243 IEEE80211_CHAN_A | IEEE80211_CHAN_HT20);
202 i = canpromote(i, IEEE80211_CHAN_A,
203 IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D);
204 i = canpromote(i, IEEE80211_CHAN_A,
205 IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U);
244 if (htconf & 2) {
245 i = canpromote(i, IEEE80211_CHAN_A,
246 IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D);
247 i = canpromote(i, IEEE80211_CHAN_A,
248 IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U);
249 }
206 }
207 return i;
208}
209
210static void
211mapfreq(struct ieee80211_channel *chan, int freq, int flags)
212{
213 int i;

--- 25 unchanged lines hidden (view full) ---

239 if (flags == 0) {
240 /* when ambiguous promote to ``best'' */
241 c = &chaninfo.ic_chans[promote(i)];
242 }
243 *chan = *c;
244 return;
245 }
246 }
250 }
251 return i;
252}
253
254static void
255mapfreq(struct ieee80211_channel *chan, int freq, int flags)
256{
257 int i;

--- 25 unchanged lines hidden (view full) ---

283 if (flags == 0) {
284 /* when ambiguous promote to ``best'' */
285 c = &chaninfo.ic_chans[promote(i)];
286 }
287 *chan = *c;
288 return;
289 }
290 }
247 errx(1, "unknown/undefined channel number %d", ieee);
291 errx(1, "unknown/undefined channel number %d flags 0x%x", ieee, flags);
248}
249
292}
293
294static const struct ieee80211_channel *
295getcurchan(int s)
296{
297 if (gotcurchan)
298 return &curchan;
299 if (get80211(s, IEEE80211_IOC_CURCHAN, &curchan, sizeof(curchan)) < 0) {
300 int val;
301 /* fall back to legacy ioctl */
302 if (get80211val(s, IEEE80211_IOC_CHANNEL, &val) < 0)
303 errx(-1, "cannot figure out current channel");
304 getchaninfo(s);
305 mapchan(&curchan, val, 0);
306 }
307 gotcurchan = 1;
308 return &curchan;
309}
310
250static int
251ieee80211_mhz2ieee(int freq, int flags)
252{
253 struct ieee80211_channel chan;
254 mapfreq(&chan, freq, flags);
255 return chan.ic_ieee;
256}
257
258static int
259isanyarg(const char *arg)
260{
311static int
312ieee80211_mhz2ieee(int freq, int flags)
313{
314 struct ieee80211_channel chan;
315 mapfreq(&chan, freq, flags);
316 return chan.ic_ieee;
317}
318
319static int
320isanyarg(const char *arg)
321{
261 return (strcmp(arg, "-") == 0 ||
262 strcasecmp(arg, "any") == 0 || strcasecmp(arg, "off") == 0);
322 return (strncmp(arg, "-", 1) == 0 ||
323 strncasecmp(arg, "any", 3) == 0 || strncasecmp(arg, "off", 3) == 0);
263}
264
265static void
266set80211ssid(const char *val, int d, int s, const struct afswtch *rafp)
267{
268 int ssid;
269 int len;
270 u_int8_t data[IEEE80211_NWID_LEN];

--- 34 unchanged lines hidden (view full) ---

305 *
306 * These can be combined in either order; e.g. 2437:ng/40.
307 * Modes are case insensitive.
308 *
309 * The result is not validated here; it's assumed to be
310 * checked against the channel table fetched from the kernel.
311 */
312static int
324}
325
326static void
327set80211ssid(const char *val, int d, int s, const struct afswtch *rafp)
328{
329 int ssid;
330 int len;
331 u_int8_t data[IEEE80211_NWID_LEN];

--- 34 unchanged lines hidden (view full) ---

366 *
367 * These can be combined in either order; e.g. 2437:ng/40.
368 * Modes are case insensitive.
369 *
370 * The result is not validated here; it's assumed to be
371 * checked against the channel table fetched from the kernel.
372 */
373static int
313getchannelflags(const char *val)
374getchannelflags(const char *val, int freq)
314{
375{
315#define CHAN_HT_DEFAULT IEEE80211_CHAN_HT40U
316#define _CHAN_HT 0x80000000
317 const char *cp;
318 int flags;
319
320 flags = 0;
321
322 cp = strchr(val, ':');
323 if (cp != NULL) {

--- 23 unchanged lines hidden (view full) ---

347 /* dt and unadorned t specify Dynamic Turbo */
348 if ((flags & (IEEE80211_CHAN_STURBO|_CHAN_HT)) == 0)
349 flags |= IEEE80211_CHAN_TURBO;
350 break;
351 case 's': /* st = Atheros Static Turbo */
352 flags |= IEEE80211_CHAN_STURBO;
353 break;
354 default:
376#define _CHAN_HT 0x80000000
377 const char *cp;
378 int flags;
379
380 flags = 0;
381
382 cp = strchr(val, ':');
383 if (cp != NULL) {

--- 23 unchanged lines hidden (view full) ---

407 /* dt and unadorned t specify Dynamic Turbo */
408 if ((flags & (IEEE80211_CHAN_STURBO|_CHAN_HT)) == 0)
409 flags |= IEEE80211_CHAN_TURBO;
410 break;
411 case 's': /* st = Atheros Static Turbo */
412 flags |= IEEE80211_CHAN_STURBO;
413 break;
414 default:
355 errx(-1, "%s: Invalid channel attribute %c",
415 errx(-1, "%s: Invalid channel attribute %c\n",
356 val, *cp);
357 }
358 }
359 }
360 cp = strchr(val, '/');
361 if (cp != NULL) {
362 char *ep;
363 u_long cw = strtoul(cp+1, &ep, 10);

--- 9 unchanged lines hidden (view full) ---

373 /* NB: this may be removed below */
374 flags |= IEEE80211_CHAN_HT20;
375 break;
376 case 40:
377 if (ep != NULL && *ep == '+')
378 flags |= IEEE80211_CHAN_HT40U;
379 else if (ep != NULL && *ep == '-')
380 flags |= IEEE80211_CHAN_HT40D;
416 val, *cp);
417 }
418 }
419 }
420 cp = strchr(val, '/');
421 if (cp != NULL) {
422 char *ep;
423 u_long cw = strtoul(cp+1, &ep, 10);

--- 9 unchanged lines hidden (view full) ---

433 /* NB: this may be removed below */
434 flags |= IEEE80211_CHAN_HT20;
435 break;
436 case 40:
437 if (ep != NULL && *ep == '+')
438 flags |= IEEE80211_CHAN_HT40U;
439 else if (ep != NULL && *ep == '-')
440 flags |= IEEE80211_CHAN_HT40D;
381 else /* NB: pick something */
382 flags |= CHAN_HT_DEFAULT;
383 break;
384 default:
441 break;
442 default:
385 errx(-1, "%s: Invalid channel width", val);
443 errx(-1, "%s: Invalid channel width\n", val);
386 }
387 }
388 /*
389 * Cleanup specifications.
390 */
391 if ((flags & _CHAN_HT) == 0) {
392 /*
393 * If user specified freq/20 or freq/40 quietly remove

--- 5 unchanged lines hidden (view full) ---

399 flags &= ~IEEE80211_CHAN_HT;
400 } else {
401 /*
402 * Remove private indicator that this is an HT channel
403 * and if no explicit channel width has been given
404 * provide the default settings.
405 */
406 flags &= ~_CHAN_HT;
444 }
445 }
446 /*
447 * Cleanup specifications.
448 */
449 if ((flags & _CHAN_HT) == 0) {
450 /*
451 * If user specified freq/20 or freq/40 quietly remove

--- 5 unchanged lines hidden (view full) ---

457 flags &= ~IEEE80211_CHAN_HT;
458 } else {
459 /*
460 * Remove private indicator that this is an HT channel
461 * and if no explicit channel width has been given
462 * provide the default settings.
463 */
464 flags &= ~_CHAN_HT;
407 if ((flags & IEEE80211_CHAN_HT) == 0)
408 flags |= CHAN_HT_DEFAULT;
465 if ((flags & IEEE80211_CHAN_HT) == 0) {
466 struct ieee80211_channel chan;
467 /*
468 * Consult the channel list to see if we can use
469 * HT40+ or HT40- (if both the map routines choose).
470 */
471 if (freq > 255)
472 mapfreq(&chan, freq, 0);
473 else
474 mapchan(&chan, freq, 0);
475 flags |= (chan.ic_flags & IEEE80211_CHAN_HT);
476 }
409 }
410 return flags;
477 }
478 return flags;
411#undef CHAN_HT_DEFAULT
412#undef _CHAN_HT
413}
414
415static void
416set80211channel(const char *val, int d, int s, const struct afswtch *rafp)
417{
418 struct ieee80211_channel chan;
419
420 memset(&chan, 0, sizeof(chan));
421 if (!isanyarg(val)) {
479#undef _CHAN_HT
480}
481
482static void
483set80211channel(const char *val, int d, int s, const struct afswtch *rafp)
484{
485 struct ieee80211_channel chan;
486
487 memset(&chan, 0, sizeof(chan));
488 if (!isanyarg(val)) {
422 int v = atoi(val);
423 int flags = getchannelflags(val);
489 int v, flags;
424
425 getchaninfo(s);
490
491 getchaninfo(s);
492 v = atoi(val);
493 flags = getchannelflags(val, v);
426 if (v > 255) { /* treat as frequency */
427 mapfreq(&chan, v, flags);
428 } else {
429 mapchan(&chan, v, flags);
430 }
431 } else {
432 chan.ic_freq = IEEE80211_CHAN_ANY;
433 }

--- 173 unchanged lines hidden (view full) ---

607set80211protmode(const char *val, int d, int s, const struct afswtch *rafp)
608{
609 int mode;
610
611 if (strcasecmp(val, "off") == 0) {
612 mode = IEEE80211_PROTMODE_OFF;
613 } else if (strcasecmp(val, "cts") == 0) {
614 mode = IEEE80211_PROTMODE_CTS;
494 if (v > 255) { /* treat as frequency */
495 mapfreq(&chan, v, flags);
496 } else {
497 mapchan(&chan, v, flags);
498 }
499 } else {
500 chan.ic_freq = IEEE80211_CHAN_ANY;
501 }

--- 173 unchanged lines hidden (view full) ---

675set80211protmode(const char *val, int d, int s, const struct afswtch *rafp)
676{
677 int mode;
678
679 if (strcasecmp(val, "off") == 0) {
680 mode = IEEE80211_PROTMODE_OFF;
681 } else if (strcasecmp(val, "cts") == 0) {
682 mode = IEEE80211_PROTMODE_CTS;
615 } else if (strcasecmp(val, "rtscts") == 0) {
683 } else if (strncasecmp(val, "rtscts", 3) == 0) {
616 mode = IEEE80211_PROTMODE_RTSCTS;
617 } else {
618 errx(1, "unknown protection mode");
619 }
620
621 set80211(s, IEEE80211_IOC_PROTMODE, mode, 0, NULL);
622}
623
624static void
684 mode = IEEE80211_PROTMODE_RTSCTS;
685 } else {
686 errx(1, "unknown protection mode");
687 }
688
689 set80211(s, IEEE80211_IOC_PROTMODE, mode, 0, NULL);
690}
691
692static void
693set80211htprotmode(const char *val, int d, int s, const struct afswtch *rafp)
694{
695 int mode;
696
697 if (strcasecmp(val, "off") == 0) {
698 mode = IEEE80211_PROTMODE_OFF;
699 } else if (strncasecmp(val, "rts", 3) == 0) {
700 mode = IEEE80211_PROTMODE_RTSCTS;
701 } else {
702 errx(1, "unknown protection mode");
703 }
704
705 set80211(s, IEEE80211_IOC_HTPROTMODE, mode, 0, NULL);
706}
707
708static void
625set80211txpower(const char *val, int d, int s, const struct afswtch *rafp)
626{
709set80211txpower(const char *val, int d, int s, const struct afswtch *rafp)
710{
627 set80211(s, IEEE80211_IOC_TXPOWER, atoi(val), 0, NULL);
711 double v = atof(val);
712 int txpow;
713
714 txpow = (int) (2*v);
715 if (txpow != 2*v)
716 errx(-1, "invalid tx power (must be .5 dBm units)");
717 set80211(s, IEEE80211_IOC_TXPOWER, txpow, 0, NULL);
628}
629
630#define IEEE80211_ROAMING_DEVICE 0
631#define IEEE80211_ROAMING_AUTO 1
632#define IEEE80211_ROAMING_MANUAL 2
633
634static void
635set80211roaming(const char *val, int d, int s, const struct afswtch *rafp)

--- 51 unchanged lines hidden (view full) ---

687
688 temp = malloc(strlen(val) + 1);
689 if (temp == NULL)
690 errx(1, "malloc failed");
691 strcpy(temp, val);
692 memset(&chanlist, 0, sizeof(chanlist));
693 cp = temp;
694 for (;;) {
718}
719
720#define IEEE80211_ROAMING_DEVICE 0
721#define IEEE80211_ROAMING_AUTO 1
722#define IEEE80211_ROAMING_MANUAL 2
723
724static void
725set80211roaming(const char *val, int d, int s, const struct afswtch *rafp)

--- 51 unchanged lines hidden (view full) ---

777
778 temp = malloc(strlen(val) + 1);
779 if (temp == NULL)
780 errx(1, "malloc failed");
781 strcpy(temp, val);
782 memset(&chanlist, 0, sizeof(chanlist));
783 cp = temp;
784 for (;;) {
695 int first, last, f;
785 int first, last, f, c;
696
697 tp = strchr(cp, ',');
698 if (tp != NULL)
699 *tp++ = '\0';
700 switch (sscanf(cp, "%u-%u", &first, &last)) {
701 case 1:
702 if (first > MAXCHAN)
703 errx(-1, "channel %u out of range, max %zu",

--- 11 unchanged lines hidden (view full) ---

715 errx(-1, "void channel range, %u > %u",
716 first, last);
717 for (f = first; f <= last; f++)
718 setbit(chanlist.ic_channels, f);
719 break;
720 }
721 if (tp == NULL)
722 break;
786
787 tp = strchr(cp, ',');
788 if (tp != NULL)
789 *tp++ = '\0';
790 switch (sscanf(cp, "%u-%u", &first, &last)) {
791 case 1:
792 if (first > MAXCHAN)
793 errx(-1, "channel %u out of range, max %zu",

--- 11 unchanged lines hidden (view full) ---

805 errx(-1, "void channel range, %u > %u",
806 first, last);
807 for (f = first; f <= last; f++)
808 setbit(chanlist.ic_channels, f);
809 break;
810 }
811 if (tp == NULL)
812 break;
723 while (isspace(*tp))
813 c = *tp;
814 while (isspace(c))
724 tp++;
815 tp++;
725 if (!isdigit(*tp))
816 if (!isdigit(c))
726 break;
727 cp = tp;
728 }
729 set80211(s, IEEE80211_IOC_CHANLIST, 0, sizeof(chanlist), &chanlist);
730#undef MAXCHAN
731}
732
733static void

--- 278 unchanged lines hidden (view full) ---

1012}
1013
1014static void
1015set80211doth(const char *val, int d, int s, const struct afswtch *rafp)
1016{
1017 set80211(s, IEEE80211_IOC_DOTH, d, 0, NULL);
1018}
1019
817 break;
818 cp = tp;
819 }
820 set80211(s, IEEE80211_IOC_CHANLIST, 0, sizeof(chanlist), &chanlist);
821#undef MAXCHAN
822}
823
824static void

--- 278 unchanged lines hidden (view full) ---

1103}
1104
1105static void
1106set80211doth(const char *val, int d, int s, const struct afswtch *rafp)
1107{
1108 set80211(s, IEEE80211_IOC_DOTH, d, 0, NULL);
1109}
1110
1111static void
1112set80211shortgi(const char *val, int d, int s, const struct afswtch *rafp)
1113{
1114 set80211(s, IEEE80211_IOC_SHORTGI,
1115 d ? (IEEE80211_HTCAP_SHORTGI20 | IEEE80211_HTCAP_SHORTGI40) : 0,
1116 0, NULL);
1117}
1118
1119static void
1120set80211ampdu(const char *val, int d, int s, const struct afswtch *rafp)
1121{
1122 int ampdu;
1123
1124 if (get80211val(s, IEEE80211_IOC_AMPDU, &ampdu) < 0)
1125 errx(-1, "cannot get AMPDU setting");
1126 if (d < 0) {
1127 d = -d;
1128 ampdu &= ~d;
1129 } else
1130 ampdu |= d;
1131 set80211(s, IEEE80211_IOC_AMPDU, ampdu, 0, NULL);
1132}
1133
1134static
1135DECL_CMD_FUNC(set80211ampdulimit, val, d)
1136{
1137 int v;
1138
1139 switch (atoi(val)) {
1140 case 8:
1141 case 8*1024:
1142 v = IEEE80211_HTCAP_MAXRXAMPDU_8K;
1143 break;
1144 case 16:
1145 case 16*1024:
1146 v = IEEE80211_HTCAP_MAXRXAMPDU_16K;
1147 break;
1148 case 32:
1149 case 32*1024:
1150 v = IEEE80211_HTCAP_MAXRXAMPDU_32K;
1151 break;
1152 case 64:
1153 case 64*1024:
1154 v = IEEE80211_HTCAP_MAXRXAMPDU_64K;
1155 break;
1156 default:
1157 errx(-1, "invalid A-MPDU limit %s", val);
1158 }
1159 set80211(s, IEEE80211_IOC_AMPDU_LIMIT, v, 0, NULL);
1160}
1161
1162static
1163DECL_CMD_FUNC(set80211ampdudensity, val, d)
1164{
1165 int v;
1166
1167 if (isanyarg(val))
1168 v = IEEE80211_HTCAP_MPDUDENSITY_NA;
1169 else switch ((int)(atof(val)*4)) {
1170 case 0:
1171 v = IEEE80211_HTCAP_MPDUDENSITY_NA;
1172 break;
1173 case 1:
1174 v = IEEE80211_HTCAP_MPDUDENSITY_025;
1175 break;
1176 case 2:
1177 v = IEEE80211_HTCAP_MPDUDENSITY_05;
1178 break;
1179 case 4:
1180 v = IEEE80211_HTCAP_MPDUDENSITY_1;
1181 break;
1182 case 8:
1183 v = IEEE80211_HTCAP_MPDUDENSITY_2;
1184 break;
1185 case 16:
1186 v = IEEE80211_HTCAP_MPDUDENSITY_4;
1187 break;
1188 case 32:
1189 v = IEEE80211_HTCAP_MPDUDENSITY_8;
1190 break;
1191 case 64:
1192 v = IEEE80211_HTCAP_MPDUDENSITY_16;
1193 break;
1194 default:
1195 errx(-1, "invalid A-MPDU density %s", val);
1196 }
1197 set80211(s, IEEE80211_IOC_AMPDU_DENSITY, v, 0, NULL);
1198}
1199
1200static void
1201set80211amsdu(const char *val, int d, int s, const struct afswtch *rafp)
1202{
1203 int amsdu;
1204
1205 if (get80211val(s, IEEE80211_IOC_AMSDU, &amsdu) < 0)
1206 errx(-1, "cannot get AMSDU setting");
1207 if (d < 0) {
1208 d = -d;
1209 amsdu &= ~d;
1210 } else
1211 amsdu |= d;
1212 set80211(s, IEEE80211_IOC_AMSDU, amsdu, 0, NULL);
1213}
1214
1215static
1216DECL_CMD_FUNC(set80211amsdulimit, val, d)
1217{
1218 set80211(s, IEEE80211_IOC_AMSDU_LIMIT, atoi(val), 0, NULL);
1219}
1220
1221static void
1222set80211puren(const char *val, int d, int s, const struct afswtch *rafp)
1223{
1224 set80211(s, IEEE80211_IOC_PUREN, d, 0, NULL);
1225}
1226
1227static void
1228set80211htcompat(const char *val, int d, int s, const struct afswtch *rafp)
1229{
1230 set80211(s, IEEE80211_IOC_HTCOMPAT, d, 0, NULL);
1231}
1232
1233static void
1234set80211htconf(const char *val, int d, int s, const struct afswtch *rafp)
1235{
1236 set80211(s, IEEE80211_IOC_HTCONF, d, 0, NULL);
1237 htconf = d;
1238}
1239
1240static void
1241set80211inact(const char *val, int d, int s, const struct afswtch *rafp)
1242{
1243 set80211(s, IEEE80211_IOC_INACTIVITY, d, 0, NULL);
1244}
1245
1246static void
1247LINE_INIT(char c)
1248{
1249 spacer = c;
1250 if (c == '\t')
1251 col = 8;
1252 else
1253 col = 1;
1254}
1255
1256static void
1257LINE_BREAK(void)
1258{
1259 if (spacer != '\t') {
1260 printf("\n");
1261 spacer = '\t';
1262 }
1263 col = 8; /* 8-col tab */
1264}
1265
1266static void
1267LINE_CHECK(const char *fmt, ...)
1268{
1269 char buf[80];
1270 va_list ap;
1271 int n;
1272
1273 va_start(ap, fmt);
1274 n = vsnprintf(buf+1, sizeof(buf)-1, fmt, ap);
1275 va_end(ap);
1276 col += 1+n;
1277 if (col > MAXCOL) {
1278 LINE_BREAK();
1279 col += n;
1280 }
1281 buf[0] = spacer;
1282 printf("%s", buf);
1283 spacer = ' ';
1284}
1285
1020static int
1021getmaxrate(const uint8_t rates[15], uint8_t nrates)
1022{
1023 int i, maxrate = -1;
1024
1025 for (i = 0; i < nrates; i++) {
1026 int rate = rates[i] & IEEE80211_RATE_VAL;
1027 if (rate > maxrate)

--- 38 unchanged lines hidden (view full) ---

1066getflags(int flags)
1067{
1068/* XXX need these publicly defined or similar */
1069#define IEEE80211_NODE_AUTH 0x0001 /* authorized for data */
1070#define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */
1071#define IEEE80211_NODE_ERP 0x0004 /* ERP enabled */
1072#define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */
1073#define IEEE80211_NODE_HT 0x0040 /* HT enabled */
1286static int
1287getmaxrate(const uint8_t rates[15], uint8_t nrates)
1288{
1289 int i, maxrate = -1;
1290
1291 for (i = 0; i < nrates; i++) {
1292 int rate = rates[i] & IEEE80211_RATE_VAL;
1293 if (rate > maxrate)

--- 38 unchanged lines hidden (view full) ---

1332getflags(int flags)
1333{
1334/* XXX need these publicly defined or similar */
1335#define IEEE80211_NODE_AUTH 0x0001 /* authorized for data */
1336#define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */
1337#define IEEE80211_NODE_ERP 0x0004 /* ERP enabled */
1338#define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */
1339#define IEEE80211_NODE_HT 0x0040 /* HT enabled */
1340#define IEEE80211_NODE_HTCOMPAT 0x0080 /* HT setup w/ vendor OUI's */
1341#define IEEE80211_NODE_WPS 0x0100 /* WPS association */
1342#define IEEE80211_NODE_TSN 0x0200 /* TSN association */
1343
1074 static char flagstring[32];
1075 char *cp = flagstring;
1076
1077 if (flags & IEEE80211_NODE_AUTH)
1078 *cp++ = 'A';
1079 if (flags & IEEE80211_NODE_QOS)
1080 *cp++ = 'Q';
1081 if (flags & IEEE80211_NODE_ERP)
1082 *cp++ = 'E';
1083 if (flags & IEEE80211_NODE_PWR_MGT)
1084 *cp++ = 'P';
1344 static char flagstring[32];
1345 char *cp = flagstring;
1346
1347 if (flags & IEEE80211_NODE_AUTH)
1348 *cp++ = 'A';
1349 if (flags & IEEE80211_NODE_QOS)
1350 *cp++ = 'Q';
1351 if (flags & IEEE80211_NODE_ERP)
1352 *cp++ = 'E';
1353 if (flags & IEEE80211_NODE_PWR_MGT)
1354 *cp++ = 'P';
1085 if (flags & IEEE80211_NODE_HT)
1355 if (flags & IEEE80211_NODE_HT) {
1086 *cp++ = 'H';
1356 *cp++ = 'H';
1357 if (flags & IEEE80211_NODE_HTCOMPAT)
1358 *cp++ = '+';
1359 }
1360 if (flags & IEEE80211_NODE_WPS)
1361 *cp++ = 'W';
1362 if (flags & IEEE80211_NODE_TSN)
1363 *cp++ = 'T';
1087 *cp = '\0';
1088 return flagstring;
1364 *cp = '\0';
1365 return flagstring;
1366#undef IEEE80211_NODE_TSN
1367#undef IEEE80211_NODE_WPS
1368#undef IEEE80211_NODE_HTCOMPAT
1089#undef IEEE80211_NODE_HT
1090#undef IEEE80211_NODE_AUTH
1091#undef IEEE80211_NODE_QOS
1092#undef IEEE80211_NODE_ERP
1093#undef IEEE80211_NODE_PWR_MGT
1094}
1095
1096static void

--- 29 unchanged lines hidden (view full) ---

1126
1127/*
1128 * NB: The decoding routines assume a properly formatted ie
1129 * which should be safe as the kernel only retains them
1130 * if they parse ok.
1131 */
1132
1133static void
1369#undef IEEE80211_NODE_HT
1370#undef IEEE80211_NODE_AUTH
1371#undef IEEE80211_NODE_QOS
1372#undef IEEE80211_NODE_ERP
1373#undef IEEE80211_NODE_PWR_MGT
1374}
1375
1376static void

--- 29 unchanged lines hidden (view full) ---

1406
1407/*
1408 * NB: The decoding routines assume a properly formatted ie
1409 * which should be safe as the kernel only retains them
1410 * if they parse ok.
1411 */
1412
1413static void
1134printwmeie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1414printwmeparam(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1135{
1136#define MS(_v, _f) (((_v) & _f) >> _f##_S)
1137 static const char *acnames[] = { "BE", "BK", "VO", "VI" };
1415{
1416#define MS(_v, _f) (((_v) & _f) >> _f##_S)
1417 static const char *acnames[] = { "BE", "BK", "VO", "VI" };
1418 const struct ieee80211_wme_param *wme =
1419 (const struct ieee80211_wme_param *) ie;
1138 int i;
1139
1140 printf("%s", tag);
1420 int i;
1421
1422 printf("%s", tag);
1141 if (verbose) {
1142 printf("<qosinfo 0x%x", ie[
1143 __offsetof(struct ieee80211_wme_param, param_qosInfo)]);
1144 ie += __offsetof(struct ieee80211_wme_param, params_acParams);
1145 for (i = 0; i < WME_NUM_AC; i++) {
1146 printf(" %s[%saifsn %u cwmin %u cwmax %u txop %u]"
1147 , acnames[i]
1148 , MS(ie[0], WME_PARAM_ACM) ? "acm " : ""
1149 , MS(ie[0], WME_PARAM_AIFSN)
1150 , MS(ie[1], WME_PARAM_LOGCWMIN)
1151 , MS(ie[1], WME_PARAM_LOGCWMAX)
1152 , LE_READ_2(ie+2)
1153 );
1154 ie += 4;
1155 }
1156 printf(">");
1423 if (!verbose)
1424 return;
1425 printf("<qosinfo 0x%x", wme->param_qosInfo);
1426 ie += offsetof(struct ieee80211_wme_param, params_acParams);
1427 for (i = 0; i < WME_NUM_AC; i++) {
1428 const struct ieee80211_wme_acparams *ac =
1429 &wme->params_acParams[i];
1430
1431 printf(" %s[%saifsn %u cwmin %u cwmax %u txop %u]"
1432 , acnames[i]
1433 , MS(ac->acp_aci_aifsn, WME_PARAM_ACM) ? "acm " : ""
1434 , MS(ac->acp_aci_aifsn, WME_PARAM_AIFSN)
1435 , MS(ac->acp_logcwminmax, WME_PARAM_LOGCWMIN)
1436 , MS(ac->acp_logcwminmax, WME_PARAM_LOGCWMAX)
1437 , LE_READ_2(&ac->acp_txop)
1438 );
1157 }
1439 }
1440 printf(">");
1158#undef MS
1159}
1160
1161static void
1441#undef MS
1442}
1443
1444static void
1445printwmeinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1446{
1447 printf("%s", tag);
1448 if (verbose) {
1449 const struct ieee80211_wme_info *wme =
1450 (const struct ieee80211_wme_info *) ie;
1451 printf("<version 0x%x info 0x%x>",
1452 wme->wme_version, wme->wme_info);
1453 }
1454}
1455
1456static void
1457printhtcap(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1458{
1459 printf("%s", tag);
1460 if (verbose) {
1461 const struct ieee80211_ie_htcap *htcap =
1462 (const struct ieee80211_ie_htcap *) ie;
1463 const char *sep;
1464 int i, j;
1465
1466 printf("<cap 0x%x param 0x%x",
1467 LE_READ_2(&htcap->hc_cap), htcap->hc_param);
1468 printf(" mcsset[");
1469 sep = "";
1470 for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++)
1471 if (isset(htcap->hc_mcsset, i)) {
1472 for (j = i+1; j < IEEE80211_HTRATE_MAXSIZE; j++)
1473 if (isclr(htcap->hc_mcsset, j))
1474 break;
1475 j--;
1476 if (i == j)
1477 printf("%s%u", sep, i);
1478 else
1479 printf("%s%u-%u", sep, i, j);
1480 i += j-i;
1481 sep = ",";
1482 }
1483 printf("] extcap 0x%x txbf 0x%x antenna 0x%x>",
1484 LE_READ_2(&htcap->hc_extcap),
1485 LE_READ_4(&htcap->hc_txbf),
1486 htcap->hc_antenna);
1487 }
1488}
1489
1490static void
1491printhtinfo(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1492{
1493 printf("%s", tag);
1494 if (verbose) {
1495 const struct ieee80211_ie_htinfo *htinfo =
1496 (const struct ieee80211_ie_htinfo *) ie;
1497 const char *sep;
1498 int i, j;
1499
1500 printf("<ctl %u, %x,%x,%x,%x", htinfo->hi_ctrlchannel,
1501 htinfo->hi_byte1, htinfo->hi_byte2, htinfo->hi_byte3,
1502 LE_READ_2(&htinfo->hi_byte45));
1503 printf(" basicmcs[");
1504 sep = "";
1505 for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++)
1506 if (isset(htinfo->hi_basicmcsset, i)) {
1507 for (j = i+1; j < IEEE80211_HTRATE_MAXSIZE; j++)
1508 if (isclr(htinfo->hi_basicmcsset, j))
1509 break;
1510 j--;
1511 if (i == j)
1512 printf("%s%u", sep, i);
1513 else
1514 printf("%s%u-%u", sep, i, j);
1515 i += j-i;
1516 sep = ",";
1517 }
1518 printf("]>");
1519 }
1520}
1521
1522static void
1162printathie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1163{
1164
1165 printf("%s", tag);
1166 if (verbose) {
1167 const struct ieee80211_ath_ie *ath =
1168 (const struct ieee80211_ath_ie *)ie;
1169

--- 142 unchanged lines hidden (view full) ---

1312 }
1313 return "?";
1314#undef RSN_SEL
1315}
1316
1317static void
1318printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1319{
1523printathie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1524{
1525
1526 printf("%s", tag);
1527 if (verbose) {
1528 const struct ieee80211_ath_ie *ath =
1529 (const struct ieee80211_ath_ie *)ie;
1530

--- 142 unchanged lines hidden (view full) ---

1673 }
1674 return "?";
1675#undef RSN_SEL
1676}
1677
1678static void
1679printrsnie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1680{
1320 u_int8_t len = ie[1];
1321
1322 printf("%s", tag);
1323 if (verbose) {
1324 const char *sep;
1325 int n;
1326
1681 printf("%s", tag);
1682 if (verbose) {
1683 const char *sep;
1684 int n;
1685
1327 ie += 6, len -= 4; /* NB: len is payload only */
1686 ie += 2, ielen -= 2;
1328
1329 printf("<v%u", LE_READ_2(ie));
1687
1688 printf("<v%u", LE_READ_2(ie));
1330 ie += 2, len -= 2;
1689 ie += 2, ielen -= 2;
1331
1332 printf(" mc:%s", rsn_cipher(ie));
1690
1691 printf(" mc:%s", rsn_cipher(ie));
1333 ie += 4, len -= 4;
1692 ie += 4, ielen -= 4;
1334
1335 /* unicast ciphers */
1336 n = LE_READ_2(ie);
1693
1694 /* unicast ciphers */
1695 n = LE_READ_2(ie);
1337 ie += 2, len -= 2;
1696 ie += 2, ielen -= 2;
1338 sep = " uc:";
1339 for (; n > 0; n--) {
1340 printf("%s%s", sep, rsn_cipher(ie));
1697 sep = " uc:";
1698 for (; n > 0; n--) {
1699 printf("%s%s", sep, rsn_cipher(ie));
1341 ie += 4, len -= 4;
1700 ie += 4, ielen -= 4;
1342 sep = "+";
1343 }
1344
1345 /* key management algorithms */
1346 n = LE_READ_2(ie);
1701 sep = "+";
1702 }
1703
1704 /* key management algorithms */
1705 n = LE_READ_2(ie);
1347 ie += 2, len -= 2;
1706 ie += 2, ielen -= 2;
1348 sep = " km:";
1349 for (; n > 0; n--) {
1350 printf("%s%s", sep, rsn_keymgmt(ie));
1707 sep = " km:";
1708 for (; n > 0; n--) {
1709 printf("%s%s", sep, rsn_keymgmt(ie));
1351 ie += 4, len -= 4;
1710 ie += 4, ielen -= 4;
1352 sep = "+";
1353 }
1354
1711 sep = "+";
1712 }
1713
1355 if (len > 2) /* optional capabilities */
1714 if (ielen > 2) /* optional capabilities */
1356 printf(", caps 0x%x", LE_READ_2(ie));
1357 /* XXXPMKID */
1358 printf(">");
1359 }
1360}
1361
1362/*
1363 * Copy the ssid string contents into buf, truncating to fit. If the

--- 32 unchanged lines hidden (view full) ---

1396 } else { /* printable, truncate as needed */
1397 memcpy(buf, essid, maxlen);
1398 if (maxlen != essid_len)
1399 memcpy(&buf[maxlen-3], "...", 3);
1400 }
1401 return maxlen;
1402}
1403
1715 printf(", caps 0x%x", LE_READ_2(ie));
1716 /* XXXPMKID */
1717 printf(">");
1718 }
1719}
1720
1721/*
1722 * Copy the ssid string contents into buf, truncating to fit. If the

--- 32 unchanged lines hidden (view full) ---

1755 } else { /* printable, truncate as needed */
1756 memcpy(buf, essid, maxlen);
1757 if (maxlen != essid_len)
1758 memcpy(&buf[maxlen-3], "...", 3);
1759 }
1760 return maxlen;
1761}
1762
1763static void
1764printssid(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1765{
1766 char ssid[2*IEEE80211_NWID_LEN+1];
1767
1768 printf("%s<%.*s>", tag, copy_essid(ssid, maxlen, ie+2, ie[1]), ssid);
1769}
1770
1771static void
1772printrates(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1773{
1774 const char *sep;
1775 int i;
1776
1777 printf("%s", tag);
1778 sep = "<";
1779 for (i = 2; i < ielen; i++) {
1780 printf("%s%s%d", sep,
1781 ie[i] & IEEE80211_RATE_BASIC ? "B" : "",
1782 ie[i] & IEEE80211_RATE_VAL);
1783 sep = ",";
1784 }
1785 printf(">");
1786}
1787
1788static void
1789printcountry(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen)
1790{
1791 const struct ieee80211_country_ie *cie =
1792 (const struct ieee80211_country_ie *) ie;
1793 int i, nbands, schan, nchan;
1794
1795 printf("%s<%c%c%c", tag, cie->cc[0], cie->cc[1], cie->cc[2]);
1796 nbands = (cie->len - 3) / sizeof(cie->band[0]);
1797 for (i = 0; i < nbands; i++) {
1798 schan = cie->band[i].schan;
1799 nchan = cie->band[i].nchan;
1800 if (nchan != 1)
1801 printf(" %u-%u,%u", schan, schan + nchan-1,
1802 cie->band[i].maxtxpwr);
1803 else
1804 printf(" %u,%u", schan, cie->band[i].maxtxpwr);
1805 }
1806 printf(">");
1807}
1808
1404/* unaligned little endian access */
1405#define LE_READ_4(p) \
1406 ((u_int32_t) \
1407 ((((const u_int8_t *)(p))[0] ) | \
1408 (((const u_int8_t *)(p))[1] << 8) | \
1409 (((const u_int8_t *)(p))[2] << 16) | \
1410 (((const u_int8_t *)(p))[3] << 24)))
1411
1412static int __inline
1413iswpaoui(const u_int8_t *frm)
1414{
1415 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
1416}
1417
1418static int __inline
1809/* unaligned little endian access */
1810#define LE_READ_4(p) \
1811 ((u_int32_t) \
1812 ((((const u_int8_t *)(p))[0] ) | \
1813 (((const u_int8_t *)(p))[1] << 8) | \
1814 (((const u_int8_t *)(p))[2] << 16) | \
1815 (((const u_int8_t *)(p))[3] << 24)))
1816
1817static int __inline
1818iswpaoui(const u_int8_t *frm)
1819{
1820 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
1821}
1822
1823static int __inline
1419iswmeoui(const u_int8_t *frm)
1824iswmeinfo(const u_int8_t *frm)
1420{
1825{
1421 return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI);
1826 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1827 frm[6] == WME_INFO_OUI_SUBTYPE;
1422}
1423
1424static int __inline
1828}
1829
1830static int __inline
1831iswmeparam(const u_int8_t *frm)
1832{
1833 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1834 frm[6] == WME_PARAM_OUI_SUBTYPE;
1835}
1836
1837static int __inline
1425isatherosoui(const u_int8_t *frm)
1426{
1427 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
1428}
1429
1838isatherosoui(const u_int8_t *frm)
1839{
1840 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
1841}
1842
1843static const char *
1844iename(int elemid)
1845{
1846 switch (elemid) {
1847 case IEEE80211_ELEMID_FHPARMS: return " FHPARMS";
1848 case IEEE80211_ELEMID_CFPARMS: return " CFPARMS";
1849 case IEEE80211_ELEMID_TIM: return " TIM";
1850 case IEEE80211_ELEMID_IBSSPARMS:return " IBSSPARMS";
1851 case IEEE80211_ELEMID_CHALLENGE:return " CHALLENGE";
1852 case IEEE80211_ELEMID_PWRCNSTR: return " PWRCNSTR";
1853 case IEEE80211_ELEMID_PWRCAP: return " PWRCAP";
1854 case IEEE80211_ELEMID_TPCREQ: return " TPCREQ";
1855 case IEEE80211_ELEMID_TPCREP: return " TPCREP";
1856 case IEEE80211_ELEMID_SUPPCHAN: return " SUPPCHAN";
1857 case IEEE80211_ELEMID_CHANSWITCHANN:return " CSA";
1858 case IEEE80211_ELEMID_MEASREQ: return " MEASREQ";
1859 case IEEE80211_ELEMID_MEASREP: return " MEASREP";
1860 case IEEE80211_ELEMID_QUIET: return " QUIET";
1861 case IEEE80211_ELEMID_IBSSDFS: return " IBSSDFS";
1862 case IEEE80211_ELEMID_TPC: return " TPC";
1863 case IEEE80211_ELEMID_CCKM: return " CCKM";
1864 }
1865 return " ???";
1866}
1867
1430static void
1431printies(const u_int8_t *vp, int ielen, int maxcols)
1432{
1433 while (ielen > 0) {
1434 switch (vp[0]) {
1868static void
1869printies(const u_int8_t *vp, int ielen, int maxcols)
1870{
1871 while (ielen > 0) {
1872 switch (vp[0]) {
1873 case IEEE80211_ELEMID_SSID:
1874 if (verbose)
1875 printssid(" SSID", vp, 2+vp[1], maxcols);
1876 break;
1877 case IEEE80211_ELEMID_RATES:
1878 case IEEE80211_ELEMID_XRATES:
1879 if (verbose)
1880 printrates(vp[0] == IEEE80211_ELEMID_RATES ?
1881 " RATES" : " XRATES", vp, 2+vp[1], maxcols);
1882 break;
1883 case IEEE80211_ELEMID_DSPARMS:
1884 if (verbose)
1885 printf(" DSPARMS<%u>", vp[2]);
1886 break;
1887 case IEEE80211_ELEMID_COUNTRY:
1888 if (verbose)
1889 printcountry(" COUNTRY", vp, 2+vp[1], maxcols);
1890 break;
1891 case IEEE80211_ELEMID_ERP:
1892 if (verbose)
1893 printf(" ERP<0x%x>", vp[2]);
1894 break;
1435 case IEEE80211_ELEMID_VENDOR:
1436 if (iswpaoui(vp))
1437 printwpaie(" WPA", vp, 2+vp[1], maxcols);
1895 case IEEE80211_ELEMID_VENDOR:
1896 if (iswpaoui(vp))
1897 printwpaie(" WPA", vp, 2+vp[1], maxcols);
1438 else if (iswmeoui(vp))
1439 printwmeie(" WME", vp, 2+vp[1], maxcols);
1898 else if (iswmeinfo(vp))
1899 printwmeinfo(" WME", vp, 2+vp[1], maxcols);
1900 else if (iswmeparam(vp))
1901 printwmeparam(" WME", vp, 2+vp[1], maxcols);
1440 else if (isatherosoui(vp))
1441 printathie(" ATH", vp, 2+vp[1], maxcols);
1902 else if (isatherosoui(vp))
1903 printathie(" ATH", vp, 2+vp[1], maxcols);
1442 else
1904 else if (verbose)
1443 printie(" VEN", vp, 2+vp[1], maxcols);
1444 break;
1445 case IEEE80211_ELEMID_RSN:
1446 printrsnie(" RSN", vp, 2+vp[1], maxcols);
1447 break;
1905 printie(" VEN", vp, 2+vp[1], maxcols);
1906 break;
1907 case IEEE80211_ELEMID_RSN:
1908 printrsnie(" RSN", vp, 2+vp[1], maxcols);
1909 break;
1910 case IEEE80211_ELEMID_HTCAP:
1911 printhtcap(" HTCAP", vp, 2+vp[1], maxcols);
1912 break;
1913 case IEEE80211_ELEMID_HTINFO:
1914 if (verbose)
1915 printhtinfo(" HTINFO", vp, 2+vp[1], maxcols);
1916 break;
1448 default:
1917 default:
1449 printie(" ???", vp, 2+vp[1], maxcols);
1918 if (verbose)
1919 printie(iename(vp[0]), vp, 2+vp[1], maxcols);
1450 break;
1451 }
1452 ielen -= 2+vp[1];
1453 vp += 2+vp[1];
1454 }
1455}
1456
1457static void
1458list_scan(int s)
1459{
1460 uint8_t buf[24*1024];
1920 break;
1921 }
1922 ielen -= 2+vp[1];
1923 vp += 2+vp[1];
1924 }
1925}
1926
1927static void
1928list_scan(int s)
1929{
1930 uint8_t buf[24*1024];
1461 struct ieee80211req ireq;
1462 char ssid[IEEE80211_NWID_LEN+1];
1931 char ssid[IEEE80211_NWID_LEN+1];
1463 uint8_t *cp;
1932 const uint8_t *cp;
1464 int len, ssidmax;
1465
1933 int len, ssidmax;
1934
1466 (void) memset(&ireq, 0, sizeof(ireq));
1467 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
1468 ireq.i_type = IEEE80211_IOC_SCAN_RESULTS;
1469 ireq.i_data = buf;
1470 ireq.i_len = sizeof(buf);
1471 if (ioctl(s, SIOCG80211, &ireq) < 0)
1935 if (get80211len(s, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf), &len) < 0)
1472 errx(1, "unable to get scan results");
1936 errx(1, "unable to get scan results");
1473 len = ireq.i_len;
1474 if (len < sizeof(struct ieee80211req_scan_result))
1475 return;
1476
1477 getchaninfo(s);
1478
1479 ssidmax = verbose ? IEEE80211_NWID_LEN : 14;
1480 printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n"
1481 , ssidmax, ssidmax, "SSID"

--- 5 unchanged lines hidden (view full) ---

1487 , "CAPS"
1488 );
1489 cp = buf;
1490 do {
1491 const struct ieee80211req_scan_result *sr;
1492 const uint8_t *vp;
1493
1494 sr = (const struct ieee80211req_scan_result *) cp;
1937 if (len < sizeof(struct ieee80211req_scan_result))
1938 return;
1939
1940 getchaninfo(s);
1941
1942 ssidmax = verbose ? IEEE80211_NWID_LEN : 14;
1943 printf("%-*.*s %-17.17s %4s %4s %-7s %3s %4s\n"
1944 , ssidmax, ssidmax, "SSID"

--- 5 unchanged lines hidden (view full) ---

1950 , "CAPS"
1951 );
1952 cp = buf;
1953 do {
1954 const struct ieee80211req_scan_result *sr;
1955 const uint8_t *vp;
1956
1957 sr = (const struct ieee80211req_scan_result *) cp;
1495 vp = ((const u_int8_t *)sr) + sr->isr_ie_off;
1958 vp = cp + sr->isr_ie_off;
1496 printf("%-*.*s %s %3d %3dM %3d:%-3d %3d %-4.4s"
1497 , ssidmax
1498 , copy_essid(ssid, ssidmax, vp, sr->isr_ssid_len)
1499 , ssid
1500 , ether_ntoa((const struct ether_addr *) sr->isr_bssid)
1501 , ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags)
1502 , getmaxrate(sr->isr_rates, sr->isr_nrates)
1503 , (sr->isr_rssi/2)+sr->isr_noise, sr->isr_noise

--- 47 unchanged lines hidden (view full) ---

1551DECL_CMD_FUNC(set80211scan, val, d)
1552{
1553 scan_and_wait(s);
1554 list_scan(s);
1555}
1556
1557static enum ieee80211_opmode get80211opmode(int s);
1558
1959 printf("%-*.*s %s %3d %3dM %3d:%-3d %3d %-4.4s"
1960 , ssidmax
1961 , copy_essid(ssid, ssidmax, vp, sr->isr_ssid_len)
1962 , ssid
1963 , ether_ntoa((const struct ether_addr *) sr->isr_bssid)
1964 , ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags)
1965 , getmaxrate(sr->isr_rates, sr->isr_nrates)
1966 , (sr->isr_rssi/2)+sr->isr_noise, sr->isr_noise

--- 47 unchanged lines hidden (view full) ---

2014DECL_CMD_FUNC(set80211scan, val, d)
2015{
2016 scan_and_wait(s);
2017 list_scan(s);
2018}
2019
2020static enum ieee80211_opmode get80211opmode(int s);
2021
2022static int
2023gettxseq(const struct ieee80211req_sta_info *si)
2024{
2025#define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */
2026
2027 int i, txseq;
2028
2029 if ((si->isi_state & IEEE80211_NODE_QOS) == 0)
2030 return si->isi_txseqs[0];
2031 /* XXX not right but usually what folks want */
2032 txseq = 0;
2033 for (i = 0; i < IEEE80211_TID_SIZE; i++)
2034 if (si->isi_txseqs[i] > txseq)
2035 txseq = si->isi_txseqs[i];
2036 return txseq;
2037#undef IEEE80211_NODE_QOS
2038}
2039
2040static int
2041getrxseq(const struct ieee80211req_sta_info *si)
2042{
2043#define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */
2044
2045 int i, rxseq;
2046
2047 if ((si->isi_state & IEEE80211_NODE_QOS) == 0)
2048 return si->isi_rxseqs[0];
2049 /* XXX not right but usually what folks want */
2050 rxseq = 0;
2051 for (i = 0; i < IEEE80211_TID_SIZE; i++)
2052 if (si->isi_rxseqs[i] > rxseq)
2053 rxseq = si->isi_rxseqs[i];
2054 return rxseq;
2055#undef IEEE80211_NODE_QOS
2056}
2057
2058static int
2059gettxrate(int txrate, int chanflags)
2060{
2061 if (txrate & 0x80) {
2062 txrate = htrates[txrate & 0xf];
2063 /* NB: could bump this more based on short gi */
2064 return chanflags & IEEE80211_CHAN_HT40 ? txrate : txrate / 2;
2065 } else
2066 return (txrate & IEEE80211_RATE_VAL) / 2;
2067}
2068
1559static void
1560list_stations(int s)
1561{
1562 union {
1563 struct ieee80211req_sta_req req;
1564 uint8_t buf[24*1024];
1565 } u;
1566 enum ieee80211_opmode opmode = get80211opmode(s);
2069static void
2070list_stations(int s)
2071{
2072 union {
2073 struct ieee80211req_sta_req req;
2074 uint8_t buf[24*1024];
2075 } u;
2076 enum ieee80211_opmode opmode = get80211opmode(s);
1567 struct ieee80211req ireq;
1568 const uint8_t *cp;
1569 int len;
1570
2077 const uint8_t *cp;
2078 int len;
2079
1571 (void) memset(&ireq, 0, sizeof(ireq));
1572 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
1573 /* broadcast address =>'s get all stations */
1574 (void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN);
1575 if (opmode == IEEE80211_M_STA) {
1576 /*
1577 * Get information about the associated AP.
1578 */
2080 /* broadcast address =>'s get all stations */
2081 (void) memset(u.req.is_u.macaddr, 0xff, IEEE80211_ADDR_LEN);
2082 if (opmode == IEEE80211_M_STA) {
2083 /*
2084 * Get information about the associated AP.
2085 */
1579 ireq.i_type = IEEE80211_IOC_BSSID;
1580 ireq.i_data = u.req.is_u.macaddr;
1581 ireq.i_len = IEEE80211_ADDR_LEN;
1582 (void) ioctl(s, SIOCG80211, &ireq);
2086 (void) get80211(s, IEEE80211_IOC_BSSID,
2087 u.req.is_u.macaddr, IEEE80211_ADDR_LEN);
1583 }
2088 }
1584 ireq.i_type = IEEE80211_IOC_STA_INFO;
1585 ireq.i_data = &u;
1586 ireq.i_len = sizeof(u);
1587 if (ioctl(s, SIOCG80211, &ireq) < 0)
2089 if (get80211len(s, IEEE80211_IOC_STA_INFO, &u, sizeof(u), &len) < 0)
1588 errx(1, "unable to get station information");
2090 errx(1, "unable to get station information");
1589 len = ireq.i_len;
1590 if (len < sizeof(struct ieee80211req_sta_info))
1591 return;
1592
1593 getchaninfo(s);
1594
1595 printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %4s\n"
1596 , "ADDR"
1597 , "AID"

--- 12 unchanged lines hidden (view full) ---

1610
1611 si = (const struct ieee80211req_sta_info *) cp;
1612 if (si->isi_len < sizeof(*si))
1613 break;
1614 printf("%s %4u %4d %3dM %3.1f %4d %6d %6d %-4.4s %-4.4s"
1615 , ether_ntoa((const struct ether_addr*) si->isi_macaddr)
1616 , IEEE80211_AID(si->isi_associd)
1617 , ieee80211_mhz2ieee(si->isi_freq, si->isi_flags)
2091 if (len < sizeof(struct ieee80211req_sta_info))
2092 return;
2093
2094 getchaninfo(s);
2095
2096 printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %4s\n"
2097 , "ADDR"
2098 , "AID"

--- 12 unchanged lines hidden (view full) ---

2111
2112 si = (const struct ieee80211req_sta_info *) cp;
2113 if (si->isi_len < sizeof(*si))
2114 break;
2115 printf("%s %4u %4d %3dM %3.1f %4d %6d %6d %-4.4s %-4.4s"
2116 , ether_ntoa((const struct ether_addr*) si->isi_macaddr)
2117 , IEEE80211_AID(si->isi_associd)
2118 , ieee80211_mhz2ieee(si->isi_freq, si->isi_flags)
1618 , (si->isi_rates[si->isi_txrate] & IEEE80211_RATE_VAL)/2
2119 , gettxrate(si->isi_txrate, si->isi_flags)
1619 , si->isi_rssi/2.
1620 , si->isi_inact
2120 , si->isi_rssi/2.
2121 , si->isi_inact
1621 , si->isi_txseqs[0]
1622 , si->isi_rxseqs[0]
2122 , gettxseq(si)
2123 , getrxseq(si)
1623 , getcaps(si->isi_capinfo)
1624 , getflags(si->isi_state)
1625 );
1626 printies(cp + si->isi_ie_off, si->isi_ie_len, 24);
1627 printf("\n");
1628 cp += si->isi_len, len -= si->isi_len;
1629 } while (len >= sizeof(struct ieee80211req_sta_info));
1630}

--- 34 unchanged lines hidden (view full) ---

1665 } else {
1666 if (IEEE80211_IS_CHAN_HT(c))
1667 strlcat(buf, " ht", bsize);
1668 }
1669 return buf;
1670}
1671
1672static void
2124 , getcaps(si->isi_capinfo)
2125 , getflags(si->isi_state)
2126 );
2127 printies(cp + si->isi_ie_off, si->isi_ie_len, 24);
2128 printf("\n");
2129 cp += si->isi_len, len -= si->isi_len;
2130 } while (len >= sizeof(struct ieee80211req_sta_info));
2131}

--- 34 unchanged lines hidden (view full) ---

2166 } else {
2167 if (IEEE80211_IS_CHAN_HT(c))
2168 strlcat(buf, " ht", bsize);
2169 }
2170 return buf;
2171}
2172
2173static void
1673print_chaninfo(const struct ieee80211_channel *c)
2174print_chaninfo(const struct ieee80211_channel *c, int verb)
1674{
1675 char buf[14];
1676
1677 printf("Channel %3u : %u%c Mhz%-14.14s",
1678 ieee80211_mhz2ieee(c->ic_freq, c->ic_flags), c->ic_freq,
1679 IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ',
2175{
2176 char buf[14];
2177
2178 printf("Channel %3u : %u%c Mhz%-14.14s",
2179 ieee80211_mhz2ieee(c->ic_freq, c->ic_flags), c->ic_freq,
2180 IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ',
1680 get_chaninfo(c, verbose, buf, sizeof(buf)));
2181 get_chaninfo(c, verb, buf, sizeof(buf)));
1681}
1682
1683static void
2182}
2183
2184static void
1684list_channels(int s, int allchans)
2185print_channels(int s, const struct ieee80211req_chaninfo *chans,
2186 int allchans, int verb)
1685{
1686 struct ieee80211req_chaninfo achans;
1687 uint8_t reported[IEEE80211_CHAN_BYTES];
1688 const struct ieee80211_channel *c;
1689 int i, half;
1690
2187{
2188 struct ieee80211req_chaninfo achans;
2189 uint8_t reported[IEEE80211_CHAN_BYTES];
2190 const struct ieee80211_channel *c;
2191 int i, half;
2192
1691 getchaninfo(s);
1692 memset(&achans, 0, sizeof(achans));
1693 memset(reported, 0, sizeof(reported));
1694 if (!allchans) {
1695 struct ieee80211req_chanlist active;
2193 memset(&achans, 0, sizeof(achans));
2194 memset(reported, 0, sizeof(reported));
2195 if (!allchans) {
2196 struct ieee80211req_chanlist active;
1696 struct ieee80211req ireq;
1697
2197
1698 (void) memset(&ireq, 0, sizeof(ireq));
1699 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
1700 ireq.i_type = IEEE80211_IOC_CHANLIST;
1701 ireq.i_data = &active;
1702 ireq.i_len = sizeof(active);
1703 if (ioctl(s, SIOCG80211, &ireq) < 0)
2198 if (get80211(s, IEEE80211_IOC_CHANLIST, &active, sizeof(active)) < 0)
1704 errx(1, "unable to get active channel list");
1705 memset(&achans, 0, sizeof(achans));
2199 errx(1, "unable to get active channel list");
2200 memset(&achans, 0, sizeof(achans));
1706 for (i = 0; i < chaninfo.ic_nchans; i++) {
1707 c = &chaninfo.ic_chans[i];
2201 for (i = 0; i < chans->ic_nchans; i++) {
2202 c = &chans->ic_chans[i];
1708 if (!isset(active.ic_channels, c->ic_ieee))
1709 continue;
1710 /*
1711 * Suppress compatible duplicates unless
1712 * verbose. The kernel gives us it's
1713 * complete channel list which has separate
1714 * entries for 11g/11b and 11a/turbo.
1715 */
2203 if (!isset(active.ic_channels, c->ic_ieee))
2204 continue;
2205 /*
2206 * Suppress compatible duplicates unless
2207 * verbose. The kernel gives us it's
2208 * complete channel list which has separate
2209 * entries for 11g/11b and 11a/turbo.
2210 */
1716 if (isset(reported, c->ic_ieee) && !verbose) {
2211 if (isset(reported, c->ic_ieee) && !verb) {
1717 /* XXX we assume duplicates are adjacent */
1718 achans.ic_chans[achans.ic_nchans-1] = *c;
1719 } else {
1720 achans.ic_chans[achans.ic_nchans++] = *c;
1721 setbit(reported, c->ic_ieee);
1722 }
1723 }
1724 } else {
2212 /* XXX we assume duplicates are adjacent */
2213 achans.ic_chans[achans.ic_nchans-1] = *c;
2214 } else {
2215 achans.ic_chans[achans.ic_nchans++] = *c;
2216 setbit(reported, c->ic_ieee);
2217 }
2218 }
2219 } else {
1725 for (i = 0; i < chaninfo.ic_nchans; i++) {
1726 c = &chaninfo.ic_chans[i];
2220 for (i = 0; i < chans->ic_nchans; i++) {
2221 c = &chans->ic_chans[i];
1727 /* suppress duplicates as above */
2222 /* suppress duplicates as above */
1728 if (isset(reported, c->ic_ieee) && !verbose) {
2223 if (isset(reported, c->ic_ieee) && !verb) {
1729 /* XXX we assume duplicates are adjacent */
1730 achans.ic_chans[achans.ic_nchans-1] = *c;
1731 } else {
1732 achans.ic_chans[achans.ic_nchans++] = *c;
1733 setbit(reported, c->ic_ieee);
1734 }
1735 }
1736 }
1737 half = achans.ic_nchans / 2;
1738 if (achans.ic_nchans % 2)
1739 half++;
1740
1741 for (i = 0; i < achans.ic_nchans / 2; i++) {
2224 /* XXX we assume duplicates are adjacent */
2225 achans.ic_chans[achans.ic_nchans-1] = *c;
2226 } else {
2227 achans.ic_chans[achans.ic_nchans++] = *c;
2228 setbit(reported, c->ic_ieee);
2229 }
2230 }
2231 }
2232 half = achans.ic_nchans / 2;
2233 if (achans.ic_nchans % 2)
2234 half++;
2235
2236 for (i = 0; i < achans.ic_nchans / 2; i++) {
1742 print_chaninfo(&achans.ic_chans[i]);
1743 print_chaninfo(&achans.ic_chans[half+i]);
2237 print_chaninfo(&achans.ic_chans[i], verb);
2238 print_chaninfo(&achans.ic_chans[half+i], verb);
1744 printf("\n");
1745 }
1746 if (achans.ic_nchans % 2) {
2239 printf("\n");
2240 }
2241 if (achans.ic_nchans % 2) {
1747 print_chaninfo(&achans.ic_chans[i]);
2242 print_chaninfo(&achans.ic_chans[i], verb);
1748 printf("\n");
1749 }
1750}
1751
1752static void
2243 printf("\n");
2244 }
2245}
2246
2247static void
2248list_channels(int s, int allchans)
2249{
2250 getchaninfo(s);
2251 print_channels(s, &chaninfo, allchans, verbose);
2252}
2253
2254static void
1753print_txpow(const struct ieee80211_channel *c)
1754{
1755 printf("Channel %3u : %u Mhz %3.1f reg %2d ",
1756 c->ic_ieee, c->ic_freq,
1757 c->ic_maxpower/2., c->ic_maxregpower);
1758}
1759
1760static void
1761print_txpow_verbose(const struct ieee80211_channel *c)
1762{
2255print_txpow(const struct ieee80211_channel *c)
2256{
2257 printf("Channel %3u : %u Mhz %3.1f reg %2d ",
2258 c->ic_ieee, c->ic_freq,
2259 c->ic_maxpower/2., c->ic_maxregpower);
2260}
2261
2262static void
2263print_txpow_verbose(const struct ieee80211_channel *c)
2264{
1763 print_chaninfo(c);
2265 print_chaninfo(c, 1);
1764 printf("min %4.1f dBm max %3.1f dBm reg %2d dBm",
1765 c->ic_minpower/2., c->ic_maxpower/2., c->ic_maxregpower);
1766 /* indicate where regulatory cap limits power use */
1767 if (c->ic_maxpower > 2*c->ic_maxregpower)
1768 printf(" <");
1769}
1770
1771static void

--- 64 unchanged lines hidden (view full) ---

1836 ireq.i_type = IEEE80211_IOC_DRIVER_CAPS;
1837 if (ioctl(s, SIOCG80211, &ireq) < 0)
1838 errx(1, "unable to get driver capabilities");
1839 caps = (((u_int16_t) ireq.i_val) << 16) | ((u_int16_t) ireq.i_len);
1840 printb(name, caps, IEEE80211_C_BITS);
1841 putchar('\n');
1842}
1843
2266 printf("min %4.1f dBm max %3.1f dBm reg %2d dBm",
2267 c->ic_minpower/2., c->ic_maxpower/2., c->ic_maxregpower);
2268 /* indicate where regulatory cap limits power use */
2269 if (c->ic_maxpower > 2*c->ic_maxregpower)
2270 printf(" <");
2271}
2272
2273static void

--- 64 unchanged lines hidden (view full) ---

2338 ireq.i_type = IEEE80211_IOC_DRIVER_CAPS;
2339 if (ioctl(s, SIOCG80211, &ireq) < 0)
2340 errx(1, "unable to get driver capabilities");
2341 caps = (((u_int16_t) ireq.i_val) << 16) | ((u_int16_t) ireq.i_len);
2342 printb(name, caps, IEEE80211_C_BITS);
2343 putchar('\n');
2344}
2345
1844static void
1845list_wme(int s)
2346static int
2347get80211wme(int s, int param, int ac, int *val)
1846{
2348{
1847 static const char *acnames[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" };
1848 struct ieee80211req ireq;
2349 struct ieee80211req ireq;
1849 int ac;
1850
1851 (void) memset(&ireq, 0, sizeof(ireq));
1852 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
2350
2351 (void) memset(&ireq, 0, sizeof(ireq));
2352 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
1853 ireq.i_len = 0;
2353 ireq.i_type = param;
2354 ireq.i_len = ac;
2355 if (ioctl(s, SIOCG80211, &ireq) < 0) {
2356 warn("cannot get WME parameter %d, ac %d%s",
2357 param, ac & IEEE80211_WMEPARAM_VAL,
2358 ac & IEEE80211_WMEPARAM_BSS ? " (BSS)" : "");
2359 return -1;
2360 }
2361 *val = ireq.i_val;
2362 return 0;
2363}
2364
2365static void
2366list_wme(int s)
2367{
2368 static const char *acnames[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" };
2369 int ac, val;
2370
1854 for (ac = WME_AC_BE; ac <= WME_AC_VO; ac++) {
1855again:
2371 for (ac = WME_AC_BE; ac <= WME_AC_VO; ac++) {
2372again:
1856 if (ireq.i_len & IEEE80211_WMEPARAM_BSS)
2373 if (ac & IEEE80211_WMEPARAM_BSS)
1857 printf("\t%s", " ");
1858 else
1859 printf("\t%s", acnames[ac]);
1860
2374 printf("\t%s", " ");
2375 else
2376 printf("\t%s", acnames[ac]);
2377
1861 ireq.i_len = (ireq.i_len & IEEE80211_WMEPARAM_BSS) | ac;
1862
1863 /* show WME BSS parameters */
2378 /* show WME BSS parameters */
1864 ireq.i_type = IEEE80211_IOC_WME_CWMIN;
1865 if (ioctl(s, SIOCG80211, &ireq) != -1)
1866 printf(" cwmin %2u", ireq.i_val);
1867 ireq.i_type = IEEE80211_IOC_WME_CWMAX;
1868 if (ioctl(s, SIOCG80211, &ireq) != -1)
1869 printf(" cwmax %2u", ireq.i_val);
1870 ireq.i_type = IEEE80211_IOC_WME_AIFS;
1871 if (ioctl(s, SIOCG80211, &ireq) != -1)
1872 printf(" aifs %2u", ireq.i_val);
1873 ireq.i_type = IEEE80211_IOC_WME_TXOPLIMIT;
1874 if (ioctl(s, SIOCG80211, &ireq) != -1)
1875 printf(" txopLimit %3u", ireq.i_val);
1876 ireq.i_type = IEEE80211_IOC_WME_ACM;
1877 if (ioctl(s, SIOCG80211, &ireq) != -1) {
1878 if (ireq.i_val)
2379 if (get80211wme(s, IEEE80211_IOC_WME_CWMIN, ac, &val) != -1)
2380 printf(" cwmin %2u", val);
2381 if (get80211wme(s, IEEE80211_IOC_WME_CWMAX, ac, &val) != -1)
2382 printf(" cwmax %2u", val);
2383 if (get80211wme(s, IEEE80211_IOC_WME_AIFS, ac, &val) != -1)
2384 printf(" aifs %2u", val);
2385 if (get80211wme(s, IEEE80211_IOC_WME_TXOPLIMIT, ac, &val) != -1)
2386 printf(" txopLimit %3u", val);
2387 if (get80211wme(s, IEEE80211_IOC_WME_ACM, ac, &val) != -1) {
2388 if (val)
1879 printf(" acm");
1880 else if (verbose)
1881 printf(" -acm");
1882 }
1883 /* !BSS only */
2389 printf(" acm");
2390 else if (verbose)
2391 printf(" -acm");
2392 }
2393 /* !BSS only */
1884 if ((ireq.i_len & IEEE80211_WMEPARAM_BSS) == 0) {
1885 ireq.i_type = IEEE80211_IOC_WME_ACKPOLICY;
1886 if (ioctl(s, SIOCG80211, &ireq) != -1) {
1887 if (!ireq.i_val)
2394 if ((ac & IEEE80211_WMEPARAM_BSS) == 0) {
2395 if (get80211wme(s, IEEE80211_IOC_WME_ACKPOLICY, ac, &val) != -1) {
2396 if (!val)
1888 printf(" -ack");
1889 else if (verbose)
1890 printf(" ack");
1891 }
1892 }
1893 printf("\n");
2397 printf(" -ack");
2398 else if (verbose)
2399 printf(" ack");
2400 }
2401 }
2402 printf("\n");
1894 if ((ireq.i_len & IEEE80211_WMEPARAM_BSS) == 0) {
1895 ireq.i_len |= IEEE80211_WMEPARAM_BSS;
2403 if ((ac & IEEE80211_WMEPARAM_BSS) == 0) {
2404 ac |= IEEE80211_WMEPARAM_BSS;
1896 goto again;
1897 } else
2405 goto again;
2406 } else
1898 ireq.i_len &= ~IEEE80211_WMEPARAM_BSS;
2407 ac &= ~IEEE80211_WMEPARAM_BSS;
1899 }
1900}
1901
1902static void
2408 }
2409}
2410
2411static void
2412printpolicy(int policy)
2413{
2414 switch (policy) {
2415 case IEEE80211_MACCMD_POLICY_OPEN:
2416 printf("policy: open\n");
2417 break;
2418 case IEEE80211_MACCMD_POLICY_ALLOW:
2419 printf("policy: allow\n");
2420 break;
2421 case IEEE80211_MACCMD_POLICY_DENY:
2422 printf("policy: deny\n");
2423 break;
2424 default:
2425 printf("policy: unknown (%u)\n", policy);
2426 break;
2427 }
2428}
2429
2430static void
1903list_mac(int s)
1904{
1905 struct ieee80211req ireq;
1906 struct ieee80211req_maclist *acllist;
2431list_mac(int s)
2432{
2433 struct ieee80211req ireq;
2434 struct ieee80211req_maclist *acllist;
1907 int i, nacls, policy;
2435 int i, nacls, policy, len;
2436 uint8_t *data;
1908 char c;
1909
1910 (void) memset(&ireq, 0, sizeof(ireq));
1911 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); /* XXX ?? */
1912 ireq.i_type = IEEE80211_IOC_MACCMD;
1913 ireq.i_val = IEEE80211_MACCMD_POLICY;
1914 if (ioctl(s, SIOCG80211, &ireq) < 0) {
1915 if (errno == EINVAL) {
1916 printf("No acl policy loaded\n");
1917 return;
1918 }
1919 err(1, "unable to get mac policy");
1920 }
1921 policy = ireq.i_val;
2437 char c;
2438
2439 (void) memset(&ireq, 0, sizeof(ireq));
2440 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); /* XXX ?? */
2441 ireq.i_type = IEEE80211_IOC_MACCMD;
2442 ireq.i_val = IEEE80211_MACCMD_POLICY;
2443 if (ioctl(s, SIOCG80211, &ireq) < 0) {
2444 if (errno == EINVAL) {
2445 printf("No acl policy loaded\n");
2446 return;
2447 }
2448 err(1, "unable to get mac policy");
2449 }
2450 policy = ireq.i_val;
1922
1923 ireq.i_val = IEEE80211_MACCMD_LIST;
1924 ireq.i_len = 0;
1925 if (ioctl(s, SIOCG80211, &ireq) < 0)
1926 err(1, "unable to get mac acl list size");
1927 if (ireq.i_len == 0) /* NB: no acls */
1928 return;
1929
1930 ireq.i_data = malloc(ireq.i_len);
1931 if (ireq.i_data == NULL)
1932 err(1, "out of memory for acl list");
1933
1934 if (ioctl(s, SIOCG80211, &ireq) < 0)
1935 err(1, "unable to get mac acl list");
1936 if (policy == IEEE80211_MACCMD_POLICY_OPEN) {
2451 if (policy == IEEE80211_MACCMD_POLICY_OPEN) {
1937 if (verbose)
1938 printf("policy: open\n");
1939 c = '*';
1940 } else if (policy == IEEE80211_MACCMD_POLICY_ALLOW) {
2452 c = '*';
2453 } else if (policy == IEEE80211_MACCMD_POLICY_ALLOW) {
1941 if (verbose)
1942 printf("policy: allow\n");
1943 c = '+';
1944 } else if (policy == IEEE80211_MACCMD_POLICY_DENY) {
2454 c = '+';
2455 } else if (policy == IEEE80211_MACCMD_POLICY_DENY) {
1945 if (verbose)
1946 printf("policy: deny\n");
1947 c = '-';
1948 } else {
1949 printf("policy: unknown (%u)\n", policy);
1950 c = '?';
1951 }
2456 c = '-';
2457 } else {
2458 printf("policy: unknown (%u)\n", policy);
2459 c = '?';
2460 }
1952 nacls = ireq.i_len / sizeof(*acllist);
1953 acllist = (struct ieee80211req_maclist *) ireq.i_data;
2461 if (verbose || c == '?')
2462 printpolicy(policy);
2463
2464 if (get80211len(s, IEEE80211_MACCMD_LIST, NULL, 0, &len) < 0)
2465 err(1, "unable to get mac acl list size");
2466 if (len == 0) { /* NB: no acls */
2467 if (!(verbose || c == '?'))
2468 printpolicy(policy);
2469 return;
2470 }
2471
2472 data = malloc(len);
2473 if (data == NULL)
2474 err(1, "out of memory for acl list");
2475
2476 if (get80211(s, IEEE80211_MACCMD_LIST, data, len) < 0)
2477 err(1, "unable to get mac acl list");
2478 nacls = len / sizeof(*acllist);
2479 acllist = (struct ieee80211req_maclist *) data;
1954 for (i = 0; i < nacls; i++)
1955 printf("%c%s\n", c, ether_ntoa(
1956 (const struct ether_addr *) acllist[i].ml_macaddr));
2480 for (i = 0; i < nacls; i++)
2481 printf("%c%s\n", c, ether_ntoa(
2482 (const struct ether_addr *) acllist[i].ml_macaddr));
2483 free(data);
1957}
1958
1959static
1960DECL_CMD_FUNC(set80211list, arg, d)
1961{
1962#define iseq(a,b) (strncasecmp(a,b,sizeof(b)-1) == 0)
1963
2484}
2485
2486static
2487DECL_CMD_FUNC(set80211list, arg, d)
2488{
2489#define iseq(a,b) (strncasecmp(a,b,sizeof(b)-1) == 0)
2490
2491 LINE_INIT('\t');
2492
1964 if (iseq(arg, "sta"))
1965 list_stations(s);
1966 else if (iseq(arg, "scan") || iseq(arg, "ap"))
1967 list_scan(s);
1968 else if (iseq(arg, "chan") || iseq(arg, "freq"))
1969 list_channels(s, 1);
1970 else if (iseq(arg, "active"))
1971 list_channels(s, 0);

--- 62 unchanged lines hidden (view full) ---

2034 break;
2035 default:
2036 printf("UNKNOWN (0x%x)", ireq->i_val);
2037 break;
2038 }
2039}
2040#endif
2041
2493 if (iseq(arg, "sta"))
2494 list_stations(s);
2495 else if (iseq(arg, "scan") || iseq(arg, "ap"))
2496 list_scan(s);
2497 else if (iseq(arg, "chan") || iseq(arg, "freq"))
2498 list_channels(s, 1);
2499 else if (iseq(arg, "active"))
2500 list_channels(s, 0);

--- 62 unchanged lines hidden (view full) ---

2563 break;
2564 default:
2565 printf("UNKNOWN (0x%x)", ireq->i_val);
2566 break;
2567 }
2568}
2569#endif
2570
2042#define MAXCOL 78
2043static int col;
2044static char spacer;
2045
2046static void
2571static void
2047LINE_BREAK(void)
2048{
2049 if (spacer != '\t') {
2050 printf("\n");
2051 spacer = '\t';
2052 }
2053 col = 8; /* 8-col tab */
2054}
2055
2056static void
2057LINE_CHECK(const char *fmt, ...)
2058{
2059 char buf[80];
2060 va_list ap;
2061 int n;
2062
2063 va_start(ap, fmt);
2064 n = vsnprintf(buf+1, sizeof(buf)-1, fmt, ap);
2065 va_end(ap);
2066 col += 1+n;
2067 if (col > MAXCOL) {
2068 LINE_BREAK();
2069 col += n;
2070 }
2071 buf[0] = spacer;
2072 printf("%s", buf);
2073 spacer = ' ';
2074}
2075
2076static void
2077printkey(const struct ieee80211req_key *ik)
2078{
2079 static const uint8_t zerodata[IEEE80211_KEYBUF_SIZE];
2080 int keylen = ik->ik_keylen;
2081 int printcontents;
2082
2083 printcontents = printkeys &&
2084 (memcmp(ik->ik_keydata, zerodata, keylen) != 0 || verbose);

--- 51 unchanged lines hidden (view full) ---

2136 if (ik->ik_flags & IEEE80211_KEY_DEFAULT)
2137 printf("%sdef", sep), sep = "+";
2138 }
2139 LINE_BREAK();
2140 }
2141}
2142
2143static void
2572printkey(const struct ieee80211req_key *ik)
2573{
2574 static const uint8_t zerodata[IEEE80211_KEYBUF_SIZE];
2575 int keylen = ik->ik_keylen;
2576 int printcontents;
2577
2578 printcontents = printkeys &&
2579 (memcmp(ik->ik_keydata, zerodata, keylen) != 0 || verbose);

--- 51 unchanged lines hidden (view full) ---

2631 if (ik->ik_flags & IEEE80211_KEY_DEFAULT)
2632 printf("%sdef", sep), sep = "+";
2633 }
2634 LINE_BREAK();
2635 }
2636}
2637
2638static void
2144ieee80211_status(int s)
2639printrate(const char *tag, int v, int defrate, int defmcs)
2145{
2640{
2146 static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
2147 enum ieee80211_opmode opmode = get80211opmode(s);
2148 int i, num, wpa, wme, bgscan, bgscaninterval;
2641 if (v == 11)
2642 LINE_CHECK("%s 5.5", tag);
2643 else if (v & 0x80) {
2644 if (v != defmcs)
2645 LINE_CHECK("%s %d", tag, v &~ 0x80);
2646 } else {
2647 if (v != defrate)
2648 LINE_CHECK("%s %d", tag, v/2);
2649 }
2650}
2651
2652static int
2653getssid(int s, int ix, void *data, size_t len, int *plen)
2654{
2149 struct ieee80211req ireq;
2655 struct ieee80211req ireq;
2150 u_int8_t data[32];
2151 struct ieee80211_channel chan;
2152 const struct ieee80211_channel *c;
2153
2154 (void) memset(&ireq, 0, sizeof(ireq));
2155 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
2656
2657 (void) memset(&ireq, 0, sizeof(ireq));
2658 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
2156 ireq.i_data = &data;
2659 ireq.i_type = IEEE80211_IOC_SSID;
2660 ireq.i_val = ix;
2661 ireq.i_data = data;
2662 ireq.i_len = len;
2663 if (ioctl(s, SIOCG80211, &ireq) < 0)
2664 return -1;
2665 *plen = ireq.i_len;
2666 return 0;
2667}
2157
2668
2158 wpa = 0; /* unknown/not set */
2159 bgscan = 0; /* unknown/not set */
2669static void
2670printrssi(const char *tag, int rssi)
2671{
2672 if (rssi & 1)
2673 LINE_CHECK("%s %u.5", tag, rssi/2);
2674 else
2675 LINE_CHECK("%s %u", tag, rssi/2);
2676}
2160
2677
2161 ireq.i_type = IEEE80211_IOC_SSID;
2162 ireq.i_val = -1;
2163 if (ioctl(s, SIOCG80211, &ireq) < 0) {
2678static void
2679ieee80211_status(int s)
2680{
2681 static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
2682 enum ieee80211_opmode opmode = get80211opmode(s);
2683 int i, num, wpa, wme, bgscan, bgscaninterval, val, len, wepmode;
2684 uint8_t data[32];
2685 const struct ieee80211_channel *c;
2686
2687 if (getssid(s, -1, data, sizeof(data), &len) < 0) {
2164 /* If we can't get the SSID, this isn't an 802.11 device. */
2165 return;
2166 }
2688 /* If we can't get the SSID, this isn't an 802.11 device. */
2689 return;
2690 }
2167 num = 0;
2168 ireq.i_type = IEEE80211_IOC_NUMSSIDS;
2169 if (ioctl(s, SIOCG80211, &ireq) >= 0)
2170 num = ireq.i_val;
2691
2692 /*
2693 * Invalidate cached state so printing status for multiple
2694 * if's doesn't reuse the first interfaces' cached state.
2695 */
2696 gotcurchan = 0;
2697 gothtconf = 0;
2698
2699 if (get80211val(s, IEEE80211_IOC_NUMSSIDS, &num) < 0)
2700 num = 0;
2171 printf("\tssid ");
2172 if (num > 1) {
2701 printf("\tssid ");
2702 if (num > 1) {
2173 ireq.i_type = IEEE80211_IOC_SSID;
2174 for (ireq.i_val = 0; ireq.i_val < num; ireq.i_val++) {
2175 if (ioctl(s, SIOCG80211, &ireq) >= 0 && ireq.i_len > 0) {
2176 printf(" %d:", ireq.i_val + 1);
2177 print_string(data, ireq.i_len);
2703 for (i = 0; i < num; i++) {
2704 if (getssid(s, i, data, sizeof(data), &len) >= 0 && len > 0) {
2705 printf(" %d:", i + 1);
2706 print_string(data, len);
2178 }
2179 }
2180 } else
2707 }
2708 }
2709 } else
2181 print_string(data, ireq.i_len);
2710 print_string(data, len);
2182
2711
2183 ireq.i_data = &chan;
2184 ireq.i_len = sizeof(chan);
2185 ireq.i_type = IEEE80211_IOC_CURCHAN;
2186 if (ioctl(s, SIOCG80211, &ireq) < 0) {
2187 /* fall back to legacy ioctl */
2188 ireq.i_data = NULL;
2189 ireq.i_len = 0;
2190 ireq.i_type = IEEE80211_IOC_CHANNEL;
2191 if (ioctl(s, SIOCG80211, &ireq) < 0)
2192 goto end;
2193 getchaninfo(s);
2194 mapchan(&chan, ireq.i_val, 0);
2195 }
2196 c = &chan;
2712 c = getcurchan(s);
2197 if (c->ic_freq != IEEE80211_CHAN_ANY) {
2198 char buf[14];
2199 printf(" channel %d (%u Mhz%s)", c->ic_ieee, c->ic_freq,
2200 get_chaninfo(c, 1, buf, sizeof(buf)));
2201 } else if (verbose)
2202 printf(" channel UNDEF");
2713 if (c->ic_freq != IEEE80211_CHAN_ANY) {
2714 char buf[14];
2715 printf(" channel %d (%u Mhz%s)", c->ic_ieee, c->ic_freq,
2716 get_chaninfo(c, 1, buf, sizeof(buf)));
2717 } else if (verbose)
2718 printf(" channel UNDEF");
2203 ireq.i_data = &data; /* reset data buffer */
2204
2719
2205 ireq.i_type = IEEE80211_IOC_BSSID;
2206 ireq.i_len = IEEE80211_ADDR_LEN;
2207 if (ioctl(s, SIOCG80211, &ireq) >= 0 &&
2208 (memcmp(ireq.i_data, zerobssid, sizeof(zerobssid)) != 0 || verbose))
2209 printf(" bssid %s", ether_ntoa(ireq.i_data));
2720 if (get80211(s, IEEE80211_IOC_BSSID, data, IEEE80211_ADDR_LEN) >= 0 &&
2721 (memcmp(data, zerobssid, sizeof(zerobssid)) != 0 || verbose))
2722 printf(" bssid %s", ether_ntoa((struct ether_addr *)data));
2210
2723
2211 ireq.i_type = IEEE80211_IOC_STATIONNAME;
2212 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2724 if (get80211len(s, IEEE80211_IOC_STATIONNAME, data, sizeof(data), &len) != -1) {
2213 printf("\n\tstationname ");
2725 printf("\n\tstationname ");
2214 print_string(data, ireq.i_len);
2726 print_string(data, len);
2215 }
2216
2217 spacer = ' '; /* force first break */
2218 LINE_BREAK();
2219
2727 }
2728
2729 spacer = ' '; /* force first break */
2730 LINE_BREAK();
2731
2220 ireq.i_type = IEEE80211_IOC_AUTHMODE;
2221 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2222 switch (ireq.i_val) {
2223 case IEEE80211_AUTH_NONE:
2224 LINE_CHECK("authmode NONE");
2732 wpa = 0;
2733 if (get80211val(s, IEEE80211_IOC_AUTHMODE, &val) != -1) {
2734 switch (val) {
2735 case IEEE80211_AUTH_NONE:
2736 LINE_CHECK("authmode NONE");
2737 break;
2738 case IEEE80211_AUTH_OPEN:
2739 LINE_CHECK("authmode OPEN");
2740 break;
2741 case IEEE80211_AUTH_SHARED:
2742 LINE_CHECK("authmode SHARED");
2743 break;
2744 case IEEE80211_AUTH_8021X:
2745 LINE_CHECK("authmode 802.1x");
2746 break;
2747 case IEEE80211_AUTH_WPA:
2748 if (get80211val(s, IEEE80211_IOC_WPA, &wpa) < 0)
2749 wpa = 1; /* default to WPA1 */
2750 switch (wpa) {
2751 case 2:
2752 LINE_CHECK("authmode WPA2/802.11i");
2225 break;
2753 break;
2226 case IEEE80211_AUTH_OPEN:
2227 LINE_CHECK("authmode OPEN");
2754 case 3:
2755 LINE_CHECK("authmode WPA1+WPA2/802.11i");
2228 break;
2756 break;
2229 case IEEE80211_AUTH_SHARED:
2230 LINE_CHECK("authmode SHARED");
2231 break;
2232 case IEEE80211_AUTH_8021X:
2233 LINE_CHECK("authmode 802.1x");
2234 break;
2235 case IEEE80211_AUTH_WPA:
2236 ireq.i_type = IEEE80211_IOC_WPA;
2237 if (ioctl(s, SIOCG80211, &ireq) != -1)
2238 wpa = ireq.i_val;
2239 if (!wpa)
2240 wpa = 1; /* default to WPA1 */
2241 switch (wpa) {
2242 case 2:
2243 LINE_CHECK("authmode WPA2/802.11i");
2244 break;
2245 case 3:
2246 LINE_CHECK("authmode WPA1+WPA2/802.11i");
2247 break;
2248 default:
2249 LINE_CHECK("authmode WPA");
2250 break;
2251 }
2252 break;
2253 case IEEE80211_AUTH_AUTO:
2254 LINE_CHECK("authmode AUTO");
2255 break;
2256 default:
2757 default:
2257 LINE_CHECK("authmode UNKNOWN (0x%x)",
2258 ireq.i_val);
2758 LINE_CHECK("authmode WPA");
2259 break;
2759 break;
2760 }
2761 break;
2762 case IEEE80211_AUTH_AUTO:
2763 LINE_CHECK("authmode AUTO");
2764 break;
2765 default:
2766 LINE_CHECK("authmode UNKNOWN (0x%x)", val);
2767 break;
2260 }
2261 }
2262
2768 }
2769 }
2770
2263 ireq.i_type = IEEE80211_IOC_WEP;
2264 if (ioctl(s, SIOCG80211, &ireq) != -1 &&
2265 ireq.i_val != IEEE80211_WEP_NOSUP) {
2266 int firstkey, wepmode;
2771 if (wpa || verbose) {
2772 if (ioctl(s, IEEE80211_IOC_COUNTERMEASURES, &val) != -1) {
2773 if (val)
2774 LINE_CHECK("countermeasures");
2775 else if (verbose)
2776 LINE_CHECK("-countermeasures");
2777 }
2778 }
2267
2779
2268 wepmode = ireq.i_val;
2780 if (get80211val(s, IEEE80211_IOC_WEP, &wepmode) != -1 &&
2781 wepmode != IEEE80211_WEP_NOSUP) {
2782 int firstkey;
2783
2269 switch (wepmode) {
2784 switch (wepmode) {
2270 case IEEE80211_WEP_OFF:
2271 LINE_CHECK("privacy OFF");
2272 break;
2273 case IEEE80211_WEP_ON:
2274 LINE_CHECK("privacy ON");
2275 break;
2276 case IEEE80211_WEP_MIXED:
2277 LINE_CHECK("privacy MIXED");
2278 break;
2279 default:
2280 LINE_CHECK("privacy UNKNOWN (0x%x)", wepmode);
2281 break;
2785 case IEEE80211_WEP_OFF:
2786 LINE_CHECK("privacy OFF");
2787 break;
2788 case IEEE80211_WEP_ON:
2789 LINE_CHECK("privacy ON");
2790 break;
2791 case IEEE80211_WEP_MIXED:
2792 LINE_CHECK("privacy MIXED");
2793 break;
2794 default:
2795 LINE_CHECK("privacy UNKNOWN (0x%x)", wepmode);
2796 break;
2282 }
2283
2284 /*
2285 * If we get here then we've got WEP support so we need
2286 * to print WEP status.
2287 */
2288
2797 }
2798
2799 /*
2800 * If we get here then we've got WEP support so we need
2801 * to print WEP status.
2802 */
2803
2289 ireq.i_type = IEEE80211_IOC_WEPTXKEY;
2290 if (ioctl(s, SIOCG80211, &ireq) < 0) {
2804 if (get80211val(s, IEEE80211_IOC_WEPTXKEY, &val) < 0) {
2291 warn("WEP support, but no tx key!");
2292 goto end;
2293 }
2805 warn("WEP support, but no tx key!");
2806 goto end;
2807 }
2294 if (ireq.i_val != -1)
2295 LINE_CHECK("deftxkey %d", ireq.i_val+1);
2808 if (val != -1)
2809 LINE_CHECK("deftxkey %d", val+1);
2296 else if (wepmode != IEEE80211_WEP_OFF || verbose)
2297 LINE_CHECK("deftxkey UNDEF");
2298
2810 else if (wepmode != IEEE80211_WEP_OFF || verbose)
2811 LINE_CHECK("deftxkey UNDEF");
2812
2299 ireq.i_type = IEEE80211_IOC_NUMWEPKEYS;
2300 if (ioctl(s, SIOCG80211, &ireq) < 0) {
2813 if (get80211val(s, IEEE80211_IOC_NUMWEPKEYS, &num) < 0) {
2301 warn("WEP support, but no NUMWEPKEYS support!");
2302 goto end;
2303 }
2814 warn("WEP support, but no NUMWEPKEYS support!");
2815 goto end;
2816 }
2304 num = ireq.i_val;
2305
2306 firstkey = 1;
2307 for (i = 0; i < num; i++) {
2308 struct ieee80211req_key ik;
2309
2310 memset(&ik, 0, sizeof(ik));
2311 ik.ik_keyix = i;
2817
2818 firstkey = 1;
2819 for (i = 0; i < num; i++) {
2820 struct ieee80211req_key ik;
2821
2822 memset(&ik, 0, sizeof(ik));
2823 ik.ik_keyix = i;
2312 ireq.i_type = IEEE80211_IOC_WPAKEY;
2313 ireq.i_data = &ik;
2314 ireq.i_len = sizeof(ik);
2315 if (ioctl(s, SIOCG80211, &ireq) < 0) {
2824 if (get80211(s, IEEE80211_IOC_WPAKEY, &ik, sizeof(ik)) < 0) {
2316 warn("WEP support, but can get keys!");
2317 goto end;
2318 }
2319 if (ik.ik_keylen != 0) {
2320 if (verbose)
2321 LINE_BREAK();
2322 printkey(&ik);
2323 firstkey = 0;
2324 }
2325 }
2825 warn("WEP support, but can get keys!");
2826 goto end;
2827 }
2828 if (ik.ik_keylen != 0) {
2829 if (verbose)
2830 LINE_BREAK();
2831 printkey(&ik);
2832 firstkey = 0;
2833 }
2834 }
2326 ireq.i_data = &data; /* reset data buffer */
2835end:
2836 ;
2327 }
2328
2837 }
2838
2329 ireq.i_type = IEEE80211_IOC_POWERSAVE;
2330 if (ioctl(s, SIOCG80211, &ireq) != -1 &&
2331 ireq.i_val != IEEE80211_POWERSAVE_NOSUP ) {
2332 if (ireq.i_val != IEEE80211_POWERSAVE_OFF || verbose) {
2333 switch (ireq.i_val) {
2334 case IEEE80211_POWERSAVE_OFF:
2335 LINE_CHECK("powersavemode OFF");
2336 break;
2337 case IEEE80211_POWERSAVE_CAM:
2338 LINE_CHECK("powersavemode CAM");
2339 break;
2340 case IEEE80211_POWERSAVE_PSP:
2341 LINE_CHECK("powersavemode PSP");
2342 break;
2343 case IEEE80211_POWERSAVE_PSP_CAM:
2344 LINE_CHECK("powersavemode PSP-CAM");
2345 break;
2839 if (get80211val(s, IEEE80211_IOC_POWERSAVE, &val) != -1 &&
2840 val != IEEE80211_POWERSAVE_NOSUP ) {
2841 if (val != IEEE80211_POWERSAVE_OFF || verbose) {
2842 switch (val) {
2843 case IEEE80211_POWERSAVE_OFF:
2844 LINE_CHECK("powersavemode OFF");
2845 break;
2846 case IEEE80211_POWERSAVE_CAM:
2847 LINE_CHECK("powersavemode CAM");
2848 break;
2849 case IEEE80211_POWERSAVE_PSP:
2850 LINE_CHECK("powersavemode PSP");
2851 break;
2852 case IEEE80211_POWERSAVE_PSP_CAM:
2853 LINE_CHECK("powersavemode PSP-CAM");
2854 break;
2346 }
2855 }
2347 ireq.i_type = IEEE80211_IOC_POWERSAVESLEEP;
2348 if (ioctl(s, SIOCG80211, &ireq) != -1)
2349 LINE_CHECK("powersavesleep %d", ireq.i_val);
2856 if (get80211val(s, IEEE80211_IOC_POWERSAVESLEEP, &val) != -1)
2857 LINE_CHECK("powersavesleep %d", val);
2350 }
2351 }
2352
2858 }
2859 }
2860
2353 ireq.i_type = IEEE80211_IOC_TXPOWMAX;
2354 if (ioctl(s, SIOCG80211, &ireq) != -1)
2355 LINE_CHECK("txpowmax %d", ireq.i_val);
2356
2861 if (get80211val(s, IEEE80211_IOC_TXPOWER, &val) != -1) {
2862 if (val & 1)
2863 LINE_CHECK("txpower %d.5", val/2);
2864 else
2865 LINE_CHECK("txpower %d", val/2);
2866 }
2357 if (verbose) {
2867 if (verbose) {
2358 ireq.i_type = IEEE80211_IOC_TXPOWER;
2359 if (ioctl(s, SIOCG80211, &ireq) != -1)
2360 LINE_CHECK("txpower %d", ireq.i_val);
2868 if (get80211val(s, IEEE80211_IOC_TXPOWMAX, &val) != -1)
2869 LINE_CHECK("txpowmax %.1f", val/2.);
2361 }
2362
2870 }
2871
2363 ireq.i_type = IEEE80211_IOC_RTSTHRESHOLD;
2364 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2365 if (ireq.i_val != IEEE80211_RTS_MAX || verbose)
2366 LINE_CHECK("rtsthreshold %d", ireq.i_val);
2872 if (get80211val(s, IEEE80211_IOC_RTSTHRESHOLD, &val) != -1) {
2873 if (val != IEEE80211_RTS_MAX || verbose)
2874 LINE_CHECK("rtsthreshold %d", val);
2367 }
2368
2875 }
2876
2369 ireq.i_type = IEEE80211_IOC_FRAGTHRESHOLD;
2370 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2371 if (ireq.i_val != IEEE80211_FRAG_MAX || verbose)
2372 LINE_CHECK("fragthreshold %d", ireq.i_val);
2877 if (get80211val(s, IEEE80211_IOC_FRAGTHRESHOLD, &val) != -1) {
2878 if (val != IEEE80211_FRAG_MAX || verbose)
2879 LINE_CHECK("fragthreshold %d", val);
2373 }
2880 }
2374 ireq.i_type = IEEE80211_IOC_BMISSTHRESHOLD;
2375 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2376 if (ireq.i_val != IEEE80211_HWBMISS_MAX || verbose)
2377 LINE_CHECK("bmiss %d", ireq.i_val);
2378 }
2379
2380 ireq.i_type = IEEE80211_IOC_MCAST_RATE;
2381 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2382 if (ireq.i_val != 2*1 || verbose) {
2383 if (ireq.i_val == 11)
2384 LINE_CHECK("mcastrate 5.5");
2385 else
2386 LINE_CHECK("mcastrate %d", ireq.i_val/2);
2881 if (opmode == IEEE80211_M_STA || verbose) {
2882 if (get80211val(s, IEEE80211_IOC_BMISSTHRESHOLD, &val) != -1) {
2883 if (val != IEEE80211_HWBMISS_MAX || verbose)
2884 LINE_CHECK("bmiss %d", val);
2387 }
2388 }
2389
2885 }
2886 }
2887
2390 ireq.i_type = IEEE80211_IOC_BGSCAN_INTERVAL;
2391 if (ioctl(s, SIOCG80211, &ireq) != -1)
2392 bgscaninterval = ireq.i_val;
2393 else
2394 bgscaninterval = -1;
2888 if (get80211val(s, IEEE80211_IOC_MCAST_RATE, &val) != -1)
2889 printrate("mcastrate", val, 2*1, 0/*XXX*/);
2395
2890
2396 ireq.i_type = IEEE80211_IOC_SCANVALID;
2397 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2398 if (ireq.i_val != bgscaninterval || verbose)
2399 LINE_CHECK("scanvalid %u", ireq.i_val);
2891 bgscaninterval = -1;
2892 (void) get80211val(s, IEEE80211_IOC_BGSCAN_INTERVAL, &bgscaninterval);
2893
2894 if (get80211val(s, IEEE80211_IOC_SCANVALID, &val) != -1) {
2895 if (val != bgscaninterval || verbose)
2896 LINE_CHECK("scanvalid %u", val);
2400 }
2401
2897 }
2898
2402 ireq.i_type = IEEE80211_IOC_BGSCAN;
2403 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2404 bgscan = ireq.i_val;
2405 if (ireq.i_val)
2899 bgscan = 0;
2900 if (get80211val(s, IEEE80211_IOC_BGSCAN, &bgscan) != -1) {
2901 if (bgscan)
2406 LINE_CHECK("bgscan");
2407 else if (verbose)
2408 LINE_CHECK("-bgscan");
2409 }
2410 if (bgscan || verbose) {
2411 if (bgscaninterval != -1)
2412 LINE_CHECK("bgscanintvl %u", bgscaninterval);
2902 LINE_CHECK("bgscan");
2903 else if (verbose)
2904 LINE_CHECK("-bgscan");
2905 }
2906 if (bgscan || verbose) {
2907 if (bgscaninterval != -1)
2908 LINE_CHECK("bgscanintvl %u", bgscaninterval);
2413 ireq.i_type = IEEE80211_IOC_BGSCAN_IDLE;
2414 if (ioctl(s, SIOCG80211, &ireq) != -1)
2415 LINE_CHECK("bgscanidle %u", ireq.i_val);
2909 if (get80211val(s, IEEE80211_IOC_BGSCAN_IDLE, &val) != -1)
2910 LINE_CHECK("bgscanidle %u", val);
2416 if (IEEE80211_IS_CHAN_A(c) || verbose) {
2911 if (IEEE80211_IS_CHAN_A(c) || verbose) {
2417 ireq.i_type = IEEE80211_IOC_ROAM_RSSI_11A;
2418 if (ioctl(s, SIOCG80211, &ireq) != -1)
2419 LINE_CHECK("roam:rssi11a %d", ireq.i_val);
2420 ireq.i_type = IEEE80211_IOC_ROAM_RATE_11A;
2421 if (ioctl(s, SIOCG80211, &ireq) != -1)
2422 LINE_CHECK("roam:rate11a %u", ireq.i_val/2);
2912 if (get80211val(s, IEEE80211_IOC_ROAM_RSSI_11A, &val) != -1)
2913 printrssi("roam:rssi11a", val);
2914 if (get80211val(s, IEEE80211_IOC_ROAM_RATE_11A, &val) != -1)
2915 printrate("roam:rate11a", val, -1, -1);
2423 }
2424 if (IEEE80211_IS_CHAN_B(c) || verbose) {
2916 }
2917 if (IEEE80211_IS_CHAN_B(c) || verbose) {
2425 ireq.i_type = IEEE80211_IOC_ROAM_RSSI_11B;
2426 if (ioctl(s, SIOCG80211, &ireq) != -1)
2427 LINE_CHECK("roam:rssi11b %d", ireq.i_val);
2428 ireq.i_type = IEEE80211_IOC_ROAM_RATE_11B;
2429 if (ioctl(s, SIOCG80211, &ireq) != -1)
2430 LINE_CHECK("roam:rate11b %u", ireq.i_val/2);
2918 if (get80211val(s, IEEE80211_IOC_ROAM_RSSI_11B, &val) != -1)
2919 printrssi("roam:rssi11b", val);
2920 if (get80211val(s, IEEE80211_IOC_ROAM_RATE_11B, &val) != -1)
2921 printrate("roam:rate11b", val, -1, -1);
2431 }
2432 if (IEEE80211_IS_CHAN_ANYG(c) || verbose) {
2922 }
2923 if (IEEE80211_IS_CHAN_ANYG(c) || verbose) {
2433 ireq.i_type = IEEE80211_IOC_ROAM_RSSI_11G;
2434 if (ioctl(s, SIOCG80211, &ireq) != -1)
2435 LINE_CHECK("roam:rssi11g %d", ireq.i_val);
2436 ireq.i_type = IEEE80211_IOC_ROAM_RATE_11G;
2437 if (ioctl(s, SIOCG80211, &ireq) != -1)
2438 LINE_CHECK("roam:rate11g %u", ireq.i_val/2);
2924 if (get80211val(s, IEEE80211_IOC_ROAM_RSSI_11G, &val) != -1)
2925 printrssi("roam:rssi11g", val);
2926 if (get80211val(s, IEEE80211_IOC_ROAM_RATE_11G, &val) != -1)
2927 printrate("roam:rate11g", val, -1, -1);
2439 }
2440 }
2441
2442 if (IEEE80211_IS_CHAN_ANYG(c) || verbose) {
2928 }
2929 }
2930
2931 if (IEEE80211_IS_CHAN_ANYG(c) || verbose) {
2443 ireq.i_type = IEEE80211_IOC_PUREG;
2444 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2445 if (ireq.i_val)
2932 if (get80211val(s, IEEE80211_IOC_PUREG, &val) != -1) {
2933 if (val)
2446 LINE_CHECK("pureg");
2447 else if (verbose)
2448 LINE_CHECK("-pureg");
2449 }
2934 LINE_CHECK("pureg");
2935 else if (verbose)
2936 LINE_CHECK("-pureg");
2937 }
2450 ireq.i_type = IEEE80211_IOC_PROTMODE;
2451 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2452 switch (ireq.i_val) {
2453 case IEEE80211_PROTMODE_OFF:
2454 LINE_CHECK("protmode OFF");
2455 break;
2456 case IEEE80211_PROTMODE_CTS:
2457 LINE_CHECK("protmode CTS");
2458 break;
2459 case IEEE80211_PROTMODE_RTSCTS:
2460 LINE_CHECK("protmode RTSCTS");
2461 break;
2462 default:
2463 LINE_CHECK("protmode UNKNOWN (0x%x)",
2464 ireq.i_val);
2465 break;
2938 if (get80211val(s, IEEE80211_IOC_PROTMODE, &val) != -1) {
2939 switch (val) {
2940 case IEEE80211_PROTMODE_OFF:
2941 LINE_CHECK("protmode OFF");
2942 break;
2943 case IEEE80211_PROTMODE_CTS:
2944 LINE_CHECK("protmode CTS");
2945 break;
2946 case IEEE80211_PROTMODE_RTSCTS:
2947 LINE_CHECK("protmode RTSCTS");
2948 break;
2949 default:
2950 LINE_CHECK("protmode UNKNOWN (0x%x)", val);
2951 break;
2466 }
2467 }
2468 }
2469
2952 }
2953 }
2954 }
2955
2470 ireq.i_type = IEEE80211_IOC_WME;
2471 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2472 wme = ireq.i_val;
2956 if (IEEE80211_IS_CHAN_HT(c) || verbose) {
2957 gethtconf(s);
2958 switch (htconf & 3) {
2959 case 0:
2960 case 2:
2961 LINE_CHECK("-ht");
2962 break;
2963 case 1:
2964 LINE_CHECK("ht20");
2965 break;
2966 case 3:
2967 if (verbose)
2968 LINE_CHECK("ht");
2969 break;
2970 }
2971 if (get80211val(s, IEEE80211_IOC_HTCOMPAT, &val) != -1) {
2972 if (!val)
2973 LINE_CHECK("-htcompat");
2974 else if (verbose)
2975 LINE_CHECK("htcompat");
2976 }
2977 if (get80211val(s, IEEE80211_IOC_AMPDU, &val) != -1) {
2978 switch (val) {
2979 case 0:
2980 LINE_CHECK("-ampdu");
2981 break;
2982 case 1:
2983 LINE_CHECK("ampdutx -ampdurx");
2984 break;
2985 case 2:
2986 LINE_CHECK("-ampdutx ampdurx");
2987 break;
2988 case 3:
2989 if (verbose)
2990 LINE_CHECK("ampdu");
2991 break;
2992 }
2993 }
2994 if (get80211val(s, IEEE80211_IOC_AMPDU_LIMIT, &val) != -1) {
2995 switch (val) {
2996 case IEEE80211_HTCAP_MAXRXAMPDU_8K:
2997 LINE_CHECK("ampdulimit 8k");
2998 break;
2999 case IEEE80211_HTCAP_MAXRXAMPDU_16K:
3000 LINE_CHECK("ampdulimit 16k");
3001 break;
3002 case IEEE80211_HTCAP_MAXRXAMPDU_32K:
3003 LINE_CHECK("ampdulimit 32k");
3004 break;
3005 case IEEE80211_HTCAP_MAXRXAMPDU_64K:
3006 LINE_CHECK("ampdulimit 64k");
3007 break;
3008 }
3009 }
3010 if (get80211val(s, IEEE80211_IOC_AMPDU_DENSITY, &val) != -1) {
3011 switch (val) {
3012 case IEEE80211_HTCAP_MPDUDENSITY_NA:
3013 if (verbose)
3014 LINE_CHECK("ampdudensity -");
3015 break;
3016 case IEEE80211_HTCAP_MPDUDENSITY_025:
3017 LINE_CHECK("ampdudensity .25");
3018 break;
3019 case IEEE80211_HTCAP_MPDUDENSITY_05:
3020 LINE_CHECK("ampdudensity .5");
3021 break;
3022 case IEEE80211_HTCAP_MPDUDENSITY_1:
3023 LINE_CHECK("ampdudensity 1");
3024 break;
3025 case IEEE80211_HTCAP_MPDUDENSITY_2:
3026 LINE_CHECK("ampdudensity 2");
3027 break;
3028 case IEEE80211_HTCAP_MPDUDENSITY_4:
3029 LINE_CHECK("ampdudensity 4");
3030 break;
3031 case IEEE80211_HTCAP_MPDUDENSITY_8:
3032 LINE_CHECK("ampdudensity 8");
3033 break;
3034 case IEEE80211_HTCAP_MPDUDENSITY_16:
3035 LINE_CHECK("ampdudensity 16");
3036 break;
3037 }
3038 }
3039 if (get80211val(s, IEEE80211_IOC_AMSDU, &val) != -1) {
3040 switch (val) {
3041 case 0:
3042 LINE_CHECK("-amsdu");
3043 break;
3044 case 1:
3045 LINE_CHECK("amsdutx -amsdurx");
3046 break;
3047 case 2:
3048 LINE_CHECK("-amsdutx amsdurx");
3049 break;
3050 case 3:
3051 if (verbose)
3052 LINE_CHECK("amsdu");
3053 break;
3054 }
3055 }
3056 /* XXX amsdu limit */
3057 /* XXX 20/40 */
3058 if (get80211val(s, IEEE80211_IOC_SHORTGI, &val) != -1) {
3059 if (val)
3060 LINE_CHECK("shortgi");
3061 else if (verbose)
3062 LINE_CHECK("-shortgi");
3063 }
3064 if (get80211val(s, IEEE80211_IOC_HTPROTMODE, &val) != -1) {
3065 if (val == IEEE80211_PROTMODE_OFF)
3066 LINE_CHECK("htprotmode OFF");
3067 else if (val != IEEE80211_PROTMODE_RTSCTS)
3068 LINE_CHECK("htprotmode UNKNOWN (0x%x)", val);
3069 else if (verbose)
3070 LINE_CHECK("htprotmode RTSCTS");
3071 }
3072 if (get80211val(s, IEEE80211_IOC_PUREN, &val) != -1) {
3073 if (val)
3074 LINE_CHECK("puren");
3075 else if (verbose)
3076 LINE_CHECK("-puren");
3077 }
3078 }
3079
3080 if (get80211val(s, IEEE80211_IOC_WME, &wme) != -1) {
2473 if (wme)
2474 LINE_CHECK("wme");
2475 else if (verbose)
2476 LINE_CHECK("-wme");
2477 } else
2478 wme = 0;
2479
3081 if (wme)
3082 LINE_CHECK("wme");
3083 else if (verbose)
3084 LINE_CHECK("-wme");
3085 } else
3086 wme = 0;
3087
2480 ireq.i_type = IEEE80211_IOC_BURST;
2481 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2482 if (ireq.i_val)
3088 if (get80211val(s, IEEE80211_IOC_BURST, &val) != -1) {
3089 if (val)
2483 LINE_CHECK("burst");
2484 else if (verbose)
2485 LINE_CHECK("-burst");
2486 }
2487
3090 LINE_CHECK("burst");
3091 else if (verbose)
3092 LINE_CHECK("-burst");
3093 }
3094
2488 ireq.i_type = IEEE80211_IOC_FF;
2489 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2490 if (ireq.i_val)
3095 if (get80211val(s, IEEE80211_IOC_FF, &val) != -1) {
3096 if (val)
2491 LINE_CHECK("ff");
2492 else if (verbose)
2493 LINE_CHECK("-ff");
2494 }
3097 LINE_CHECK("ff");
3098 else if (verbose)
3099 LINE_CHECK("-ff");
3100 }
2495 ireq.i_type = IEEE80211_IOC_TURBOP;
2496 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2497 if (ireq.i_val)
3101 if (get80211val(s, IEEE80211_IOC_TURBOP, &val) != -1) {
3102 if (val)
2498 LINE_CHECK("dturbo");
2499 else if (verbose)
2500 LINE_CHECK("-dturbo");
2501 }
2502
2503 if (opmode == IEEE80211_M_HOSTAP) {
3103 LINE_CHECK("dturbo");
3104 else if (verbose)
3105 LINE_CHECK("-dturbo");
3106 }
3107
3108 if (opmode == IEEE80211_M_HOSTAP) {
2504 ireq.i_type = IEEE80211_IOC_HIDESSID;
2505 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2506 if (ireq.i_val)
3109 if (get80211val(s, IEEE80211_IOC_HIDESSID, &val) != -1) {
3110 if (val)
2507 LINE_CHECK("hidessid");
2508 else if (verbose)
2509 LINE_CHECK("-hidessid");
2510 }
3111 LINE_CHECK("hidessid");
3112 else if (verbose)
3113 LINE_CHECK("-hidessid");
3114 }
2511
2512 ireq.i_type = IEEE80211_IOC_APBRIDGE;
2513 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2514 if (!ireq.i_val)
3115 if (get80211val(s, IEEE80211_IOC_APBRIDGE, &val) != -1) {
3116 if (!val)
2515 LINE_CHECK("-apbridge");
2516 else if (verbose)
2517 LINE_CHECK("apbridge");
2518 }
3117 LINE_CHECK("-apbridge");
3118 else if (verbose)
3119 LINE_CHECK("apbridge");
3120 }
3121 if (get80211val(s, IEEE80211_IOC_DTIM_PERIOD, &val) != -1)
3122 LINE_CHECK("dtimperiod %u", val);
2519
3123
2520 ireq.i_type = IEEE80211_IOC_DTIM_PERIOD;
2521 if (ioctl(s, SIOCG80211, &ireq) != -1)
2522 LINE_CHECK("dtimperiod %u", ireq.i_val);
2523
2524 ireq.i_type = IEEE80211_IOC_DOTH;
2525 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2526 if (!ireq.i_val)
3124 if (get80211val(s, IEEE80211_IOC_DOTH, &val) != -1) {
3125 if (!val)
2527 LINE_CHECK("-doth");
2528 else if (verbose)
2529 LINE_CHECK("doth");
2530 }
3126 LINE_CHECK("-doth");
3127 else if (verbose)
3128 LINE_CHECK("doth");
3129 }
3130 if (get80211val(s, IEEE80211_IOC_INACTIVITY, &val) != -1) {
3131 if (!val)
3132 LINE_CHECK("-inact");
3133 else if (verbose)
3134 LINE_CHECK("inact");
3135 }
2531 } else {
3136 } else {
2532 ireq.i_type = IEEE80211_IOC_ROAMING;
2533 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2534 if (ireq.i_val != IEEE80211_ROAMING_AUTO || verbose) {
2535 switch (ireq.i_val) {
3137 if (get80211val(s, IEEE80211_IOC_ROAMING, &val) != -1) {
3138 if (val != IEEE80211_ROAMING_AUTO || verbose) {
3139 switch (val) {
2536 case IEEE80211_ROAMING_DEVICE:
2537 LINE_CHECK("roaming DEVICE");
2538 break;
2539 case IEEE80211_ROAMING_AUTO:
2540 LINE_CHECK("roaming AUTO");
2541 break;
2542 case IEEE80211_ROAMING_MANUAL:
2543 LINE_CHECK("roaming MANUAL");
2544 break;
2545 default:
2546 LINE_CHECK("roaming UNKNOWN (0x%x)",
3140 case IEEE80211_ROAMING_DEVICE:
3141 LINE_CHECK("roaming DEVICE");
3142 break;
3143 case IEEE80211_ROAMING_AUTO:
3144 LINE_CHECK("roaming AUTO");
3145 break;
3146 case IEEE80211_ROAMING_MANUAL:
3147 LINE_CHECK("roaming MANUAL");
3148 break;
3149 default:
3150 LINE_CHECK("roaming UNKNOWN (0x%x)",
2547 ireq.i_val);
3151 val);
2548 break;
2549 }
2550 }
2551 }
2552 }
3152 break;
3153 }
3154 }
3155 }
3156 }
2553 ireq.i_type = IEEE80211_IOC_BEACON_INTERVAL;
2554 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2555 if (ireq.i_val)
2556 LINE_CHECK("bintval %u", ireq.i_val);
2557 else if (verbose)
2558 LINE_CHECK("bintval %u", ireq.i_val);
3157 if (get80211val(s, IEEE80211_IOC_BEACON_INTERVAL, &val) != -1) {
3158 /* XXX default define not visible */
3159 if (val != 100 || verbose)
3160 LINE_CHECK("bintval %u", val);
2559 }
2560
2561 if (wme && verbose) {
2562 LINE_BREAK();
2563 list_wme(s);
2564 }
3161 }
3162
3163 if (wme && verbose) {
3164 LINE_BREAK();
3165 list_wme(s);
3166 }
3167 LINE_BREAK();
3168}
2565
3169
2566 if (wpa) {
2567 ireq.i_type = IEEE80211_IOC_COUNTERMEASURES;
2568 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2569 if (ireq.i_val)
2570 LINE_CHECK("countermeasures");
2571 else if (verbose)
2572 LINE_CHECK("-countermeasures");
2573 }
2574#if 0
2575 /* XXX not interesting with WPA done in user space */
2576 ireq.i_type = IEEE80211_IOC_KEYMGTALGS;
2577 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2578 }
3170static int
3171get80211(int s, int type, void *data, int len)
3172{
3173 struct ieee80211req ireq;
2579
3174
2580 ireq.i_type = IEEE80211_IOC_MCASTCIPHER;
2581 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2582 LINE_CHECK("mcastcipher ");
2583 printcipher(s, &ireq, IEEE80211_IOC_MCASTKEYLEN);
2584 spacer = ' ';
2585 }
3175 (void) memset(&ireq, 0, sizeof(ireq));
3176 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
3177 ireq.i_type = type;
3178 ireq.i_data = data;
3179 ireq.i_len = len;
3180 return ioctl(s, SIOCG80211, &ireq);
3181}
2586
3182
2587 ireq.i_type = IEEE80211_IOC_UCASTCIPHER;
2588 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2589 LINE_CHECK("ucastcipher ");
2590 printcipher(s, &ireq, IEEE80211_IOC_UCASTKEYLEN);
2591 }
3183static int
3184get80211len(int s, int type, void *data, int len, int *plen)
3185{
3186 struct ieee80211req ireq;
2592
3187
2593 if (wpa & 2) {
2594 ireq.i_type = IEEE80211_IOC_RSNCAPS;
2595 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2596 LINE_CHECK("RSN caps 0x%x", ireq.i_val);
2597 spacer = ' ';
2598 }
2599 }
3188 (void) memset(&ireq, 0, sizeof(ireq));
3189 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
3190 ireq.i_type = type;
3191 ireq.i_len = len;
3192 ireq.i_data = data;
3193 if (ioctl(s, SIOCG80211, &ireq) < 0)
3194 return -1;
3195 *plen = ireq.i_len;
3196 return 0;
3197}
2600
3198
2601 ireq.i_type = IEEE80211_IOC_UCASTCIPHERS;
2602 if (ioctl(s, SIOCG80211, &ireq) != -1) {
2603 }
2604#endif
2605 LINE_BREAK();
2606 }
2607 LINE_BREAK();
3199static int
3200get80211val(int s, int type, int *val)
3201{
3202 struct ieee80211req ireq;
2608
3203
2609end:
2610 return;
3204 (void) memset(&ireq, 0, sizeof(ireq));
3205 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
3206 ireq.i_type = type;
3207 if (ioctl(s, SIOCG80211, &ireq) < 0)
3208 return -1;
3209 *val = ireq.i_val;
3210 return 0;
2611}
2612
2613static void
2614set80211(int s, int type, int val, int len, void *data)
2615{
2616 struct ieee80211req ireq;
2617
2618 (void) memset(&ireq, 0, sizeof(ireq));

--- 162 unchanged lines hidden (view full) ---

2781 DEF_CMD_ARG("roam:rate11b", set80211roamrate11b),
2782 DEF_CMD_ARG("roam:rate11g", set80211roamrate11g),
2783 DEF_CMD_ARG("mcastrate", set80211mcastrate),
2784 DEF_CMD_ARG("fragthreshold", set80211fragthreshold),
2785 DEF_CMD("burst", 1, set80211burst),
2786 DEF_CMD("-burst", 0, set80211burst),
2787 DEF_CMD_ARG("bmiss", set80211bmissthreshold),
2788 DEF_CMD_ARG("bmissthreshold", set80211bmissthreshold),
3211}
3212
3213static void
3214set80211(int s, int type, int val, int len, void *data)
3215{
3216 struct ieee80211req ireq;
3217
3218 (void) memset(&ireq, 0, sizeof(ireq));

--- 162 unchanged lines hidden (view full) ---

3381 DEF_CMD_ARG("roam:rate11b", set80211roamrate11b),
3382 DEF_CMD_ARG("roam:rate11g", set80211roamrate11g),
3383 DEF_CMD_ARG("mcastrate", set80211mcastrate),
3384 DEF_CMD_ARG("fragthreshold", set80211fragthreshold),
3385 DEF_CMD("burst", 1, set80211burst),
3386 DEF_CMD("-burst", 0, set80211burst),
3387 DEF_CMD_ARG("bmiss", set80211bmissthreshold),
3388 DEF_CMD_ARG("bmissthreshold", set80211bmissthreshold),
3389 DEF_CMD("shortgi", 1, set80211shortgi),
3390 DEF_CMD("-shortgi", 0, set80211shortgi),
3391 DEF_CMD("ampdurx", 2, set80211ampdu),
3392 DEF_CMD("-ampdurx", -2, set80211ampdu),
3393 DEF_CMD("ampdutx", 1, set80211ampdu),
3394 DEF_CMD("-ampdutx", -1, set80211ampdu),
3395 DEF_CMD("ampdu", 3, set80211ampdu), /* NB: tx+rx */
3396 DEF_CMD("-ampdu", -3, set80211ampdu),
3397 DEF_CMD_ARG("ampdulimit", set80211ampdulimit),
3398 DEF_CMD_ARG("ampdudensity", set80211ampdudensity),
3399 DEF_CMD("amsdurx", 2, set80211amsdu),
3400 DEF_CMD("-amsdurx", -2, set80211amsdu),
3401 DEF_CMD("amsdutx", 1, set80211amsdu),
3402 DEF_CMD("-amsdutx", -1, set80211amsdu),
3403 DEF_CMD("amsdu", 3, set80211amsdu), /* NB: tx+rx */
3404 DEF_CMD("-amsdu", -3, set80211amsdu),
3405 DEF_CMD_ARG("amsdulimit", set80211amsdulimit),
3406 DEF_CMD("puren", 1, set80211puren),
3407 DEF_CMD("-puren", 0, set80211puren),
2789 DEF_CMD("doth", 1, set80211doth),
2790 DEF_CMD("-doth", 0, set80211doth),
3408 DEF_CMD("doth", 1, set80211doth),
3409 DEF_CMD("-doth", 0, set80211doth),
3410 DEF_CMD("htcompat", 1, set80211htcompat),
3411 DEF_CMD("-htcompat", 0, set80211htcompat),
3412 DEF_CMD("inact", 1, set80211inact),
3413 DEF_CMD("-inact", 0, set80211inact),
3414 DEF_CMD_ARG("htprotmode", set80211htprotmode),
3415 DEF_CMD("ht20", 1, set80211htconf),
3416 DEF_CMD("-ht20", 0, set80211htconf),
3417 DEF_CMD("ht40", 3, set80211htconf), /* NB: 20+40 */
3418 DEF_CMD("-ht40", 0, set80211htconf),
3419 DEF_CMD("ht", 3, set80211htconf), /* NB: 20+40 */
3420 DEF_CMD("-ht", 0, set80211htconf),
2791};
2792static struct afswtch af_ieee80211 = {
2793 .af_name = "af_ieee80211",
2794 .af_af = AF_UNSPEC,
2795 .af_other_status = ieee80211_status,
2796};
2797
2798static __constructor void
2799ieee80211_ctor(void)
2800{
2801#define N(a) (sizeof(a) / sizeof(a[0]))
2802 int i;
2803
2804 for (i = 0; i < N(ieee80211_cmds); i++)
2805 cmd_register(&ieee80211_cmds[i]);
2806 af_register(&af_ieee80211);
2807#undef N
2808}
3421};
3422static struct afswtch af_ieee80211 = {
3423 .af_name = "af_ieee80211",
3424 .af_af = AF_UNSPEC,
3425 .af_other_status = ieee80211_status,
3426};
3427
3428static __constructor void
3429ieee80211_ctor(void)
3430{
3431#define N(a) (sizeof(a) / sizeof(a[0]))
3432 int i;
3433
3434 for (i = 0; i < N(ieee80211_cmds); i++)
3435 cmd_register(&ieee80211_cmds[i]);
3436 af_register(&af_ieee80211);
3437#undef N
3438}