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. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. The name of The Aerospace Corporation may not be used to endorse or 13 * promote products derived from this software. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE 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. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. The name of The Aerospace Corporation may not be used to endorse or 13 * promote products derived from this software. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE 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, 36 * NASA Ames Research Center. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by the NetBSD 49 * Foundation, Inc. and its contributors. 50 * 4. Neither the name of The NetBSD Foundation nor the names of its 51 * contributors may be used to endorse or promote products derived 52 * from this software without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 55 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 64 * POSSIBILITY OF SUCH DAMAGE. 65 */ 66 67#include <sys/param.h> 68#include <sys/ioctl.h> 69#include <sys/socket.h> 70#include <sys/sysctl.h> 71#include <sys/time.h> 72 73#include <net/ethernet.h> 74#include <net/if.h> 75#include <net/if_dl.h> 76#include <net/if_types.h> 77#include <net/if_media.h> 78#include <net/route.h> 79 80#include <net80211/ieee80211.h> 81#include <net80211/ieee80211_crypto.h> 82#include <net80211/ieee80211_ioctl.h> 83 84#include <ctype.h> 85#include <err.h> 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, 36 * NASA Ames Research Center. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by the NetBSD 49 * Foundation, Inc. and its contributors. 50 * 4. Neither the name of The NetBSD Foundation nor the names of its 51 * contributors may be used to endorse or promote products derived 52 * from this software without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 55 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 64 * POSSIBILITY OF SUCH DAMAGE. 65 */ 66 67#include <sys/param.h> 68#include <sys/ioctl.h> 69#include <sys/socket.h> 70#include <sys/sysctl.h> 71#include <sys/time.h> 72 73#include <net/ethernet.h> 74#include <net/if.h> 75#include <net/if_dl.h> 76#include <net/if_types.h> 77#include <net/if_media.h> 78#include <net/route.h> 79 80#include <net80211/ieee80211.h> 81#include <net80211/ieee80211_crypto.h> 82#include <net80211/ieee80211_ioctl.h> 83 84#include <ctype.h> 85#include <err.h> 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. 133 */ 134static int 135canpromote(int i, int from, int to) 136{ 137 const struct ieee80211_channel *fc = &chaninfo.ic_chans[i]; 138 int j; 139 140 if ((fc->ic_flags & from) != from) 141 return i; 142 /* NB: quick check exploiting ordering of chans w/ same frequency */ 143 if (i+1 < chaninfo.ic_nchans && 144 chaninfo.ic_chans[i+1].ic_freq == fc->ic_freq && 145 (chaninfo.ic_chans[i+1].ic_flags & to) == to) 146 return i+1; 147 /* brute force search in case channel list is not ordered */ 148 for (j = 0; j < chaninfo.ic_nchans; j++) { 149 const struct ieee80211_channel *tc = &chaninfo.ic_chans[j]; 150 if (j != i && 151 tc->ic_freq == fc->ic_freq && (tc->ic_flags & to) == to) 152 return j; 153 } 154 return i; 155} 156 157/* 158 * Handle channel promotion. When a channel is specified with 159 * only a frequency we want to promote it to the ``best'' channel 160 * available. The channel list has separate entries for 11b, 11g, 161 * 11a, and 11n[ga] channels so specifying a frequency w/o any 162 * attributes requires we upgrade, e.g. from 11b -> 11g. This 163 * gets complicated when the channel is specified on the same 164 * command line with a media request that constrains the available 165 * channe list (e.g. mode 11a); we want to honor that to avoid 166 * confusing behaviour. 167 */ 168static int 169promote(int i) 170{ 171 /* 172 * Query the current mode of the interface in case it's 173 * constrained (e.g. to 11a). We must do this carefully 174 * as there may be a pending ifmedia request in which case 175 * asking the kernel will give us the wrong answer. This 176 * is an unfortunate side-effect of the way ifconfig is 177 * structure for modularity (yech). 178 * 179 * NB: ifmr is actually setup in getchaninfo (above); we 180 * assume it's called coincident with to this call so 181 * we have a ``current setting''; otherwise we must pass 182 * the socket descriptor down to here so we can make 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. 173 */ 174static int 175canpromote(int i, int from, int to) 176{ 177 const struct ieee80211_channel *fc = &chaninfo.ic_chans[i]; 178 int j; 179 180 if ((fc->ic_flags & from) != from) 181 return i; 182 /* NB: quick check exploiting ordering of chans w/ same frequency */ 183 if (i+1 < chaninfo.ic_nchans && 184 chaninfo.ic_chans[i+1].ic_freq == fc->ic_freq && 185 (chaninfo.ic_chans[i+1].ic_flags & to) == to) 186 return i+1; 187 /* brute force search in case channel list is not ordered */ 188 for (j = 0; j < chaninfo.ic_nchans; j++) { 189 const struct ieee80211_channel *tc = &chaninfo.ic_chans[j]; 190 if (j != i && 191 tc->ic_freq == fc->ic_freq && (tc->ic_flags & to) == to) 192 return j; 193 } 194 return i; 195} 196 197/* 198 * Handle channel promotion. When a channel is specified with 199 * only a frequency we want to promote it to the ``best'' channel 200 * available. The channel list has separate entries for 11b, 11g, 201 * 11a, and 11n[ga] channels so specifying a frequency w/o any 202 * attributes requires we upgrade, e.g. from 11b -> 11g. This 203 * gets complicated when the channel is specified on the same 204 * command line with a media request that constrains the available 205 * channe list (e.g. mode 11a); we want to honor that to avoid 206 * confusing behaviour. 207 */ 208static int 209promote(int i) 210{ 211 /* 212 * Query the current mode of the interface in case it's 213 * constrained (e.g. to 11a). We must do this carefully 214 * as there may be a pending ifmedia request in which case 215 * asking the kernel will give us the wrong answer. This 216 * is an unfortunate side-effect of the way ifconfig is 217 * structure for modularity (yech). 218 * 219 * NB: ifmr is actually setup in getchaninfo (above); we 220 * assume it's called coincident with to this call so 221 * we have a ``current setting''; otherwise we must pass 222 * the socket descriptor down to here so we can make 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; 214 215 for (i = 0; i < chaninfo.ic_nchans; i++) { 216 const struct ieee80211_channel *c = &chaninfo.ic_chans[i]; 217 218 if (c->ic_freq == freq && (c->ic_flags & flags) == flags) { 219 if (flags == 0) { 220 /* when ambiguous promote to ``best'' */ 221 c = &chaninfo.ic_chans[promote(i)]; 222 } 223 *chan = *c; 224 return; 225 } 226 } 227 errx(1, "unknown/undefined frequency %u/0x%x", freq, flags); 228} 229 230static void 231mapchan(struct ieee80211_channel *chan, int ieee, int flags) 232{ 233 int i; 234 235 for (i = 0; i < chaninfo.ic_nchans; i++) { 236 const struct ieee80211_channel *c = &chaninfo.ic_chans[i]; 237 238 if (c->ic_ieee == ieee && (c->ic_flags & flags) == flags) { 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; 258 259 for (i = 0; i < chaninfo.ic_nchans; i++) { 260 const struct ieee80211_channel *c = &chaninfo.ic_chans[i]; 261 262 if (c->ic_freq == freq && (c->ic_flags & flags) == flags) { 263 if (flags == 0) { 264 /* when ambiguous promote to ``best'' */ 265 c = &chaninfo.ic_chans[promote(i)]; 266 } 267 *chan = *c; 268 return; 269 } 270 } 271 errx(1, "unknown/undefined frequency %u/0x%x", freq, flags); 272} 273 274static void 275mapchan(struct ieee80211_channel *chan, int ieee, int flags) 276{ 277 int i; 278 279 for (i = 0; i < chaninfo.ic_nchans; i++) { 280 const struct ieee80211_channel *c = &chaninfo.ic_chans[i]; 281 282 if (c->ic_ieee == ieee && (c->ic_flags & flags) == flags) { 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]; 271 272 ssid = 0; 273 len = strlen(val); 274 if (len > 2 && isdigit(val[0]) && val[1] == ':') { 275 ssid = atoi(val)-1; 276 val += 2; 277 } 278 279 bzero(data, sizeof(data)); 280 len = sizeof(data); 281 if (get_string(val, NULL, data, &len) == NULL) 282 exit(1); 283 284 set80211(s, IEEE80211_IOC_SSID, ssid, len, data); 285} 286 287static void 288set80211stationname(const char *val, int d, int s, const struct afswtch *rafp) 289{ 290 int len; 291 u_int8_t data[33]; 292 293 bzero(data, sizeof(data)); 294 len = sizeof(data); 295 get_string(val, NULL, data, &len); 296 297 set80211(s, IEEE80211_IOC_STATIONNAME, 0, len, data); 298} 299 300/* 301 * Parse a channel specification for attributes/flags. 302 * The syntax is: 303 * freq/xx channel width (5,10,20,40,40+,40-) 304 * freq:mode channel mode (a,b,g,h,n,t,s,d) 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]; 332 333 ssid = 0; 334 len = strlen(val); 335 if (len > 2 && isdigit(val[0]) && val[1] == ':') { 336 ssid = atoi(val)-1; 337 val += 2; 338 } 339 340 bzero(data, sizeof(data)); 341 len = sizeof(data); 342 if (get_string(val, NULL, data, &len) == NULL) 343 exit(1); 344 345 set80211(s, IEEE80211_IOC_SSID, ssid, len, data); 346} 347 348static void 349set80211stationname(const char *val, int d, int s, const struct afswtch *rafp) 350{ 351 int len; 352 u_int8_t data[33]; 353 354 bzero(data, sizeof(data)); 355 len = sizeof(data); 356 get_string(val, NULL, data, &len); 357 358 set80211(s, IEEE80211_IOC_STATIONNAME, 0, len, data); 359} 360 361/* 362 * Parse a channel specification for attributes/flags. 363 * The syntax is: 364 * freq/xx channel width (5,10,20,40,40+,40-) 365 * freq:mode channel mode (a,b,g,h,n,t,s,d) 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) { 324 for (cp++; isalpha((int) *cp); cp++) { 325 /* accept mixed case */ 326 int c = *cp; 327 if (isupper(c)) 328 c = tolower(c); 329 switch (c) { 330 case 'a': /* 802.11a */ 331 flags |= IEEE80211_CHAN_A; 332 break; 333 case 'b': /* 802.11b */ 334 flags |= IEEE80211_CHAN_B; 335 break; 336 case 'g': /* 802.11g */ 337 flags |= IEEE80211_CHAN_G; 338 break; 339 case 'h': /* ht = 802.11n */ 340 case 'n': /* 802.11n */ 341 flags |= _CHAN_HT; /* NB: private */ 342 break; 343 case 'd': /* dt = Atheros Dynamic Turbo */ 344 flags |= IEEE80211_CHAN_TURBO; 345 break; 346 case 't': /* ht, dt, st, t */ 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) { 384 for (cp++; isalpha((int) *cp); cp++) { 385 /* accept mixed case */ 386 int c = *cp; 387 if (isupper(c)) 388 c = tolower(c); 389 switch (c) { 390 case 'a': /* 802.11a */ 391 flags |= IEEE80211_CHAN_A; 392 break; 393 case 'b': /* 802.11b */ 394 flags |= IEEE80211_CHAN_B; 395 break; 396 case 'g': /* 802.11g */ 397 flags |= IEEE80211_CHAN_G; 398 break; 399 case 'h': /* ht = 802.11n */ 400 case 'n': /* 802.11n */ 401 flags |= _CHAN_HT; /* NB: private */ 402 break; 403 case 'd': /* dt = Atheros Dynamic Turbo */ 404 flags |= IEEE80211_CHAN_TURBO; 405 break; 406 case 't': /* ht, dt, st, t */ 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); 364 365 switch (cw) { 366 case 5: 367 flags |= IEEE80211_CHAN_QUARTER; 368 break; 369 case 10: 370 flags |= IEEE80211_CHAN_HALF; 371 break; 372 case 20: 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); 424 425 switch (cw) { 426 case 5: 427 flags |= IEEE80211_CHAN_QUARTER; 428 break; 429 case 10: 430 flags |= IEEE80211_CHAN_HALF; 431 break; 432 case 20: 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 394 * HT cw attributes depending on channel use. To give 395 * an explicit 20/40 width for an HT channel you must 396 * indicate it is an HT channel since all HT channels 397 * are also usable for legacy operation; e.g. freq:n/40. 398 */ 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 452 * HT cw attributes depending on channel use. To give 453 * an explicit 20/40 width for an HT channel you must 454 * indicate it is an HT channel since all HT channels 455 * are also usable for legacy operation; e.g. freq:n/40. 456 */ 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 } 434 set80211(s, IEEE80211_IOC_CURCHAN, 0, sizeof(chan), &chan); 435} 436 437static void 438set80211authmode(const char *val, int d, int s, const struct afswtch *rafp) 439{ 440 int mode; 441 442 if (strcasecmp(val, "none") == 0) { 443 mode = IEEE80211_AUTH_NONE; 444 } else if (strcasecmp(val, "open") == 0) { 445 mode = IEEE80211_AUTH_OPEN; 446 } else if (strcasecmp(val, "shared") == 0) { 447 mode = IEEE80211_AUTH_SHARED; 448 } else if (strcasecmp(val, "8021x") == 0) { 449 mode = IEEE80211_AUTH_8021X; 450 } else if (strcasecmp(val, "wpa") == 0) { 451 mode = IEEE80211_AUTH_WPA; 452 } else { 453 errx(1, "unknown authmode"); 454 } 455 456 set80211(s, IEEE80211_IOC_AUTHMODE, mode, 0, NULL); 457} 458 459static void 460set80211powersavemode(const char *val, int d, int s, const struct afswtch *rafp) 461{ 462 int mode; 463 464 if (strcasecmp(val, "off") == 0) { 465 mode = IEEE80211_POWERSAVE_OFF; 466 } else if (strcasecmp(val, "on") == 0) { 467 mode = IEEE80211_POWERSAVE_ON; 468 } else if (strcasecmp(val, "cam") == 0) { 469 mode = IEEE80211_POWERSAVE_CAM; 470 } else if (strcasecmp(val, "psp") == 0) { 471 mode = IEEE80211_POWERSAVE_PSP; 472 } else if (strcasecmp(val, "psp-cam") == 0) { 473 mode = IEEE80211_POWERSAVE_PSP_CAM; 474 } else { 475 errx(1, "unknown powersavemode"); 476 } 477 478 set80211(s, IEEE80211_IOC_POWERSAVE, mode, 0, NULL); 479} 480 481static void 482set80211powersave(const char *val, int d, int s, const struct afswtch *rafp) 483{ 484 if (d == 0) 485 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_OFF, 486 0, NULL); 487 else 488 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_ON, 489 0, NULL); 490} 491 492static void 493set80211powersavesleep(const char *val, int d, int s, const struct afswtch *rafp) 494{ 495 set80211(s, IEEE80211_IOC_POWERSAVESLEEP, atoi(val), 0, NULL); 496} 497 498static void 499set80211wepmode(const char *val, int d, int s, const struct afswtch *rafp) 500{ 501 int mode; 502 503 if (strcasecmp(val, "off") == 0) { 504 mode = IEEE80211_WEP_OFF; 505 } else if (strcasecmp(val, "on") == 0) { 506 mode = IEEE80211_WEP_ON; 507 } else if (strcasecmp(val, "mixed") == 0) { 508 mode = IEEE80211_WEP_MIXED; 509 } else { 510 errx(1, "unknown wep mode"); 511 } 512 513 set80211(s, IEEE80211_IOC_WEP, mode, 0, NULL); 514} 515 516static void 517set80211wep(const char *val, int d, int s, const struct afswtch *rafp) 518{ 519 set80211(s, IEEE80211_IOC_WEP, d, 0, NULL); 520} 521 522static int 523isundefarg(const char *arg) 524{ 525 return (strcmp(arg, "-") == 0 || strncasecmp(arg, "undef", 5) == 0); 526} 527 528static void 529set80211weptxkey(const char *val, int d, int s, const struct afswtch *rafp) 530{ 531 if (isundefarg(val)) 532 set80211(s, IEEE80211_IOC_WEPTXKEY, IEEE80211_KEYIX_NONE, 0, NULL); 533 else 534 set80211(s, IEEE80211_IOC_WEPTXKEY, atoi(val)-1, 0, NULL); 535} 536 537static void 538set80211wepkey(const char *val, int d, int s, const struct afswtch *rafp) 539{ 540 int key = 0; 541 int len; 542 u_int8_t data[IEEE80211_KEYBUF_SIZE]; 543 544 if (isdigit(val[0]) && val[1] == ':') { 545 key = atoi(val)-1; 546 val += 2; 547 } 548 549 bzero(data, sizeof(data)); 550 len = sizeof(data); 551 get_string(val, NULL, data, &len); 552 553 set80211(s, IEEE80211_IOC_WEPKEY, key, len, data); 554} 555 556/* 557 * This function is purely a NetBSD compatability interface. The NetBSD 558 * interface is too inflexible, but it's there so we'll support it since 559 * it's not all that hard. 560 */ 561static void 562set80211nwkey(const char *val, int d, int s, const struct afswtch *rafp) 563{ 564 int txkey; 565 int i, len; 566 u_int8_t data[IEEE80211_KEYBUF_SIZE]; 567 568 set80211(s, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL); 569 570 if (isdigit(val[0]) && val[1] == ':') { 571 txkey = val[0]-'0'-1; 572 val += 2; 573 574 for (i = 0; i < 4; i++) { 575 bzero(data, sizeof(data)); 576 len = sizeof(data); 577 val = get_string(val, ",", data, &len); 578 if (val == NULL) 579 exit(1); 580 581 set80211(s, IEEE80211_IOC_WEPKEY, i, len, data); 582 } 583 } else { 584 bzero(data, sizeof(data)); 585 len = sizeof(data); 586 get_string(val, NULL, data, &len); 587 txkey = 0; 588 589 set80211(s, IEEE80211_IOC_WEPKEY, 0, len, data); 590 591 bzero(data, sizeof(data)); 592 for (i = 1; i < 4; i++) 593 set80211(s, IEEE80211_IOC_WEPKEY, i, 0, data); 594 } 595 596 set80211(s, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL); 597} 598 599static void 600set80211rtsthreshold(const char *val, int d, int s, const struct afswtch *rafp) 601{ 602 set80211(s, IEEE80211_IOC_RTSTHRESHOLD, 603 isundefarg(val) ? IEEE80211_RTS_MAX : atoi(val), 0, NULL); 604} 605 606static void 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 } 502 set80211(s, IEEE80211_IOC_CURCHAN, 0, sizeof(chan), &chan); 503} 504 505static void 506set80211authmode(const char *val, int d, int s, const struct afswtch *rafp) 507{ 508 int mode; 509 510 if (strcasecmp(val, "none") == 0) { 511 mode = IEEE80211_AUTH_NONE; 512 } else if (strcasecmp(val, "open") == 0) { 513 mode = IEEE80211_AUTH_OPEN; 514 } else if (strcasecmp(val, "shared") == 0) { 515 mode = IEEE80211_AUTH_SHARED; 516 } else if (strcasecmp(val, "8021x") == 0) { 517 mode = IEEE80211_AUTH_8021X; 518 } else if (strcasecmp(val, "wpa") == 0) { 519 mode = IEEE80211_AUTH_WPA; 520 } else { 521 errx(1, "unknown authmode"); 522 } 523 524 set80211(s, IEEE80211_IOC_AUTHMODE, mode, 0, NULL); 525} 526 527static void 528set80211powersavemode(const char *val, int d, int s, const struct afswtch *rafp) 529{ 530 int mode; 531 532 if (strcasecmp(val, "off") == 0) { 533 mode = IEEE80211_POWERSAVE_OFF; 534 } else if (strcasecmp(val, "on") == 0) { 535 mode = IEEE80211_POWERSAVE_ON; 536 } else if (strcasecmp(val, "cam") == 0) { 537 mode = IEEE80211_POWERSAVE_CAM; 538 } else if (strcasecmp(val, "psp") == 0) { 539 mode = IEEE80211_POWERSAVE_PSP; 540 } else if (strcasecmp(val, "psp-cam") == 0) { 541 mode = IEEE80211_POWERSAVE_PSP_CAM; 542 } else { 543 errx(1, "unknown powersavemode"); 544 } 545 546 set80211(s, IEEE80211_IOC_POWERSAVE, mode, 0, NULL); 547} 548 549static void 550set80211powersave(const char *val, int d, int s, const struct afswtch *rafp) 551{ 552 if (d == 0) 553 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_OFF, 554 0, NULL); 555 else 556 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_ON, 557 0, NULL); 558} 559 560static void 561set80211powersavesleep(const char *val, int d, int s, const struct afswtch *rafp) 562{ 563 set80211(s, IEEE80211_IOC_POWERSAVESLEEP, atoi(val), 0, NULL); 564} 565 566static void 567set80211wepmode(const char *val, int d, int s, const struct afswtch *rafp) 568{ 569 int mode; 570 571 if (strcasecmp(val, "off") == 0) { 572 mode = IEEE80211_WEP_OFF; 573 } else if (strcasecmp(val, "on") == 0) { 574 mode = IEEE80211_WEP_ON; 575 } else if (strcasecmp(val, "mixed") == 0) { 576 mode = IEEE80211_WEP_MIXED; 577 } else { 578 errx(1, "unknown wep mode"); 579 } 580 581 set80211(s, IEEE80211_IOC_WEP, mode, 0, NULL); 582} 583 584static void 585set80211wep(const char *val, int d, int s, const struct afswtch *rafp) 586{ 587 set80211(s, IEEE80211_IOC_WEP, d, 0, NULL); 588} 589 590static int 591isundefarg(const char *arg) 592{ 593 return (strcmp(arg, "-") == 0 || strncasecmp(arg, "undef", 5) == 0); 594} 595 596static void 597set80211weptxkey(const char *val, int d, int s, const struct afswtch *rafp) 598{ 599 if (isundefarg(val)) 600 set80211(s, IEEE80211_IOC_WEPTXKEY, IEEE80211_KEYIX_NONE, 0, NULL); 601 else 602 set80211(s, IEEE80211_IOC_WEPTXKEY, atoi(val)-1, 0, NULL); 603} 604 605static void 606set80211wepkey(const char *val, int d, int s, const struct afswtch *rafp) 607{ 608 int key = 0; 609 int len; 610 u_int8_t data[IEEE80211_KEYBUF_SIZE]; 611 612 if (isdigit(val[0]) && val[1] == ':') { 613 key = atoi(val)-1; 614 val += 2; 615 } 616 617 bzero(data, sizeof(data)); 618 len = sizeof(data); 619 get_string(val, NULL, data, &len); 620 621 set80211(s, IEEE80211_IOC_WEPKEY, key, len, data); 622} 623 624/* 625 * This function is purely a NetBSD compatability interface. The NetBSD 626 * interface is too inflexible, but it's there so we'll support it since 627 * it's not all that hard. 628 */ 629static void 630set80211nwkey(const char *val, int d, int s, const struct afswtch *rafp) 631{ 632 int txkey; 633 int i, len; 634 u_int8_t data[IEEE80211_KEYBUF_SIZE]; 635 636 set80211(s, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL); 637 638 if (isdigit(val[0]) && val[1] == ':') { 639 txkey = val[0]-'0'-1; 640 val += 2; 641 642 for (i = 0; i < 4; i++) { 643 bzero(data, sizeof(data)); 644 len = sizeof(data); 645 val = get_string(val, ",", data, &len); 646 if (val == NULL) 647 exit(1); 648 649 set80211(s, IEEE80211_IOC_WEPKEY, i, len, data); 650 } 651 } else { 652 bzero(data, sizeof(data)); 653 len = sizeof(data); 654 get_string(val, NULL, data, &len); 655 txkey = 0; 656 657 set80211(s, IEEE80211_IOC_WEPKEY, 0, len, data); 658 659 bzero(data, sizeof(data)); 660 for (i = 1; i < 4; i++) 661 set80211(s, IEEE80211_IOC_WEPKEY, i, 0, data); 662 } 663 664 set80211(s, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL); 665} 666 667static void 668set80211rtsthreshold(const char *val, int d, int s, const struct afswtch *rafp) 669{ 670 set80211(s, IEEE80211_IOC_RTSTHRESHOLD, 671 isundefarg(val) ? IEEE80211_RTS_MAX : atoi(val), 0, NULL); 672} 673 674static void 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) 636{ 637 int mode; 638 639 if (strcasecmp(val, "device") == 0) { 640 mode = IEEE80211_ROAMING_DEVICE; 641 } else if (strcasecmp(val, "auto") == 0) { 642 mode = IEEE80211_ROAMING_AUTO; 643 } else if (strcasecmp(val, "manual") == 0) { 644 mode = IEEE80211_ROAMING_MANUAL; 645 } else { 646 errx(1, "unknown roaming mode"); 647 } 648 set80211(s, IEEE80211_IOC_ROAMING, mode, 0, NULL); 649} 650 651static void 652set80211wme(const char *val, int d, int s, const struct afswtch *rafp) 653{ 654 set80211(s, IEEE80211_IOC_WME, d, 0, NULL); 655} 656 657static void 658set80211hidessid(const char *val, int d, int s, const struct afswtch *rafp) 659{ 660 set80211(s, IEEE80211_IOC_HIDESSID, d, 0, NULL); 661} 662 663static void 664set80211apbridge(const char *val, int d, int s, const struct afswtch *rafp) 665{ 666 set80211(s, IEEE80211_IOC_APBRIDGE, d, 0, NULL); 667} 668 669static void 670set80211fastframes(const char *val, int d, int s, const struct afswtch *rafp) 671{ 672 set80211(s, IEEE80211_IOC_FF, d, 0, NULL); 673} 674 675static void 676set80211dturbo(const char *val, int d, int s, const struct afswtch *rafp) 677{ 678 set80211(s, IEEE80211_IOC_TURBOP, d, 0, NULL); 679} 680 681static void 682set80211chanlist(const char *val, int d, int s, const struct afswtch *rafp) 683{ 684 struct ieee80211req_chanlist chanlist; 685#define MAXCHAN (sizeof(chanlist.ic_channels)*NBBY) 686 char *temp, *cp, *tp; 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) 726{ 727 int mode; 728 729 if (strcasecmp(val, "device") == 0) { 730 mode = IEEE80211_ROAMING_DEVICE; 731 } else if (strcasecmp(val, "auto") == 0) { 732 mode = IEEE80211_ROAMING_AUTO; 733 } else if (strcasecmp(val, "manual") == 0) { 734 mode = IEEE80211_ROAMING_MANUAL; 735 } else { 736 errx(1, "unknown roaming mode"); 737 } 738 set80211(s, IEEE80211_IOC_ROAMING, mode, 0, NULL); 739} 740 741static void 742set80211wme(const char *val, int d, int s, const struct afswtch *rafp) 743{ 744 set80211(s, IEEE80211_IOC_WME, d, 0, NULL); 745} 746 747static void 748set80211hidessid(const char *val, int d, int s, const struct afswtch *rafp) 749{ 750 set80211(s, IEEE80211_IOC_HIDESSID, d, 0, NULL); 751} 752 753static void 754set80211apbridge(const char *val, int d, int s, const struct afswtch *rafp) 755{ 756 set80211(s, IEEE80211_IOC_APBRIDGE, d, 0, NULL); 757} 758 759static void 760set80211fastframes(const char *val, int d, int s, const struct afswtch *rafp) 761{ 762 set80211(s, IEEE80211_IOC_FF, d, 0, NULL); 763} 764 765static void 766set80211dturbo(const char *val, int d, int s, const struct afswtch *rafp) 767{ 768 set80211(s, IEEE80211_IOC_TURBOP, d, 0, NULL); 769} 770 771static void 772set80211chanlist(const char *val, int d, int s, const struct afswtch *rafp) 773{ 774 struct ieee80211req_chanlist chanlist; 775#define MAXCHAN (sizeof(chanlist.ic_channels)*NBBY) 776 char *temp, *cp, *tp; 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", 704 first, MAXCHAN); 705 setbit(chanlist.ic_channels, first); 706 break; 707 case 2: 708 if (first > MAXCHAN) 709 errx(-1, "channel %u out of range, max %zu", 710 first, MAXCHAN); 711 if (last > MAXCHAN) 712 errx(-1, "channel %u out of range, max %zu", 713 last, MAXCHAN); 714 if (first > last) 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", 794 first, MAXCHAN); 795 setbit(chanlist.ic_channels, first); 796 break; 797 case 2: 798 if (first > MAXCHAN) 799 errx(-1, "channel %u out of range, max %zu", 800 first, MAXCHAN); 801 if (last > MAXCHAN) 802 errx(-1, "channel %u out of range, max %zu", 803 last, MAXCHAN); 804 if (first > last) 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 734set80211bssid(const char *val, int d, int s, const struct afswtch *rafp) 735{ 736 737 if (!isanyarg(val)) { 738 char *temp; 739 struct sockaddr_dl sdl; 740 741 temp = malloc(strlen(val) + 2); /* ':' and '\0' */ 742 if (temp == NULL) 743 errx(1, "malloc failed"); 744 temp[0] = ':'; 745 strcpy(temp + 1, val); 746 sdl.sdl_len = sizeof(sdl); 747 link_addr(temp, &sdl); 748 free(temp); 749 if (sdl.sdl_alen != IEEE80211_ADDR_LEN) 750 errx(1, "malformed link-level address"); 751 set80211(s, IEEE80211_IOC_BSSID, 0, 752 IEEE80211_ADDR_LEN, LLADDR(&sdl)); 753 } else { 754 uint8_t zerobssid[IEEE80211_ADDR_LEN]; 755 memset(zerobssid, 0, sizeof(zerobssid)); 756 set80211(s, IEEE80211_IOC_BSSID, 0, 757 IEEE80211_ADDR_LEN, zerobssid); 758 } 759} 760 761static int 762getac(const char *ac) 763{ 764 if (strcasecmp(ac, "ac_be") == 0 || strcasecmp(ac, "be") == 0) 765 return WME_AC_BE; 766 if (strcasecmp(ac, "ac_bk") == 0 || strcasecmp(ac, "bk") == 0) 767 return WME_AC_BK; 768 if (strcasecmp(ac, "ac_vi") == 0 || strcasecmp(ac, "vi") == 0) 769 return WME_AC_VI; 770 if (strcasecmp(ac, "ac_vo") == 0 || strcasecmp(ac, "vo") == 0) 771 return WME_AC_VO; 772 errx(1, "unknown wme access class %s", ac); 773} 774 775static 776DECL_CMD_FUNC2(set80211cwmin, ac, val) 777{ 778 set80211(s, IEEE80211_IOC_WME_CWMIN, atoi(val), getac(ac), NULL); 779} 780 781static 782DECL_CMD_FUNC2(set80211cwmax, ac, val) 783{ 784 set80211(s, IEEE80211_IOC_WME_CWMAX, atoi(val), getac(ac), NULL); 785} 786 787static 788DECL_CMD_FUNC2(set80211aifs, ac, val) 789{ 790 set80211(s, IEEE80211_IOC_WME_AIFS, atoi(val), getac(ac), NULL); 791} 792 793static 794DECL_CMD_FUNC2(set80211txoplimit, ac, val) 795{ 796 set80211(s, IEEE80211_IOC_WME_TXOPLIMIT, atoi(val), getac(ac), NULL); 797} 798 799static 800DECL_CMD_FUNC(set80211acm, ac, d) 801{ 802 set80211(s, IEEE80211_IOC_WME_ACM, 1, getac(ac), NULL); 803} 804static 805DECL_CMD_FUNC(set80211noacm, ac, d) 806{ 807 set80211(s, IEEE80211_IOC_WME_ACM, 0, getac(ac), NULL); 808} 809 810static 811DECL_CMD_FUNC(set80211ackpolicy, ac, d) 812{ 813 set80211(s, IEEE80211_IOC_WME_ACKPOLICY, 1, getac(ac), NULL); 814} 815static 816DECL_CMD_FUNC(set80211noackpolicy, ac, d) 817{ 818 set80211(s, IEEE80211_IOC_WME_ACKPOLICY, 0, getac(ac), NULL); 819} 820 821static 822DECL_CMD_FUNC2(set80211bsscwmin, ac, val) 823{ 824 set80211(s, IEEE80211_IOC_WME_CWMIN, atoi(val), 825 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 826} 827 828static 829DECL_CMD_FUNC2(set80211bsscwmax, ac, val) 830{ 831 set80211(s, IEEE80211_IOC_WME_CWMAX, atoi(val), 832 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 833} 834 835static 836DECL_CMD_FUNC2(set80211bssaifs, ac, val) 837{ 838 set80211(s, IEEE80211_IOC_WME_AIFS, atoi(val), 839 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 840} 841 842static 843DECL_CMD_FUNC2(set80211bsstxoplimit, ac, val) 844{ 845 set80211(s, IEEE80211_IOC_WME_TXOPLIMIT, atoi(val), 846 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 847} 848 849static 850DECL_CMD_FUNC(set80211dtimperiod, val, d) 851{ 852 set80211(s, IEEE80211_IOC_DTIM_PERIOD, atoi(val), 0, NULL); 853} 854 855static 856DECL_CMD_FUNC(set80211bintval, val, d) 857{ 858 set80211(s, IEEE80211_IOC_BEACON_INTERVAL, atoi(val), 0, NULL); 859} 860 861static void 862set80211macmac(int s, int op, const char *val) 863{ 864 char *temp; 865 struct sockaddr_dl sdl; 866 867 temp = malloc(strlen(val) + 2); /* ':' and '\0' */ 868 if (temp == NULL) 869 errx(1, "malloc failed"); 870 temp[0] = ':'; 871 strcpy(temp + 1, val); 872 sdl.sdl_len = sizeof(sdl); 873 link_addr(temp, &sdl); 874 free(temp); 875 if (sdl.sdl_alen != IEEE80211_ADDR_LEN) 876 errx(1, "malformed link-level address"); 877 set80211(s, op, 0, IEEE80211_ADDR_LEN, LLADDR(&sdl)); 878} 879 880static 881DECL_CMD_FUNC(set80211addmac, val, d) 882{ 883 set80211macmac(s, IEEE80211_IOC_ADDMAC, val); 884} 885 886static 887DECL_CMD_FUNC(set80211delmac, val, d) 888{ 889 set80211macmac(s, IEEE80211_IOC_DELMAC, val); 890} 891 892static 893DECL_CMD_FUNC(set80211kickmac, val, d) 894{ 895 char *temp; 896 struct sockaddr_dl sdl; 897 struct ieee80211req_mlme mlme; 898 899 temp = malloc(strlen(val) + 2); /* ':' and '\0' */ 900 if (temp == NULL) 901 errx(1, "malloc failed"); 902 temp[0] = ':'; 903 strcpy(temp + 1, val); 904 sdl.sdl_len = sizeof(sdl); 905 link_addr(temp, &sdl); 906 free(temp); 907 if (sdl.sdl_alen != IEEE80211_ADDR_LEN) 908 errx(1, "malformed link-level address"); 909 memset(&mlme, 0, sizeof(mlme)); 910 mlme.im_op = IEEE80211_MLME_DEAUTH; 911 mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; 912 memcpy(mlme.im_macaddr, LLADDR(&sdl), IEEE80211_ADDR_LEN); 913 set80211(s, IEEE80211_IOC_MLME, 0, sizeof(mlme), &mlme); 914} 915 916static 917DECL_CMD_FUNC(set80211maccmd, val, d) 918{ 919 set80211(s, IEEE80211_IOC_MACCMD, d, 0, NULL); 920} 921 922static void 923set80211pureg(const char *val, int d, int s, const struct afswtch *rafp) 924{ 925 set80211(s, IEEE80211_IOC_PUREG, d, 0, NULL); 926} 927 928static void 929set80211bgscan(const char *val, int d, int s, const struct afswtch *rafp) 930{ 931 set80211(s, IEEE80211_IOC_BGSCAN, d, 0, NULL); 932} 933 934static 935DECL_CMD_FUNC(set80211bgscanidle, val, d) 936{ 937 set80211(s, IEEE80211_IOC_BGSCAN_IDLE, atoi(val), 0, NULL); 938} 939 940static 941DECL_CMD_FUNC(set80211bgscanintvl, val, d) 942{ 943 set80211(s, IEEE80211_IOC_BGSCAN_INTERVAL, atoi(val), 0, NULL); 944} 945 946static 947DECL_CMD_FUNC(set80211scanvalid, val, d) 948{ 949 set80211(s, IEEE80211_IOC_SCANVALID, atoi(val), 0, NULL); 950} 951 952static 953DECL_CMD_FUNC(set80211roamrssi11a, val, d) 954{ 955 set80211(s, IEEE80211_IOC_ROAM_RSSI_11A, atoi(val), 0, NULL); 956} 957 958static 959DECL_CMD_FUNC(set80211roamrssi11b, val, d) 960{ 961 set80211(s, IEEE80211_IOC_ROAM_RSSI_11B, atoi(val), 0, NULL); 962} 963 964static 965DECL_CMD_FUNC(set80211roamrssi11g, val, d) 966{ 967 set80211(s, IEEE80211_IOC_ROAM_RSSI_11G, atoi(val), 0, NULL); 968} 969 970static 971DECL_CMD_FUNC(set80211roamrate11a, val, d) 972{ 973 set80211(s, IEEE80211_IOC_ROAM_RATE_11A, 2*atoi(val), 0, NULL); 974} 975 976static 977DECL_CMD_FUNC(set80211roamrate11b, val, d) 978{ 979 set80211(s, IEEE80211_IOC_ROAM_RATE_11B, 2*atoi(val), 0, NULL); 980} 981 982static 983DECL_CMD_FUNC(set80211roamrate11g, val, d) 984{ 985 set80211(s, IEEE80211_IOC_ROAM_RATE_11G, 2*atoi(val), 0, NULL); 986} 987 988static 989DECL_CMD_FUNC(set80211mcastrate, val, d) 990{ 991 set80211(s, IEEE80211_IOC_MCAST_RATE, 2*atoi(val), 0, NULL); 992} 993 994static 995DECL_CMD_FUNC(set80211fragthreshold, val, d) 996{ 997 set80211(s, IEEE80211_IOC_FRAGTHRESHOLD, 998 isundefarg(val) ? IEEE80211_FRAG_MAX : atoi(val), 0, NULL); 999} 1000 1001static 1002DECL_CMD_FUNC(set80211bmissthreshold, val, d) 1003{ 1004 set80211(s, IEEE80211_IOC_BMISSTHRESHOLD, 1005 isundefarg(val) ? IEEE80211_HWBMISS_MAX : atoi(val), 0, NULL); 1006} 1007 1008static void 1009set80211burst(const char *val, int d, int s, const struct afswtch *rafp) 1010{ 1011 set80211(s, IEEE80211_IOC_BURST, d, 0, NULL); 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 825set80211bssid(const char *val, int d, int s, const struct afswtch *rafp) 826{ 827 828 if (!isanyarg(val)) { 829 char *temp; 830 struct sockaddr_dl sdl; 831 832 temp = malloc(strlen(val) + 2); /* ':' and '\0' */ 833 if (temp == NULL) 834 errx(1, "malloc failed"); 835 temp[0] = ':'; 836 strcpy(temp + 1, val); 837 sdl.sdl_len = sizeof(sdl); 838 link_addr(temp, &sdl); 839 free(temp); 840 if (sdl.sdl_alen != IEEE80211_ADDR_LEN) 841 errx(1, "malformed link-level address"); 842 set80211(s, IEEE80211_IOC_BSSID, 0, 843 IEEE80211_ADDR_LEN, LLADDR(&sdl)); 844 } else { 845 uint8_t zerobssid[IEEE80211_ADDR_LEN]; 846 memset(zerobssid, 0, sizeof(zerobssid)); 847 set80211(s, IEEE80211_IOC_BSSID, 0, 848 IEEE80211_ADDR_LEN, zerobssid); 849 } 850} 851 852static int 853getac(const char *ac) 854{ 855 if (strcasecmp(ac, "ac_be") == 0 || strcasecmp(ac, "be") == 0) 856 return WME_AC_BE; 857 if (strcasecmp(ac, "ac_bk") == 0 || strcasecmp(ac, "bk") == 0) 858 return WME_AC_BK; 859 if (strcasecmp(ac, "ac_vi") == 0 || strcasecmp(ac, "vi") == 0) 860 return WME_AC_VI; 861 if (strcasecmp(ac, "ac_vo") == 0 || strcasecmp(ac, "vo") == 0) 862 return WME_AC_VO; 863 errx(1, "unknown wme access class %s", ac); 864} 865 866static 867DECL_CMD_FUNC2(set80211cwmin, ac, val) 868{ 869 set80211(s, IEEE80211_IOC_WME_CWMIN, atoi(val), getac(ac), NULL); 870} 871 872static 873DECL_CMD_FUNC2(set80211cwmax, ac, val) 874{ 875 set80211(s, IEEE80211_IOC_WME_CWMAX, atoi(val), getac(ac), NULL); 876} 877 878static 879DECL_CMD_FUNC2(set80211aifs, ac, val) 880{ 881 set80211(s, IEEE80211_IOC_WME_AIFS, atoi(val), getac(ac), NULL); 882} 883 884static 885DECL_CMD_FUNC2(set80211txoplimit, ac, val) 886{ 887 set80211(s, IEEE80211_IOC_WME_TXOPLIMIT, atoi(val), getac(ac), NULL); 888} 889 890static 891DECL_CMD_FUNC(set80211acm, ac, d) 892{ 893 set80211(s, IEEE80211_IOC_WME_ACM, 1, getac(ac), NULL); 894} 895static 896DECL_CMD_FUNC(set80211noacm, ac, d) 897{ 898 set80211(s, IEEE80211_IOC_WME_ACM, 0, getac(ac), NULL); 899} 900 901static 902DECL_CMD_FUNC(set80211ackpolicy, ac, d) 903{ 904 set80211(s, IEEE80211_IOC_WME_ACKPOLICY, 1, getac(ac), NULL); 905} 906static 907DECL_CMD_FUNC(set80211noackpolicy, ac, d) 908{ 909 set80211(s, IEEE80211_IOC_WME_ACKPOLICY, 0, getac(ac), NULL); 910} 911 912static 913DECL_CMD_FUNC2(set80211bsscwmin, ac, val) 914{ 915 set80211(s, IEEE80211_IOC_WME_CWMIN, atoi(val), 916 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 917} 918 919static 920DECL_CMD_FUNC2(set80211bsscwmax, ac, val) 921{ 922 set80211(s, IEEE80211_IOC_WME_CWMAX, atoi(val), 923 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 924} 925 926static 927DECL_CMD_FUNC2(set80211bssaifs, ac, val) 928{ 929 set80211(s, IEEE80211_IOC_WME_AIFS, atoi(val), 930 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 931} 932 933static 934DECL_CMD_FUNC2(set80211bsstxoplimit, ac, val) 935{ 936 set80211(s, IEEE80211_IOC_WME_TXOPLIMIT, atoi(val), 937 getac(ac)|IEEE80211_WMEPARAM_BSS, NULL); 938} 939 940static 941DECL_CMD_FUNC(set80211dtimperiod, val, d) 942{ 943 set80211(s, IEEE80211_IOC_DTIM_PERIOD, atoi(val), 0, NULL); 944} 945 946static 947DECL_CMD_FUNC(set80211bintval, val, d) 948{ 949 set80211(s, IEEE80211_IOC_BEACON_INTERVAL, atoi(val), 0, NULL); 950} 951 952static void 953set80211macmac(int s, int op, const char *val) 954{ 955 char *temp; 956 struct sockaddr_dl sdl; 957 958 temp = malloc(strlen(val) + 2); /* ':' and '\0' */ 959 if (temp == NULL) 960 errx(1, "malloc failed"); 961 temp[0] = ':'; 962 strcpy(temp + 1, val); 963 sdl.sdl_len = sizeof(sdl); 964 link_addr(temp, &sdl); 965 free(temp); 966 if (sdl.sdl_alen != IEEE80211_ADDR_LEN) 967 errx(1, "malformed link-level address"); 968 set80211(s, op, 0, IEEE80211_ADDR_LEN, LLADDR(&sdl)); 969} 970 971static 972DECL_CMD_FUNC(set80211addmac, val, d) 973{ 974 set80211macmac(s, IEEE80211_IOC_ADDMAC, val); 975} 976 977static 978DECL_CMD_FUNC(set80211delmac, val, d) 979{ 980 set80211macmac(s, IEEE80211_IOC_DELMAC, val); 981} 982 983static 984DECL_CMD_FUNC(set80211kickmac, val, d) 985{ 986 char *temp; 987 struct sockaddr_dl sdl; 988 struct ieee80211req_mlme mlme; 989 990 temp = malloc(strlen(val) + 2); /* ':' and '\0' */ 991 if (temp == NULL) 992 errx(1, "malloc failed"); 993 temp[0] = ':'; 994 strcpy(temp + 1, val); 995 sdl.sdl_len = sizeof(sdl); 996 link_addr(temp, &sdl); 997 free(temp); 998 if (sdl.sdl_alen != IEEE80211_ADDR_LEN) 999 errx(1, "malformed link-level address"); 1000 memset(&mlme, 0, sizeof(mlme)); 1001 mlme.im_op = IEEE80211_MLME_DEAUTH; 1002 mlme.im_reason = IEEE80211_REASON_AUTH_EXPIRE; 1003 memcpy(mlme.im_macaddr, LLADDR(&sdl), IEEE80211_ADDR_LEN); 1004 set80211(s, IEEE80211_IOC_MLME, 0, sizeof(mlme), &mlme); 1005} 1006 1007static 1008DECL_CMD_FUNC(set80211maccmd, val, d) 1009{ 1010 set80211(s, IEEE80211_IOC_MACCMD, d, 0, NULL); 1011} 1012 1013static void 1014set80211pureg(const char *val, int d, int s, const struct afswtch *rafp) 1015{ 1016 set80211(s, IEEE80211_IOC_PUREG, d, 0, NULL); 1017} 1018 1019static void 1020set80211bgscan(const char *val, int d, int s, const struct afswtch *rafp) 1021{ 1022 set80211(s, IEEE80211_IOC_BGSCAN, d, 0, NULL); 1023} 1024 1025static 1026DECL_CMD_FUNC(set80211bgscanidle, val, d) 1027{ 1028 set80211(s, IEEE80211_IOC_BGSCAN_IDLE, atoi(val), 0, NULL); 1029} 1030 1031static 1032DECL_CMD_FUNC(set80211bgscanintvl, val, d) 1033{ 1034 set80211(s, IEEE80211_IOC_BGSCAN_INTERVAL, atoi(val), 0, NULL); 1035} 1036 1037static 1038DECL_CMD_FUNC(set80211scanvalid, val, d) 1039{ 1040 set80211(s, IEEE80211_IOC_SCANVALID, atoi(val), 0, NULL); 1041} 1042 1043static 1044DECL_CMD_FUNC(set80211roamrssi11a, val, d) 1045{ 1046 set80211(s, IEEE80211_IOC_ROAM_RSSI_11A, atoi(val), 0, NULL); 1047} 1048 1049static 1050DECL_CMD_FUNC(set80211roamrssi11b, val, d) 1051{ 1052 set80211(s, IEEE80211_IOC_ROAM_RSSI_11B, atoi(val), 0, NULL); 1053} 1054 1055static 1056DECL_CMD_FUNC(set80211roamrssi11g, val, d) 1057{ 1058 set80211(s, IEEE80211_IOC_ROAM_RSSI_11G, atoi(val), 0, NULL); 1059} 1060 1061static 1062DECL_CMD_FUNC(set80211roamrate11a, val, d) 1063{ 1064 set80211(s, IEEE80211_IOC_ROAM_RATE_11A, 2*atoi(val), 0, NULL); 1065} 1066 1067static 1068DECL_CMD_FUNC(set80211roamrate11b, val, d) 1069{ 1070 set80211(s, IEEE80211_IOC_ROAM_RATE_11B, 2*atoi(val), 0, NULL); 1071} 1072 1073static 1074DECL_CMD_FUNC(set80211roamrate11g, val, d) 1075{ 1076 set80211(s, IEEE80211_IOC_ROAM_RATE_11G, 2*atoi(val), 0, NULL); 1077} 1078 1079static 1080DECL_CMD_FUNC(set80211mcastrate, val, d) 1081{ 1082 set80211(s, IEEE80211_IOC_MCAST_RATE, 2*atoi(val), 0, NULL); 1083} 1084 1085static 1086DECL_CMD_FUNC(set80211fragthreshold, val, d) 1087{ 1088 set80211(s, IEEE80211_IOC_FRAGTHRESHOLD, 1089 isundefarg(val) ? IEEE80211_FRAG_MAX : atoi(val), 0, NULL); 1090} 1091 1092static 1093DECL_CMD_FUNC(set80211bmissthreshold, val, d) 1094{ 1095 set80211(s, IEEE80211_IOC_BMISSTHRESHOLD, 1096 isundefarg(val) ? IEEE80211_HWBMISS_MAX : atoi(val), 0, NULL); 1097} 1098 1099static void 1100set80211burst(const char *val, int d, int s, const struct afswtch *rafp) 1101{ 1102 set80211(s, IEEE80211_IOC_BURST, d, 0, NULL); 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, &du) < 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) 1028 maxrate = rate; 1029 } 1030 return maxrate / 2; 1031} 1032 1033static const char * 1034getcaps(int capinfo) 1035{ 1036 static char capstring[32]; 1037 char *cp = capstring; 1038 1039 if (capinfo & IEEE80211_CAPINFO_ESS) 1040 *cp++ = 'E'; 1041 if (capinfo & IEEE80211_CAPINFO_IBSS) 1042 *cp++ = 'I'; 1043 if (capinfo & IEEE80211_CAPINFO_CF_POLLABLE) 1044 *cp++ = 'c'; 1045 if (capinfo & IEEE80211_CAPINFO_CF_POLLREQ) 1046 *cp++ = 'C'; 1047 if (capinfo & IEEE80211_CAPINFO_PRIVACY) 1048 *cp++ = 'P'; 1049 if (capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) 1050 *cp++ = 'S'; 1051 if (capinfo & IEEE80211_CAPINFO_PBCC) 1052 *cp++ = 'B'; 1053 if (capinfo & IEEE80211_CAPINFO_CHNL_AGILITY) 1054 *cp++ = 'A'; 1055 if (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) 1056 *cp++ = 's'; 1057 if (capinfo & IEEE80211_CAPINFO_RSN) 1058 *cp++ = 'R'; 1059 if (capinfo & IEEE80211_CAPINFO_DSSSOFDM) 1060 *cp++ = 'D'; 1061 *cp = '\0'; 1062 return capstring; 1063} 1064 1065static const char * 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) 1294 maxrate = rate; 1295 } 1296 return maxrate / 2; 1297} 1298 1299static const char * 1300getcaps(int capinfo) 1301{ 1302 static char capstring[32]; 1303 char *cp = capstring; 1304 1305 if (capinfo & IEEE80211_CAPINFO_ESS) 1306 *cp++ = 'E'; 1307 if (capinfo & IEEE80211_CAPINFO_IBSS) 1308 *cp++ = 'I'; 1309 if (capinfo & IEEE80211_CAPINFO_CF_POLLABLE) 1310 *cp++ = 'c'; 1311 if (capinfo & IEEE80211_CAPINFO_CF_POLLREQ) 1312 *cp++ = 'C'; 1313 if (capinfo & IEEE80211_CAPINFO_PRIVACY) 1314 *cp++ = 'P'; 1315 if (capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) 1316 *cp++ = 'S'; 1317 if (capinfo & IEEE80211_CAPINFO_PBCC) 1318 *cp++ = 'B'; 1319 if (capinfo & IEEE80211_CAPINFO_CHNL_AGILITY) 1320 *cp++ = 'A'; 1321 if (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) 1322 *cp++ = 's'; 1323 if (capinfo & IEEE80211_CAPINFO_RSN) 1324 *cp++ = 'R'; 1325 if (capinfo & IEEE80211_CAPINFO_DSSSOFDM) 1326 *cp++ = 'D'; 1327 *cp = '\0'; 1328 return capstring; 1329} 1330 1331static const char * 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 1097printie(const char* tag, const uint8_t *ie, size_t ielen, int maxlen) 1098{ 1099 printf("%s", tag); 1100 if (verbose) { 1101 maxlen -= strlen(tag)+2; 1102 if (2*ielen > maxlen) 1103 maxlen--; 1104 printf("<"); 1105 for (; ielen > 0; ie++, ielen--) { 1106 if (maxlen-- <= 0) 1107 break; 1108 printf("%02x", *ie); 1109 } 1110 if (ielen != 0) 1111 printf("-"); 1112 printf(">"); 1113 } 1114} 1115 1116#define LE_READ_2(p) \ 1117 ((u_int16_t) \ 1118 ((((const u_int8_t *)(p))[0] ) | \ 1119 (((const u_int8_t *)(p))[1] << 8))) 1120#define LE_READ_4(p) \ 1121 ((u_int32_t) \ 1122 ((((const u_int8_t *)(p))[0] ) | \ 1123 (((const u_int8_t *)(p))[1] << 8) | \ 1124 (((const u_int8_t *)(p))[2] << 16) | \ 1125 (((const u_int8_t *)(p))[3] << 24))) 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 1377printie(const char* tag, const uint8_t *ie, size_t ielen, int maxlen) 1378{ 1379 printf("%s", tag); 1380 if (verbose) { 1381 maxlen -= strlen(tag)+2; 1382 if (2*ielen > maxlen) 1383 maxlen--; 1384 printf("<"); 1385 for (; ielen > 0; ie++, ielen--) { 1386 if (maxlen-- <= 0) 1387 break; 1388 printf("%02x", *ie); 1389 } 1390 if (ielen != 0) 1391 printf("-"); 1392 printf(">"); 1393 } 1394} 1395 1396#define LE_READ_2(p) \ 1397 ((u_int16_t) \ 1398 ((((const u_int8_t *)(p))[0] ) | \ 1399 (((const u_int8_t *)(p))[1] << 8))) 1400#define LE_READ_4(p) \ 1401 ((u_int32_t) \ 1402 ((((const u_int8_t *)(p))[0] ) | \ 1403 (((const u_int8_t *)(p))[1] << 8) | \ 1404 (((const u_int8_t *)(p))[2] << 16) | \ 1405 (((const u_int8_t *)(p))[3] << 24))) 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 1170 printf("<"); 1171 if (ath->ath_capability & ATHEROS_CAP_TURBO_PRIME) 1172 printf("DTURBO,"); 1173 if (ath->ath_capability & ATHEROS_CAP_COMPRESSION) 1174 printf("COMP,"); 1175 if (ath->ath_capability & ATHEROS_CAP_FAST_FRAME) 1176 printf("FF,"); 1177 if (ath->ath_capability & ATHEROS_CAP_XR) 1178 printf("XR,"); 1179 if (ath->ath_capability & ATHEROS_CAP_AR) 1180 printf("AR,"); 1181 if (ath->ath_capability & ATHEROS_CAP_BURST) 1182 printf("BURST,"); 1183 if (ath->ath_capability & ATHEROS_CAP_WME) 1184 printf("WME,"); 1185 if (ath->ath_capability & ATHEROS_CAP_BOOST) 1186 printf("BOOST,"); 1187 printf("0x%x>", LE_READ_2(ath->ath_defkeyix)); 1188 } 1189} 1190 1191static const char * 1192wpa_cipher(const u_int8_t *sel) 1193{ 1194#define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1195 u_int32_t w = LE_READ_4(sel); 1196 1197 switch (w) { 1198 case WPA_SEL(WPA_CSE_NULL): 1199 return "NONE"; 1200 case WPA_SEL(WPA_CSE_WEP40): 1201 return "WEP40"; 1202 case WPA_SEL(WPA_CSE_WEP104): 1203 return "WEP104"; 1204 case WPA_SEL(WPA_CSE_TKIP): 1205 return "TKIP"; 1206 case WPA_SEL(WPA_CSE_CCMP): 1207 return "AES-CCMP"; 1208 } 1209 return "?"; /* NB: so 1<< is discarded */ 1210#undef WPA_SEL 1211} 1212 1213static const char * 1214wpa_keymgmt(const u_int8_t *sel) 1215{ 1216#define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1217 u_int32_t w = LE_READ_4(sel); 1218 1219 switch (w) { 1220 case WPA_SEL(WPA_ASE_8021X_UNSPEC): 1221 return "8021X-UNSPEC"; 1222 case WPA_SEL(WPA_ASE_8021X_PSK): 1223 return "8021X-PSK"; 1224 case WPA_SEL(WPA_ASE_NONE): 1225 return "NONE"; 1226 } 1227 return "?"; 1228#undef WPA_SEL 1229} 1230 1231static void 1232printwpaie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) 1233{ 1234 u_int8_t len = ie[1]; 1235 1236 printf("%s", tag); 1237 if (verbose) { 1238 const char *sep; 1239 int n; 1240 1241 ie += 6, len -= 4; /* NB: len is payload only */ 1242 1243 printf("<v%u", LE_READ_2(ie)); 1244 ie += 2, len -= 2; 1245 1246 printf(" mc:%s", wpa_cipher(ie)); 1247 ie += 4, len -= 4; 1248 1249 /* unicast ciphers */ 1250 n = LE_READ_2(ie); 1251 ie += 2, len -= 2; 1252 sep = " uc:"; 1253 for (; n > 0; n--) { 1254 printf("%s%s", sep, wpa_cipher(ie)); 1255 ie += 4, len -= 4; 1256 sep = "+"; 1257 } 1258 1259 /* key management algorithms */ 1260 n = LE_READ_2(ie); 1261 ie += 2, len -= 2; 1262 sep = " km:"; 1263 for (; n > 0; n--) { 1264 printf("%s%s", sep, wpa_keymgmt(ie)); 1265 ie += 4, len -= 4; 1266 sep = "+"; 1267 } 1268 1269 if (len > 2) /* optional capabilities */ 1270 printf(", caps 0x%x", LE_READ_2(ie)); 1271 printf(">"); 1272 } 1273} 1274 1275static const char * 1276rsn_cipher(const u_int8_t *sel) 1277{ 1278#define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1279 u_int32_t w = LE_READ_4(sel); 1280 1281 switch (w) { 1282 case RSN_SEL(RSN_CSE_NULL): 1283 return "NONE"; 1284 case RSN_SEL(RSN_CSE_WEP40): 1285 return "WEP40"; 1286 case RSN_SEL(RSN_CSE_WEP104): 1287 return "WEP104"; 1288 case RSN_SEL(RSN_CSE_TKIP): 1289 return "TKIP"; 1290 case RSN_SEL(RSN_CSE_CCMP): 1291 return "AES-CCMP"; 1292 case RSN_SEL(RSN_CSE_WRAP): 1293 return "AES-OCB"; 1294 } 1295 return "?"; 1296#undef WPA_SEL 1297} 1298 1299static const char * 1300rsn_keymgmt(const u_int8_t *sel) 1301{ 1302#define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1303 u_int32_t w = LE_READ_4(sel); 1304 1305 switch (w) { 1306 case RSN_SEL(RSN_ASE_8021X_UNSPEC): 1307 return "8021X-UNSPEC"; 1308 case RSN_SEL(RSN_ASE_8021X_PSK): 1309 return "8021X-PSK"; 1310 case RSN_SEL(RSN_ASE_NONE): 1311 return "NONE"; 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 1531 printf("<"); 1532 if (ath->ath_capability & ATHEROS_CAP_TURBO_PRIME) 1533 printf("DTURBO,"); 1534 if (ath->ath_capability & ATHEROS_CAP_COMPRESSION) 1535 printf("COMP,"); 1536 if (ath->ath_capability & ATHEROS_CAP_FAST_FRAME) 1537 printf("FF,"); 1538 if (ath->ath_capability & ATHEROS_CAP_XR) 1539 printf("XR,"); 1540 if (ath->ath_capability & ATHEROS_CAP_AR) 1541 printf("AR,"); 1542 if (ath->ath_capability & ATHEROS_CAP_BURST) 1543 printf("BURST,"); 1544 if (ath->ath_capability & ATHEROS_CAP_WME) 1545 printf("WME,"); 1546 if (ath->ath_capability & ATHEROS_CAP_BOOST) 1547 printf("BOOST,"); 1548 printf("0x%x>", LE_READ_2(ath->ath_defkeyix)); 1549 } 1550} 1551 1552static const char * 1553wpa_cipher(const u_int8_t *sel) 1554{ 1555#define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1556 u_int32_t w = LE_READ_4(sel); 1557 1558 switch (w) { 1559 case WPA_SEL(WPA_CSE_NULL): 1560 return "NONE"; 1561 case WPA_SEL(WPA_CSE_WEP40): 1562 return "WEP40"; 1563 case WPA_SEL(WPA_CSE_WEP104): 1564 return "WEP104"; 1565 case WPA_SEL(WPA_CSE_TKIP): 1566 return "TKIP"; 1567 case WPA_SEL(WPA_CSE_CCMP): 1568 return "AES-CCMP"; 1569 } 1570 return "?"; /* NB: so 1<< is discarded */ 1571#undef WPA_SEL 1572} 1573 1574static const char * 1575wpa_keymgmt(const u_int8_t *sel) 1576{ 1577#define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1578 u_int32_t w = LE_READ_4(sel); 1579 1580 switch (w) { 1581 case WPA_SEL(WPA_ASE_8021X_UNSPEC): 1582 return "8021X-UNSPEC"; 1583 case WPA_SEL(WPA_ASE_8021X_PSK): 1584 return "8021X-PSK"; 1585 case WPA_SEL(WPA_ASE_NONE): 1586 return "NONE"; 1587 } 1588 return "?"; 1589#undef WPA_SEL 1590} 1591 1592static void 1593printwpaie(const char *tag, const u_int8_t *ie, size_t ielen, int maxlen) 1594{ 1595 u_int8_t len = ie[1]; 1596 1597 printf("%s", tag); 1598 if (verbose) { 1599 const char *sep; 1600 int n; 1601 1602 ie += 6, len -= 4; /* NB: len is payload only */ 1603 1604 printf("<v%u", LE_READ_2(ie)); 1605 ie += 2, len -= 2; 1606 1607 printf(" mc:%s", wpa_cipher(ie)); 1608 ie += 4, len -= 4; 1609 1610 /* unicast ciphers */ 1611 n = LE_READ_2(ie); 1612 ie += 2, len -= 2; 1613 sep = " uc:"; 1614 for (; n > 0; n--) { 1615 printf("%s%s", sep, wpa_cipher(ie)); 1616 ie += 4, len -= 4; 1617 sep = "+"; 1618 } 1619 1620 /* key management algorithms */ 1621 n = LE_READ_2(ie); 1622 ie += 2, len -= 2; 1623 sep = " km:"; 1624 for (; n > 0; n--) { 1625 printf("%s%s", sep, wpa_keymgmt(ie)); 1626 ie += 4, len -= 4; 1627 sep = "+"; 1628 } 1629 1630 if (len > 2) /* optional capabilities */ 1631 printf(", caps 0x%x", LE_READ_2(ie)); 1632 printf(">"); 1633 } 1634} 1635 1636static const char * 1637rsn_cipher(const u_int8_t *sel) 1638{ 1639#define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1640 u_int32_t w = LE_READ_4(sel); 1641 1642 switch (w) { 1643 case RSN_SEL(RSN_CSE_NULL): 1644 return "NONE"; 1645 case RSN_SEL(RSN_CSE_WEP40): 1646 return "WEP40"; 1647 case RSN_SEL(RSN_CSE_WEP104): 1648 return "WEP104"; 1649 case RSN_SEL(RSN_CSE_TKIP): 1650 return "TKIP"; 1651 case RSN_SEL(RSN_CSE_CCMP): 1652 return "AES-CCMP"; 1653 case RSN_SEL(RSN_CSE_WRAP): 1654 return "AES-OCB"; 1655 } 1656 return "?"; 1657#undef WPA_SEL 1658} 1659 1660static const char * 1661rsn_keymgmt(const u_int8_t *sel) 1662{ 1663#define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1664 u_int32_t w = LE_READ_4(sel); 1665 1666 switch (w) { 1667 case RSN_SEL(RSN_ASE_8021X_UNSPEC): 1668 return "8021X-UNSPEC"; 1669 case RSN_SEL(RSN_ASE_8021X_PSK): 1670 return "8021X-PSK"; 1671 case RSN_SEL(RSN_ASE_NONE): 1672 return "NONE"; 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 1364 * ssid is entirely printable then just copy intact. Otherwise convert 1365 * to hexadecimal. If the result is truncated then replace the last 1366 * three characters with "...". 1367 */ 1368static int 1369copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, size_t essid_len) 1370{ 1371 const u_int8_t *p; 1372 size_t maxlen; 1373 int i; 1374 1375 if (essid_len > bufsize) 1376 maxlen = bufsize; 1377 else 1378 maxlen = essid_len; 1379 /* determine printable or not */ 1380 for (i = 0, p = essid; i < maxlen; i++, p++) { 1381 if (*p < ' ' || *p > 0x7e) 1382 break; 1383 } 1384 if (i != maxlen) { /* not printable, print as hex */ 1385 if (bufsize < 3) 1386 return 0; 1387 strlcpy(buf, "0x", bufsize); 1388 bufsize -= 2; 1389 p = essid; 1390 for (i = 0; i < maxlen && bufsize >= 2; i++) { 1391 sprintf(&buf[2+2*i], "%02x", p[i]); 1392 bufsize -= 2; 1393 } 1394 if (i != essid_len) 1395 memcpy(&buf[2+2*i-3], "...", 3); 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 1723 * ssid is entirely printable then just copy intact. Otherwise convert 1724 * to hexadecimal. If the result is truncated then replace the last 1725 * three characters with "...". 1726 */ 1727static int 1728copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, size_t essid_len) 1729{ 1730 const u_int8_t *p; 1731 size_t maxlen; 1732 int i; 1733 1734 if (essid_len > bufsize) 1735 maxlen = bufsize; 1736 else 1737 maxlen = essid_len; 1738 /* determine printable or not */ 1739 for (i = 0, p = essid; i < maxlen; i++, p++) { 1740 if (*p < ' ' || *p > 0x7e) 1741 break; 1742 } 1743 if (i != maxlen) { /* not printable, print as hex */ 1744 if (bufsize < 3) 1745 return 0; 1746 strlcpy(buf, "0x", bufsize); 1747 bufsize -= 2; 1748 p = essid; 1749 for (i = 0; i < maxlen && bufsize >= 2; i++) { 1750 sprintf(&buf[2+2*i], "%02x", p[i]); 1751 bufsize -= 2; 1752 } 1753 if (i != essid_len) 1754 memcpy(&buf[2+2*i-3], "...", 3); 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" 1482 , "BSSID" 1483 , "CHAN" 1484 , "RATE" 1485 , " S:N" 1486 , "INT" 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" 1945 , "BSSID" 1946 , "CHAN" 1947 , "RATE" 1948 , " S:N" 1949 , "INT" 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 1504 , sr->isr_intval 1505 , getcaps(sr->isr_capinfo) 1506 ); 1507 printies(vp + sr->isr_ssid_len, sr->isr_ie_len, 24); 1508 printf("\n"); 1509 cp += sr->isr_len, len -= sr->isr_len; 1510 } while (len >= sizeof(struct ieee80211req_scan_result)); 1511} 1512 1513#include <net80211/ieee80211_freebsd.h> 1514 1515static void 1516scan_and_wait(int s) 1517{ 1518 struct ieee80211req ireq; 1519 int sroute; 1520 1521 sroute = socket(PF_ROUTE, SOCK_RAW, 0); 1522 if (sroute < 0) { 1523 perror("socket(PF_ROUTE,SOCK_RAW)"); 1524 return; 1525 } 1526 (void) memset(&ireq, 0, sizeof(ireq)); 1527 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 1528 ireq.i_type = IEEE80211_IOC_SCAN_REQ; 1529 /* NB: only root can trigger a scan so ignore errors */ 1530 if (ioctl(s, SIOCS80211, &ireq) >= 0) { 1531 char buf[2048]; 1532 struct if_announcemsghdr *ifan; 1533 struct rt_msghdr *rtm; 1534 1535 do { 1536 if (read(sroute, buf, sizeof(buf)) < 0) { 1537 perror("read(PF_ROUTE)"); 1538 break; 1539 } 1540 rtm = (struct rt_msghdr *) buf; 1541 if (rtm->rtm_version != RTM_VERSION) 1542 break; 1543 ifan = (struct if_announcemsghdr *) rtm; 1544 } while (rtm->rtm_type != RTM_IEEE80211 || 1545 ifan->ifan_what != RTM_IEEE80211_SCAN); 1546 } 1547 close(sroute); 1548} 1549 1550static 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 1967 , sr->isr_intval 1968 , getcaps(sr->isr_capinfo) 1969 ); 1970 printies(vp + sr->isr_ssid_len, sr->isr_ie_len, 24); 1971 printf("\n"); 1972 cp += sr->isr_len, len -= sr->isr_len; 1973 } while (len >= sizeof(struct ieee80211req_scan_result)); 1974} 1975 1976#include <net80211/ieee80211_freebsd.h> 1977 1978static void 1979scan_and_wait(int s) 1980{ 1981 struct ieee80211req ireq; 1982 int sroute; 1983 1984 sroute = socket(PF_ROUTE, SOCK_RAW, 0); 1985 if (sroute < 0) { 1986 perror("socket(PF_ROUTE,SOCK_RAW)"); 1987 return; 1988 } 1989 (void) memset(&ireq, 0, sizeof(ireq)); 1990 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 1991 ireq.i_type = IEEE80211_IOC_SCAN_REQ; 1992 /* NB: only root can trigger a scan so ignore errors */ 1993 if (ioctl(s, SIOCS80211, &ireq) >= 0) { 1994 char buf[2048]; 1995 struct if_announcemsghdr *ifan; 1996 struct rt_msghdr *rtm; 1997 1998 do { 1999 if (read(sroute, buf, sizeof(buf)) < 0) { 2000 perror("read(PF_ROUTE)"); 2001 break; 2002 } 2003 rtm = (struct rt_msghdr *) buf; 2004 if (rtm->rtm_version != RTM_VERSION) 2005 break; 2006 ifan = (struct if_announcemsghdr *) rtm; 2007 } while (rtm->rtm_type != RTM_IEEE80211 || 2008 ifan->ifan_what != RTM_IEEE80211_SCAN); 2009 } 2010 close(sroute); 2011} 2012 2013static 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" 1598 , "CHAN" 1599 , "RATE" 1600 , "RSSI" 1601 , "IDLE" 1602 , "TXSEQ" 1603 , "RXSEQ" 1604 , "CAPS" 1605 , "FLAG" 1606 ); 1607 cp = (const uint8_t *) u.req.info; 1608 do { 1609 const struct ieee80211req_sta_info *si; 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" 2099 , "CHAN" 2100 , "RATE" 2101 , "RSSI" 2102 , "IDLE" 2103 , "TXSEQ" 2104 , "RXSEQ" 2105 , "CAPS" 2106 , "FLAG" 2107 ); 2108 cp = (const uint8_t *) u.req.info; 2109 do { 2110 const struct ieee80211req_sta_info *si; 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} 1631 1632static const char * 1633get_chaninfo(const struct ieee80211_channel *c, int precise, 1634 char buf[], size_t bsize) 1635{ 1636 buf[0] = '\0'; 1637 if (IEEE80211_IS_CHAN_FHSS(c)) 1638 strlcat(buf, " FHSS", bsize); 1639 if (IEEE80211_IS_CHAN_A(c)) { 1640 if (IEEE80211_IS_CHAN_HALF(c)) 1641 strlcat(buf, " 11a/10Mhz", bsize); 1642 else if (IEEE80211_IS_CHAN_QUARTER(c)) 1643 strlcat(buf, " 11a/5Mhz", bsize); 1644 else 1645 strlcat(buf, " 11a", bsize); 1646 } 1647 if (IEEE80211_IS_CHAN_ANYG(c)) { 1648 if (IEEE80211_IS_CHAN_HALF(c)) 1649 strlcat(buf, " 11g/10Mhz", bsize); 1650 else if (IEEE80211_IS_CHAN_QUARTER(c)) 1651 strlcat(buf, " 11g/5Mhz", bsize); 1652 else 1653 strlcat(buf, " 11g", bsize); 1654 } else if (IEEE80211_IS_CHAN_B(c)) 1655 strlcat(buf, " 11b", bsize); 1656 if (IEEE80211_IS_CHAN_TURBO(c)) 1657 strlcat(buf, " Turbo", bsize); 1658 if (precise) { 1659 if (IEEE80211_IS_CHAN_HT20(c)) 1660 strlcat(buf, " ht/20", bsize); 1661 else if (IEEE80211_IS_CHAN_HT40D(c)) 1662 strlcat(buf, " ht/40-", bsize); 1663 else if (IEEE80211_IS_CHAN_HT40U(c)) 1664 strlcat(buf, " ht/40+", bsize); 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} 2132 2133static const char * 2134get_chaninfo(const struct ieee80211_channel *c, int precise, 2135 char buf[], size_t bsize) 2136{ 2137 buf[0] = '\0'; 2138 if (IEEE80211_IS_CHAN_FHSS(c)) 2139 strlcat(buf, " FHSS", bsize); 2140 if (IEEE80211_IS_CHAN_A(c)) { 2141 if (IEEE80211_IS_CHAN_HALF(c)) 2142 strlcat(buf, " 11a/10Mhz", bsize); 2143 else if (IEEE80211_IS_CHAN_QUARTER(c)) 2144 strlcat(buf, " 11a/5Mhz", bsize); 2145 else 2146 strlcat(buf, " 11a", bsize); 2147 } 2148 if (IEEE80211_IS_CHAN_ANYG(c)) { 2149 if (IEEE80211_IS_CHAN_HALF(c)) 2150 strlcat(buf, " 11g/10Mhz", bsize); 2151 else if (IEEE80211_IS_CHAN_QUARTER(c)) 2152 strlcat(buf, " 11g/5Mhz", bsize); 2153 else 2154 strlcat(buf, " 11g", bsize); 2155 } else if (IEEE80211_IS_CHAN_B(c)) 2156 strlcat(buf, " 11b", bsize); 2157 if (IEEE80211_IS_CHAN_TURBO(c)) 2158 strlcat(buf, " Turbo", bsize); 2159 if (precise) { 2160 if (IEEE80211_IS_CHAN_HT20(c)) 2161 strlcat(buf, " ht/20", bsize); 2162 else if (IEEE80211_IS_CHAN_HT40D(c)) 2163 strlcat(buf, " ht/40-", bsize); 2164 else if (IEEE80211_IS_CHAN_HT40U(c)) 2165 strlcat(buf, " ht/40+", bsize); 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 1772list_txpow(int s) 1773{ 1774 struct ieee80211req_chaninfo achans; 1775 uint8_t reported[IEEE80211_CHAN_BYTES]; 1776 struct ieee80211_channel *c, *prev; 1777 int i, half; 1778 1779 getchaninfo(s); 1780 memset(&achans, 0, sizeof(achans)); 1781 memset(reported, 0, sizeof(reported)); 1782 for (i = 0; i < chaninfo.ic_nchans; i++) { 1783 c = &chaninfo.ic_chans[i]; 1784 /* suppress duplicates as above */ 1785 if (isset(reported, c->ic_ieee) && !verbose) { 1786 /* XXX we assume duplicates are adjacent */ 1787 prev = &achans.ic_chans[achans.ic_nchans-1]; 1788 /* display highest power on channel */ 1789 if (c->ic_maxpower > prev->ic_maxpower) 1790 *prev = *c; 1791 } else { 1792 achans.ic_chans[achans.ic_nchans++] = *c; 1793 setbit(reported, c->ic_ieee); 1794 } 1795 } 1796 if (!verbose) { 1797 half = achans.ic_nchans / 2; 1798 if (achans.ic_nchans % 2) 1799 half++; 1800 1801 for (i = 0; i < achans.ic_nchans / 2; i++) { 1802 print_txpow(&achans.ic_chans[i]); 1803 print_txpow(&achans.ic_chans[half+i]); 1804 printf("\n"); 1805 } 1806 if (achans.ic_nchans % 2) { 1807 print_txpow(&achans.ic_chans[i]); 1808 printf("\n"); 1809 } 1810 } else { 1811 for (i = 0; i < achans.ic_nchans; i++) { 1812 print_txpow_verbose(&achans.ic_chans[i]); 1813 printf("\n"); 1814 } 1815 } 1816} 1817 1818static void 1819list_keys(int s) 1820{ 1821} 1822 1823#define IEEE80211_C_BITS \ 1824"\020\1WEP\2TKIP\3AES\4AES_CCM\6CKIP\7FF\10TURBOP\11IBSS\12PMGT\13HOSTAP\14AHDEMO" \ 1825"\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE\21MONITOR\22TKIPMIC\30WPA1" \ 1826"\31WPA2\32BURST\33WME\34WDS\36BGSCAN\37TXFRAG" 1827 1828static void 1829list_capabilities(int s) 1830{ 1831 struct ieee80211req ireq; 1832 u_int32_t caps; 1833 1834 (void) memset(&ireq, 0, sizeof(ireq)); 1835 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 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 2274list_txpow(int s) 2275{ 2276 struct ieee80211req_chaninfo achans; 2277 uint8_t reported[IEEE80211_CHAN_BYTES]; 2278 struct ieee80211_channel *c, *prev; 2279 int i, half; 2280 2281 getchaninfo(s); 2282 memset(&achans, 0, sizeof(achans)); 2283 memset(reported, 0, sizeof(reported)); 2284 for (i = 0; i < chaninfo.ic_nchans; i++) { 2285 c = &chaninfo.ic_chans[i]; 2286 /* suppress duplicates as above */ 2287 if (isset(reported, c->ic_ieee) && !verbose) { 2288 /* XXX we assume duplicates are adjacent */ 2289 prev = &achans.ic_chans[achans.ic_nchans-1]; 2290 /* display highest power on channel */ 2291 if (c->ic_maxpower > prev->ic_maxpower) 2292 *prev = *c; 2293 } else { 2294 achans.ic_chans[achans.ic_nchans++] = *c; 2295 setbit(reported, c->ic_ieee); 2296 } 2297 } 2298 if (!verbose) { 2299 half = achans.ic_nchans / 2; 2300 if (achans.ic_nchans % 2) 2301 half++; 2302 2303 for (i = 0; i < achans.ic_nchans / 2; i++) { 2304 print_txpow(&achans.ic_chans[i]); 2305 print_txpow(&achans.ic_chans[half+i]); 2306 printf("\n"); 2307 } 2308 if (achans.ic_nchans % 2) { 2309 print_txpow(&achans.ic_chans[i]); 2310 printf("\n"); 2311 } 2312 } else { 2313 for (i = 0; i < achans.ic_nchans; i++) { 2314 print_txpow_verbose(&achans.ic_chans[i]); 2315 printf("\n"); 2316 } 2317 } 2318} 2319 2320static void 2321list_keys(int s) 2322{ 2323} 2324 2325#define IEEE80211_C_BITS \ 2326"\020\1WEP\2TKIP\3AES\4AES_CCM\6CKIP\7FF\10TURBOP\11IBSS\12PMGT\13HOSTAP\14AHDEMO" \ 2327"\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE\21MONITOR\22TKIPMIC\30WPA1" \ 2328"\31WPA2\32BURST\33WME\34WDS\36BGSCAN\37TXFRAG" 2329 2330static void 2331list_capabilities(int s) 2332{ 2333 struct ieee80211req ireq; 2334 u_int32_t caps; 2335 2336 (void) memset(&ireq, 0, sizeof(ireq)); 2337 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 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); 1972 else if (iseq(arg, "keys")) 1973 list_keys(s); 1974 else if (iseq(arg, "caps")) 1975 list_capabilities(s); 1976 else if (iseq(arg, "wme")) 1977 list_wme(s); 1978 else if (iseq(arg, "mac")) 1979 list_mac(s); 1980 else if (iseq(arg, "txpow")) 1981 list_txpow(s); 1982 else 1983 errx(1, "Don't know how to list %s for %s", arg, name); 1984#undef iseq 1985} 1986 1987static enum ieee80211_opmode 1988get80211opmode(int s) 1989{ 1990 struct ifmediareq ifmr; 1991 1992 (void) memset(&ifmr, 0, sizeof(ifmr)); 1993 (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 1994 1995 if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) { 1996 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) 1997 return IEEE80211_M_IBSS; /* XXX ahdemo */ 1998 if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 1999 return IEEE80211_M_HOSTAP; 2000 if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 2001 return IEEE80211_M_MONITOR; 2002 } 2003 return IEEE80211_M_STA; 2004} 2005 2006#if 0 2007static void 2008printcipher(int s, struct ieee80211req *ireq, int keylenop) 2009{ 2010 switch (ireq->i_val) { 2011 case IEEE80211_CIPHER_WEP: 2012 ireq->i_type = keylenop; 2013 if (ioctl(s, SIOCG80211, ireq) != -1) 2014 printf("WEP-%s", 2015 ireq->i_len <= 5 ? "40" : 2016 ireq->i_len <= 13 ? "104" : "128"); 2017 else 2018 printf("WEP"); 2019 break; 2020 case IEEE80211_CIPHER_TKIP: 2021 printf("TKIP"); 2022 break; 2023 case IEEE80211_CIPHER_AES_OCB: 2024 printf("AES-OCB"); 2025 break; 2026 case IEEE80211_CIPHER_AES_CCM: 2027 printf("AES-CCM"); 2028 break; 2029 case IEEE80211_CIPHER_CKIP: 2030 printf("CKIP"); 2031 break; 2032 case IEEE80211_CIPHER_NONE: 2033 printf("NONE"); 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); 2501 else if (iseq(arg, "keys")) 2502 list_keys(s); 2503 else if (iseq(arg, "caps")) 2504 list_capabilities(s); 2505 else if (iseq(arg, "wme")) 2506 list_wme(s); 2507 else if (iseq(arg, "mac")) 2508 list_mac(s); 2509 else if (iseq(arg, "txpow")) 2510 list_txpow(s); 2511 else 2512 errx(1, "Don't know how to list %s for %s", arg, name); 2513#undef iseq 2514} 2515 2516static enum ieee80211_opmode 2517get80211opmode(int s) 2518{ 2519 struct ifmediareq ifmr; 2520 2521 (void) memset(&ifmr, 0, sizeof(ifmr)); 2522 (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); 2523 2524 if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) { 2525 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) 2526 return IEEE80211_M_IBSS; /* XXX ahdemo */ 2527 if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 2528 return IEEE80211_M_HOSTAP; 2529 if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 2530 return IEEE80211_M_MONITOR; 2531 } 2532 return IEEE80211_M_STA; 2533} 2534 2535#if 0 2536static void 2537printcipher(int s, struct ieee80211req *ireq, int keylenop) 2538{ 2539 switch (ireq->i_val) { 2540 case IEEE80211_CIPHER_WEP: 2541 ireq->i_type = keylenop; 2542 if (ioctl(s, SIOCG80211, ireq) != -1) 2543 printf("WEP-%s", 2544 ireq->i_len <= 5 ? "40" : 2545 ireq->i_len <= 13 ? "104" : "128"); 2546 else 2547 printf("WEP"); 2548 break; 2549 case IEEE80211_CIPHER_TKIP: 2550 printf("TKIP"); 2551 break; 2552 case IEEE80211_CIPHER_AES_OCB: 2553 printf("AES-OCB"); 2554 break; 2555 case IEEE80211_CIPHER_AES_CCM: 2556 printf("AES-CCM"); 2557 break; 2558 case IEEE80211_CIPHER_CKIP: 2559 printf("CKIP"); 2560 break; 2561 case IEEE80211_CIPHER_NONE: 2562 printf("NONE"); 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); 2085 if (printcontents) 2086 LINE_BREAK(); 2087 switch (ik->ik_type) { 2088 case IEEE80211_CIPHER_WEP: 2089 /* compatibility */ 2090 LINE_CHECK("wepkey %u:%s", ik->ik_keyix+1, 2091 keylen <= 5 ? "40-bit" : 2092 keylen <= 13 ? "104-bit" : "128-bit"); 2093 break; 2094 case IEEE80211_CIPHER_TKIP: 2095 if (keylen > 128/8) 2096 keylen -= 128/8; /* ignore MIC for now */ 2097 LINE_CHECK("TKIP %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2098 break; 2099 case IEEE80211_CIPHER_AES_OCB: 2100 LINE_CHECK("AES-OCB %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2101 break; 2102 case IEEE80211_CIPHER_AES_CCM: 2103 LINE_CHECK("AES-CCM %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2104 break; 2105 case IEEE80211_CIPHER_CKIP: 2106 LINE_CHECK("CKIP %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2107 break; 2108 case IEEE80211_CIPHER_NONE: 2109 LINE_CHECK("NULL %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2110 break; 2111 default: 2112 LINE_CHECK("UNKNOWN (0x%x) %u:%u-bit", 2113 ik->ik_type, ik->ik_keyix+1, 8*keylen); 2114 break; 2115 } 2116 if (printcontents) { 2117 int i; 2118 2119 printf(" <"); 2120 for (i = 0; i < keylen; i++) 2121 printf("%02x", ik->ik_keydata[i]); 2122 printf(">"); 2123 if (ik->ik_type != IEEE80211_CIPHER_WEP && 2124 (ik->ik_keyrsc != 0 || verbose)) 2125 printf(" rsc %ju", (uintmax_t)ik->ik_keyrsc); 2126 if (ik->ik_type != IEEE80211_CIPHER_WEP && 2127 (ik->ik_keytsc != 0 || verbose)) 2128 printf(" tsc %ju", (uintmax_t)ik->ik_keytsc); 2129 if (ik->ik_flags != 0 && verbose) { 2130 const char *sep = " "; 2131 2132 if (ik->ik_flags & IEEE80211_KEY_XMIT) 2133 printf("%stx", sep), sep = "+"; 2134 if (ik->ik_flags & IEEE80211_KEY_RECV) 2135 printf("%srx", sep), sep = "+"; 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); 2580 if (printcontents) 2581 LINE_BREAK(); 2582 switch (ik->ik_type) { 2583 case IEEE80211_CIPHER_WEP: 2584 /* compatibility */ 2585 LINE_CHECK("wepkey %u:%s", ik->ik_keyix+1, 2586 keylen <= 5 ? "40-bit" : 2587 keylen <= 13 ? "104-bit" : "128-bit"); 2588 break; 2589 case IEEE80211_CIPHER_TKIP: 2590 if (keylen > 128/8) 2591 keylen -= 128/8; /* ignore MIC for now */ 2592 LINE_CHECK("TKIP %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2593 break; 2594 case IEEE80211_CIPHER_AES_OCB: 2595 LINE_CHECK("AES-OCB %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2596 break; 2597 case IEEE80211_CIPHER_AES_CCM: 2598 LINE_CHECK("AES-CCM %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2599 break; 2600 case IEEE80211_CIPHER_CKIP: 2601 LINE_CHECK("CKIP %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2602 break; 2603 case IEEE80211_CIPHER_NONE: 2604 LINE_CHECK("NULL %u:%u-bit", ik->ik_keyix+1, 8*keylen); 2605 break; 2606 default: 2607 LINE_CHECK("UNKNOWN (0x%x) %u:%u-bit", 2608 ik->ik_type, ik->ik_keyix+1, 8*keylen); 2609 break; 2610 } 2611 if (printcontents) { 2612 int i; 2613 2614 printf(" <"); 2615 for (i = 0; i < keylen; i++) 2616 printf("%02x", ik->ik_keydata[i]); 2617 printf(">"); 2618 if (ik->ik_type != IEEE80211_CIPHER_WEP && 2619 (ik->ik_keyrsc != 0 || verbose)) 2620 printf(" rsc %ju", (uintmax_t)ik->ik_keyrsc); 2621 if (ik->ik_type != IEEE80211_CIPHER_WEP && 2622 (ik->ik_keytsc != 0 || verbose)) 2623 printf(" tsc %ju", (uintmax_t)ik->ik_keytsc); 2624 if (ik->ik_flags != 0 && verbose) { 2625 const char *sep = " "; 2626 2627 if (ik->ik_flags & IEEE80211_KEY_XMIT) 2628 printf("%stx", sep), sep = "+"; 2629 if (ik->ik_flags & IEEE80211_KEY_RECV) 2630 printf("%srx", sep), sep = "+"; 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)); 2619 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 2620 ireq.i_type = type; 2621 ireq.i_val = val; 2622 ireq.i_len = len; 2623 ireq.i_data = data; 2624 if (ioctl(s, SIOCS80211, &ireq) < 0) 2625 err(1, "SIOCS80211"); 2626} 2627 2628static const char * 2629get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp) 2630{ 2631 int len; 2632 int hexstr; 2633 u_int8_t *p; 2634 2635 len = *lenp; 2636 p = buf; 2637 hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x'); 2638 if (hexstr) 2639 val += 2; 2640 for (;;) { 2641 if (*val == '\0') 2642 break; 2643 if (sep != NULL && strchr(sep, *val) != NULL) { 2644 val++; 2645 break; 2646 } 2647 if (hexstr) { 2648 if (!isxdigit((u_char)val[0])) { 2649 warnx("bad hexadecimal digits"); 2650 return NULL; 2651 } 2652 if (!isxdigit((u_char)val[1])) { 2653 warnx("odd count hexadecimal digits"); 2654 return NULL; 2655 } 2656 } 2657 if (p >= buf + len) { 2658 if (hexstr) 2659 warnx("hexadecimal digits too long"); 2660 else 2661 warnx("string too long"); 2662 return NULL; 2663 } 2664 if (hexstr) { 2665#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10) 2666 *p++ = (tohex((u_char)val[0]) << 4) | 2667 tohex((u_char)val[1]); 2668#undef tohex 2669 val += 2; 2670 } else 2671 *p++ = *val++; 2672 } 2673 len = p - buf; 2674 /* The string "-" is treated as the empty string. */ 2675 if (!hexstr && len == 1 && buf[0] == '-') { 2676 len = 0; 2677 memset(buf, 0, *lenp); 2678 } else if (len < *lenp) 2679 memset(p, 0, *lenp - len); 2680 *lenp = len; 2681 return val; 2682} 2683 2684static void 2685print_string(const u_int8_t *buf, int len) 2686{ 2687 int i; 2688 int hasspc; 2689 2690 i = 0; 2691 hasspc = 0; 2692 for (; i < len; i++) { 2693 if (!isprint(buf[i]) && buf[i] != '\0') 2694 break; 2695 if (isspace(buf[i])) 2696 hasspc++; 2697 } 2698 if (i == len) { 2699 if (hasspc || len == 0 || buf[0] == '\0') 2700 printf("\"%.*s\"", len, buf); 2701 else 2702 printf("%.*s", len, buf); 2703 } else { 2704 printf("0x"); 2705 for (i = 0; i < len; i++) 2706 printf("%02x", buf[i]); 2707 } 2708} 2709 2710static struct cmd ieee80211_cmds[] = { 2711 DEF_CMD_ARG("ssid", set80211ssid), 2712 DEF_CMD_ARG("nwid", set80211ssid), 2713 DEF_CMD_ARG("stationname", set80211stationname), 2714 DEF_CMD_ARG("station", set80211stationname), /* BSD/OS */ 2715 DEF_CMD_ARG("channel", set80211channel), 2716 DEF_CMD_ARG("authmode", set80211authmode), 2717 DEF_CMD_ARG("powersavemode", set80211powersavemode), 2718 DEF_CMD("powersave", 1, set80211powersave), 2719 DEF_CMD("-powersave", 0, set80211powersave), 2720 DEF_CMD_ARG("powersavesleep", set80211powersavesleep), 2721 DEF_CMD_ARG("wepmode", set80211wepmode), 2722 DEF_CMD("wep", 1, set80211wep), 2723 DEF_CMD("-wep", 0, set80211wep), 2724 DEF_CMD_ARG("deftxkey", set80211weptxkey), 2725 DEF_CMD_ARG("weptxkey", set80211weptxkey), 2726 DEF_CMD_ARG("wepkey", set80211wepkey), 2727 DEF_CMD_ARG("nwkey", set80211nwkey), /* NetBSD */ 2728 DEF_CMD("-nwkey", 0, set80211wep), /* NetBSD */ 2729 DEF_CMD_ARG("rtsthreshold", set80211rtsthreshold), 2730 DEF_CMD_ARG("protmode", set80211protmode), 2731 DEF_CMD_ARG("txpower", set80211txpower), 2732 DEF_CMD_ARG("roaming", set80211roaming), 2733 DEF_CMD("wme", 1, set80211wme), 2734 DEF_CMD("-wme", 0, set80211wme), 2735 DEF_CMD("hidessid", 1, set80211hidessid), 2736 DEF_CMD("-hidessid", 0, set80211hidessid), 2737 DEF_CMD("apbridge", 1, set80211apbridge), 2738 DEF_CMD("-apbridge", 0, set80211apbridge), 2739 DEF_CMD_ARG("chanlist", set80211chanlist), 2740 DEF_CMD_ARG("bssid", set80211bssid), 2741 DEF_CMD_ARG("ap", set80211bssid), 2742 DEF_CMD("scan", 0, set80211scan), 2743 DEF_CMD_ARG("list", set80211list), 2744 DEF_CMD_ARG2("cwmin", set80211cwmin), 2745 DEF_CMD_ARG2("cwmax", set80211cwmax), 2746 DEF_CMD_ARG2("aifs", set80211aifs), 2747 DEF_CMD_ARG2("txoplimit", set80211txoplimit), 2748 DEF_CMD_ARG("acm", set80211acm), 2749 DEF_CMD_ARG("-acm", set80211noacm), 2750 DEF_CMD_ARG("ack", set80211ackpolicy), 2751 DEF_CMD_ARG("-ack", set80211noackpolicy), 2752 DEF_CMD_ARG2("bss:cwmin", set80211bsscwmin), 2753 DEF_CMD_ARG2("bss:cwmax", set80211bsscwmax), 2754 DEF_CMD_ARG2("bss:aifs", set80211bssaifs), 2755 DEF_CMD_ARG2("bss:txoplimit", set80211bsstxoplimit), 2756 DEF_CMD_ARG("dtimperiod", set80211dtimperiod), 2757 DEF_CMD_ARG("bintval", set80211bintval), 2758 DEF_CMD("mac:open", IEEE80211_MACCMD_POLICY_OPEN, set80211maccmd), 2759 DEF_CMD("mac:allow", IEEE80211_MACCMD_POLICY_ALLOW, set80211maccmd), 2760 DEF_CMD("mac:deny", IEEE80211_MACCMD_POLICY_DENY, set80211maccmd), 2761 DEF_CMD("mac:flush", IEEE80211_MACCMD_FLUSH, set80211maccmd), 2762 DEF_CMD("mac:detach", IEEE80211_MACCMD_DETACH, set80211maccmd), 2763 DEF_CMD_ARG("mac:add", set80211addmac), 2764 DEF_CMD_ARG("mac:del", set80211delmac), 2765 DEF_CMD_ARG("mac:kick", set80211kickmac), 2766 DEF_CMD("pureg", 1, set80211pureg), 2767 DEF_CMD("-pureg", 0, set80211pureg), 2768 DEF_CMD("ff", 1, set80211fastframes), 2769 DEF_CMD("-ff", 0, set80211fastframes), 2770 DEF_CMD("dturbo", 1, set80211dturbo), 2771 DEF_CMD("-dturbo", 0, set80211dturbo), 2772 DEF_CMD("bgscan", 1, set80211bgscan), 2773 DEF_CMD("-bgscan", 0, set80211bgscan), 2774 DEF_CMD_ARG("bgscanidle", set80211bgscanidle), 2775 DEF_CMD_ARG("bgscanintvl", set80211bgscanintvl), 2776 DEF_CMD_ARG("scanvalid", set80211scanvalid), 2777 DEF_CMD_ARG("roam:rssi11a", set80211roamrssi11a), 2778 DEF_CMD_ARG("roam:rssi11b", set80211roamrssi11b), 2779 DEF_CMD_ARG("roam:rssi11g", set80211roamrssi11g), 2780 DEF_CMD_ARG("roam:rate11a", set80211roamrate11a), 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)); 3219 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name)); 3220 ireq.i_type = type; 3221 ireq.i_val = val; 3222 ireq.i_len = len; 3223 ireq.i_data = data; 3224 if (ioctl(s, SIOCS80211, &ireq) < 0) 3225 err(1, "SIOCS80211"); 3226} 3227 3228static const char * 3229get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp) 3230{ 3231 int len; 3232 int hexstr; 3233 u_int8_t *p; 3234 3235 len = *lenp; 3236 p = buf; 3237 hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x'); 3238 if (hexstr) 3239 val += 2; 3240 for (;;) { 3241 if (*val == '\0') 3242 break; 3243 if (sep != NULL && strchr(sep, *val) != NULL) { 3244 val++; 3245 break; 3246 } 3247 if (hexstr) { 3248 if (!isxdigit((u_char)val[0])) { 3249 warnx("bad hexadecimal digits"); 3250 return NULL; 3251 } 3252 if (!isxdigit((u_char)val[1])) { 3253 warnx("odd count hexadecimal digits"); 3254 return NULL; 3255 } 3256 } 3257 if (p >= buf + len) { 3258 if (hexstr) 3259 warnx("hexadecimal digits too long"); 3260 else 3261 warnx("string too long"); 3262 return NULL; 3263 } 3264 if (hexstr) { 3265#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10) 3266 *p++ = (tohex((u_char)val[0]) << 4) | 3267 tohex((u_char)val[1]); 3268#undef tohex 3269 val += 2; 3270 } else 3271 *p++ = *val++; 3272 } 3273 len = p - buf; 3274 /* The string "-" is treated as the empty string. */ 3275 if (!hexstr && len == 1 && buf[0] == '-') { 3276 len = 0; 3277 memset(buf, 0, *lenp); 3278 } else if (len < *lenp) 3279 memset(p, 0, *lenp - len); 3280 *lenp = len; 3281 return val; 3282} 3283 3284static void 3285print_string(const u_int8_t *buf, int len) 3286{ 3287 int i; 3288 int hasspc; 3289 3290 i = 0; 3291 hasspc = 0; 3292 for (; i < len; i++) { 3293 if (!isprint(buf[i]) && buf[i] != '\0') 3294 break; 3295 if (isspace(buf[i])) 3296 hasspc++; 3297 } 3298 if (i == len) { 3299 if (hasspc || len == 0 || buf[0] == '\0') 3300 printf("\"%.*s\"", len, buf); 3301 else 3302 printf("%.*s", len, buf); 3303 } else { 3304 printf("0x"); 3305 for (i = 0; i < len; i++) 3306 printf("%02x", buf[i]); 3307 } 3308} 3309 3310static struct cmd ieee80211_cmds[] = { 3311 DEF_CMD_ARG("ssid", set80211ssid), 3312 DEF_CMD_ARG("nwid", set80211ssid), 3313 DEF_CMD_ARG("stationname", set80211stationname), 3314 DEF_CMD_ARG("station", set80211stationname), /* BSD/OS */ 3315 DEF_CMD_ARG("channel", set80211channel), 3316 DEF_CMD_ARG("authmode", set80211authmode), 3317 DEF_CMD_ARG("powersavemode", set80211powersavemode), 3318 DEF_CMD("powersave", 1, set80211powersave), 3319 DEF_CMD("-powersave", 0, set80211powersave), 3320 DEF_CMD_ARG("powersavesleep", set80211powersavesleep), 3321 DEF_CMD_ARG("wepmode", set80211wepmode), 3322 DEF_CMD("wep", 1, set80211wep), 3323 DEF_CMD("-wep", 0, set80211wep), 3324 DEF_CMD_ARG("deftxkey", set80211weptxkey), 3325 DEF_CMD_ARG("weptxkey", set80211weptxkey), 3326 DEF_CMD_ARG("wepkey", set80211wepkey), 3327 DEF_CMD_ARG("nwkey", set80211nwkey), /* NetBSD */ 3328 DEF_CMD("-nwkey", 0, set80211wep), /* NetBSD */ 3329 DEF_CMD_ARG("rtsthreshold", set80211rtsthreshold), 3330 DEF_CMD_ARG("protmode", set80211protmode), 3331 DEF_CMD_ARG("txpower", set80211txpower), 3332 DEF_CMD_ARG("roaming", set80211roaming), 3333 DEF_CMD("wme", 1, set80211wme), 3334 DEF_CMD("-wme", 0, set80211wme), 3335 DEF_CMD("hidessid", 1, set80211hidessid), 3336 DEF_CMD("-hidessid", 0, set80211hidessid), 3337 DEF_CMD("apbridge", 1, set80211apbridge), 3338 DEF_CMD("-apbridge", 0, set80211apbridge), 3339 DEF_CMD_ARG("chanlist", set80211chanlist), 3340 DEF_CMD_ARG("bssid", set80211bssid), 3341 DEF_CMD_ARG("ap", set80211bssid), 3342 DEF_CMD("scan", 0, set80211scan), 3343 DEF_CMD_ARG("list", set80211list), 3344 DEF_CMD_ARG2("cwmin", set80211cwmin), 3345 DEF_CMD_ARG2("cwmax", set80211cwmax), 3346 DEF_CMD_ARG2("aifs", set80211aifs), 3347 DEF_CMD_ARG2("txoplimit", set80211txoplimit), 3348 DEF_CMD_ARG("acm", set80211acm), 3349 DEF_CMD_ARG("-acm", set80211noacm), 3350 DEF_CMD_ARG("ack", set80211ackpolicy), 3351 DEF_CMD_ARG("-ack", set80211noackpolicy), 3352 DEF_CMD_ARG2("bss:cwmin", set80211bsscwmin), 3353 DEF_CMD_ARG2("bss:cwmax", set80211bsscwmax), 3354 DEF_CMD_ARG2("bss:aifs", set80211bssaifs), 3355 DEF_CMD_ARG2("bss:txoplimit", set80211bsstxoplimit), 3356 DEF_CMD_ARG("dtimperiod", set80211dtimperiod), 3357 DEF_CMD_ARG("bintval", set80211bintval), 3358 DEF_CMD("mac:open", IEEE80211_MACCMD_POLICY_OPEN, set80211maccmd), 3359 DEF_CMD("mac:allow", IEEE80211_MACCMD_POLICY_ALLOW, set80211maccmd), 3360 DEF_CMD("mac:deny", IEEE80211_MACCMD_POLICY_DENY, set80211maccmd), 3361 DEF_CMD("mac:flush", IEEE80211_MACCMD_FLUSH, set80211maccmd), 3362 DEF_CMD("mac:detach", IEEE80211_MACCMD_DETACH, set80211maccmd), 3363 DEF_CMD_ARG("mac:add", set80211addmac), 3364 DEF_CMD_ARG("mac:del", set80211delmac), 3365 DEF_CMD_ARG("mac:kick", set80211kickmac), 3366 DEF_CMD("pureg", 1, set80211pureg), 3367 DEF_CMD("-pureg", 0, set80211pureg), 3368 DEF_CMD("ff", 1, set80211fastframes), 3369 DEF_CMD("-ff", 0, set80211fastframes), 3370 DEF_CMD("dturbo", 1, set80211dturbo), 3371 DEF_CMD("-dturbo", 0, set80211dturbo), 3372 DEF_CMD("bgscan", 1, set80211bgscan), 3373 DEF_CMD("-bgscan", 0, set80211bgscan), 3374 DEF_CMD_ARG("bgscanidle", set80211bgscanidle), 3375 DEF_CMD_ARG("bgscanintvl", set80211bgscanintvl), 3376 DEF_CMD_ARG("scanvalid", set80211scanvalid), 3377 DEF_CMD_ARG("roam:rssi11a", set80211roamrssi11a), 3378 DEF_CMD_ARG("roam:rssi11b", set80211roamrssi11b), 3379 DEF_CMD_ARG("roam:rssi11g", set80211roamrssi11g), 3380 DEF_CMD_ARG("roam:rate11a", set80211roamrate11a), 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}
|