Deleted Added
full compact
ifieee80211.c (80315) ifieee80211.c (88748)
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 *
13 * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
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 *
13 * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 * $FreeBSD: head/sbin/ifconfig/ifieee80211.c 80315 2001-07-25 05:52:19Z brooks $
25 * $FreeBSD: head/sbin/ifconfig/ifieee80211.c 88748 2001-12-31 22:01:44Z ambrisko $
26 */
27
28/*-
29 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
30 * All rights reserved.
31 *
32 * This code is derived from software contributed to The NetBSD Foundation
33 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
34 * NASA Ames Research Center.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the NetBSD
47 * Foundation, Inc. and its contributors.
48 * 4. Neither the name of The NetBSD Foundation nor the names of its
49 * contributors may be used to endorse or promote products derived
50 * from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
53 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
63 */
64
65#include <sys/param.h>
66#include <sys/ioctl.h>
67#include <sys/socket.h>
68#include <sys/sysctl.h>
69#include <sys/time.h>
70
71#include <net/ethernet.h>
72#include <net/if.h>
73#include <net/if_dl.h>
74#include <net/if_types.h>
75#include <net/route.h>
76#include <net/if_ieee80211.h>
77
78#include <ctype.h>
79#include <err.h>
80#include <errno.h>
81#include <fcntl.h>
82#include <stdio.h>
83#include <stdlib.h>
84#include <string.h>
85#include <unistd.h>
86
87#include "ifconfig.h"
88
89static void set80211(int s, int type, int val, int len, u_int8_t *data);
90static const char *get_string(const char *val, const char *sep,
91 u_int8_t *buf, int *lenp);
92static void print_string(const u_int8_t *buf, int len);
93
94void
95set80211ssid(const char *val, int d, int s, const struct afswtch *rafp)
96{
97 int ssid;
98 int len;
99 u_int8_t data[33];
100
101 ssid = 0;
26 */
27
28/*-
29 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
30 * All rights reserved.
31 *
32 * This code is derived from software contributed to The NetBSD Foundation
33 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
34 * NASA Ames Research Center.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the NetBSD
47 * Foundation, Inc. and its contributors.
48 * 4. Neither the name of The NetBSD Foundation nor the names of its
49 * contributors may be used to endorse or promote products derived
50 * from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
53 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
63 */
64
65#include <sys/param.h>
66#include <sys/ioctl.h>
67#include <sys/socket.h>
68#include <sys/sysctl.h>
69#include <sys/time.h>
70
71#include <net/ethernet.h>
72#include <net/if.h>
73#include <net/if_dl.h>
74#include <net/if_types.h>
75#include <net/route.h>
76#include <net/if_ieee80211.h>
77
78#include <ctype.h>
79#include <err.h>
80#include <errno.h>
81#include <fcntl.h>
82#include <stdio.h>
83#include <stdlib.h>
84#include <string.h>
85#include <unistd.h>
86
87#include "ifconfig.h"
88
89static void set80211(int s, int type, int val, int len, u_int8_t *data);
90static const char *get_string(const char *val, const char *sep,
91 u_int8_t *buf, int *lenp);
92static void print_string(const u_int8_t *buf, int len);
93
94void
95set80211ssid(const char *val, int d, int s, const struct afswtch *rafp)
96{
97 int ssid;
98 int len;
99 u_int8_t data[33];
100
101 ssid = 0;
102 len = sizeof(val);
103 if (len > 2 && isdigit(val[0]) && val[1] == ':') {
104 ssid = atoi(val)-1;
105 val += 2;
106 }
102
103 bzero(data, sizeof(data));
104 len = sizeof(data);
105 get_string(val, NULL, data, &len);
106
107 set80211(s, IEEE80211_IOC_SSID, ssid, len, data);
108}
109
110void
111set80211stationname(const char *val, int d, int s, const struct afswtch *rafp)
112{
113 int len;
114 u_int8_t data[33];
115
116 bzero(data, sizeof(data));
117 len = sizeof(data);
118 get_string(val, NULL, data, &len);
119
120 set80211(s, IEEE80211_IOC_STATIONNAME, 0, len, data);
121}
122
123void
124set80211channel(const char *val, int d, int s, const struct afswtch *rafp)
125{
126 set80211(s, IEEE80211_IOC_CHANNEL, atoi(val), 0, NULL);
127}
128
129void
130set80211authmode(const char *val, int d, int s, const struct afswtch *rafp)
131{
132 int mode;
133
134 if(strcasecmp(val, "none") == 0) {
135 mode = IEEE80211_AUTH_NONE;
136 } else if(strcasecmp(val, "open") == 0) {
137 mode = IEEE80211_AUTH_OPEN;
138 } else if(strcasecmp(val, "shared") == 0) {
139 mode = IEEE80211_AUTH_SHARED;
140 } else {
141 err(1, "unknown authmode");
142 }
143
144 set80211(s, IEEE80211_IOC_AUTHMODE, mode, 0, NULL);
145}
146
147void
148set80211powersavemode(const char *val, int d, int s, const struct afswtch *rafp)
149{
150 int mode;
151
152 if(strcasecmp(val, "off") == 0) {
153 mode = IEEE80211_POWERSAVE_OFF;
154 } else if(strcasecmp(val, "on") == 0) {
155 mode = IEEE80211_POWERSAVE_ON;
156 } else if(strcasecmp(val, "cam") == 0) {
157 mode = IEEE80211_POWERSAVE_CAM;
158 } else if(strcasecmp(val, "psp") == 0) {
159 mode = IEEE80211_POWERSAVE_PSP;
160 } else if(strcasecmp(val, "psp-cam") == 0) {
161 mode = IEEE80211_POWERSAVE_PSP_CAM;
162 } else {
163 err(1, "unknown powersavemode");
164 }
165
166 set80211(s, IEEE80211_IOC_POWERSAVE, mode, 0, NULL);
167}
168
169void
170set80211powersave(const char *val, int d, int s, const struct afswtch *rafp)
171{
172 if (d == 0)
173 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_OFF,
174 0, NULL);
175 else
176 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_ON,
177 0, NULL);
178}
179
180void
181set80211powersavesleep(const char *val, int d, int s, const struct afswtch *rafp)
182{
183 set80211(s, IEEE80211_IOC_POWERSAVESLEEP, atoi(val), 0, NULL);
184}
185
186void
187set80211wepmode(const char *val, int d, int s, const struct afswtch *rafp)
188{
189 int mode;
190
191 if(strcasecmp(val, "off") == 0) {
192 mode = IEEE80211_WEP_OFF;
193 } else if(strcasecmp(val, "on") == 0) {
194 mode = IEEE80211_WEP_ON;
195 } else if(strcasecmp(val, "mixed") == 0) {
196 mode = IEEE80211_WEP_MIXED;
197 } else {
198 err(1, "unknown wep mode");
199 }
200
201 set80211(s, IEEE80211_IOC_WEP, mode, 0, NULL);
202}
203
204void
205set80211wep(const char *val, int d, int s, const struct afswtch *rafp)
206{
207 set80211(s, IEEE80211_IOC_WEP, d, 0, NULL);
208}
209
210void
211set80211weptxkey(const char *val, int d, int s, const struct afswtch *rafp)
212{
213 set80211(s, IEEE80211_IOC_WEPTXKEY, atoi(val)-1, 0, NULL);
214}
215
216void
217set80211wepkey(const char *val, int d, int s, const struct afswtch *rafp)
218{
219 int key = 0;
220 int len;
221 u_int8_t data[14];
222
223 if(isdigit(val[0]) && val[1] == ':') {
224 key = atoi(val)-1;
225 val += 2;
226 }
227
228 bzero(data, sizeof(data));
229 len = sizeof(data);
230 get_string(val, NULL, data, &len);
231
232 set80211(s, IEEE80211_IOC_WEPKEY, key, len, data);
233}
234
235/*
236 * This function is purly a NetBSD compatability interface. The NetBSD
237 * iterface is too inflexable, but it's there so we'll support it since
238 * it's not all that hard.
239 */
240void
241set80211nwkey(const char *val, int d, int s, const struct afswtch *rafp)
242{
243 int txkey;
244 int i, len;
245 u_int8_t data[14];
246
247 set80211(s, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL);
248
249 if(isdigit(val[0]) && val[1] == ':') {
250 txkey = val[0]-'0'-1;
251 val += 2;
252
253 for(i = 0; i < 4; i++) {
254 bzero(data, sizeof(data));
255 len = sizeof(data);
256 val = get_string(val, ",", data, &len);
257
258 set80211(s, IEEE80211_IOC_WEPKEY, i, len, data);
259 }
260 } else {
261 bzero(data, sizeof(data));
262 len = sizeof(data);
263 get_string(val, NULL, data, &len);
264 txkey = 0;
265
266 set80211(s, IEEE80211_IOC_WEPKEY, 0, len, data);
267
268 bzero(data, sizeof(data));
269 for(i = 1; i < 4; i++)
270 set80211(s, IEEE80211_IOC_WEPKEY, i, 0, data);
271 }
272
273 set80211(s, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL);
274}
275
276void
277ieee80211_status (s, info)
278 int s;
279 struct rt_addrinfo *info __unused;
280{
281 int i;
282 int num;
283 struct ieee80211req ireq;
284 u_int8_t data[32];
285 char spacer;
286
287 (void) memset(&ireq, 0, sizeof(ireq));
288 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
289 ireq.i_data = &data;
290
291 ireq.i_type = IEEE80211_IOC_SSID;
292 ireq.i_val = -1;
293 if (ioctl(s, SIOCG80211, &ireq) < 0) {
294 /* If we can't get the SSID, the this isn't an 802.11 device. */
295 return;
296 }
297 printf("\tssid ");
298 print_string(data, ireq.i_len);
107
108 bzero(data, sizeof(data));
109 len = sizeof(data);
110 get_string(val, NULL, data, &len);
111
112 set80211(s, IEEE80211_IOC_SSID, ssid, len, data);
113}
114
115void
116set80211stationname(const char *val, int d, int s, const struct afswtch *rafp)
117{
118 int len;
119 u_int8_t data[33];
120
121 bzero(data, sizeof(data));
122 len = sizeof(data);
123 get_string(val, NULL, data, &len);
124
125 set80211(s, IEEE80211_IOC_STATIONNAME, 0, len, data);
126}
127
128void
129set80211channel(const char *val, int d, int s, const struct afswtch *rafp)
130{
131 set80211(s, IEEE80211_IOC_CHANNEL, atoi(val), 0, NULL);
132}
133
134void
135set80211authmode(const char *val, int d, int s, const struct afswtch *rafp)
136{
137 int mode;
138
139 if(strcasecmp(val, "none") == 0) {
140 mode = IEEE80211_AUTH_NONE;
141 } else if(strcasecmp(val, "open") == 0) {
142 mode = IEEE80211_AUTH_OPEN;
143 } else if(strcasecmp(val, "shared") == 0) {
144 mode = IEEE80211_AUTH_SHARED;
145 } else {
146 err(1, "unknown authmode");
147 }
148
149 set80211(s, IEEE80211_IOC_AUTHMODE, mode, 0, NULL);
150}
151
152void
153set80211powersavemode(const char *val, int d, int s, const struct afswtch *rafp)
154{
155 int mode;
156
157 if(strcasecmp(val, "off") == 0) {
158 mode = IEEE80211_POWERSAVE_OFF;
159 } else if(strcasecmp(val, "on") == 0) {
160 mode = IEEE80211_POWERSAVE_ON;
161 } else if(strcasecmp(val, "cam") == 0) {
162 mode = IEEE80211_POWERSAVE_CAM;
163 } else if(strcasecmp(val, "psp") == 0) {
164 mode = IEEE80211_POWERSAVE_PSP;
165 } else if(strcasecmp(val, "psp-cam") == 0) {
166 mode = IEEE80211_POWERSAVE_PSP_CAM;
167 } else {
168 err(1, "unknown powersavemode");
169 }
170
171 set80211(s, IEEE80211_IOC_POWERSAVE, mode, 0, NULL);
172}
173
174void
175set80211powersave(const char *val, int d, int s, const struct afswtch *rafp)
176{
177 if (d == 0)
178 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_OFF,
179 0, NULL);
180 else
181 set80211(s, IEEE80211_IOC_POWERSAVE, IEEE80211_POWERSAVE_ON,
182 0, NULL);
183}
184
185void
186set80211powersavesleep(const char *val, int d, int s, const struct afswtch *rafp)
187{
188 set80211(s, IEEE80211_IOC_POWERSAVESLEEP, atoi(val), 0, NULL);
189}
190
191void
192set80211wepmode(const char *val, int d, int s, const struct afswtch *rafp)
193{
194 int mode;
195
196 if(strcasecmp(val, "off") == 0) {
197 mode = IEEE80211_WEP_OFF;
198 } else if(strcasecmp(val, "on") == 0) {
199 mode = IEEE80211_WEP_ON;
200 } else if(strcasecmp(val, "mixed") == 0) {
201 mode = IEEE80211_WEP_MIXED;
202 } else {
203 err(1, "unknown wep mode");
204 }
205
206 set80211(s, IEEE80211_IOC_WEP, mode, 0, NULL);
207}
208
209void
210set80211wep(const char *val, int d, int s, const struct afswtch *rafp)
211{
212 set80211(s, IEEE80211_IOC_WEP, d, 0, NULL);
213}
214
215void
216set80211weptxkey(const char *val, int d, int s, const struct afswtch *rafp)
217{
218 set80211(s, IEEE80211_IOC_WEPTXKEY, atoi(val)-1, 0, NULL);
219}
220
221void
222set80211wepkey(const char *val, int d, int s, const struct afswtch *rafp)
223{
224 int key = 0;
225 int len;
226 u_int8_t data[14];
227
228 if(isdigit(val[0]) && val[1] == ':') {
229 key = atoi(val)-1;
230 val += 2;
231 }
232
233 bzero(data, sizeof(data));
234 len = sizeof(data);
235 get_string(val, NULL, data, &len);
236
237 set80211(s, IEEE80211_IOC_WEPKEY, key, len, data);
238}
239
240/*
241 * This function is purly a NetBSD compatability interface. The NetBSD
242 * iterface is too inflexable, but it's there so we'll support it since
243 * it's not all that hard.
244 */
245void
246set80211nwkey(const char *val, int d, int s, const struct afswtch *rafp)
247{
248 int txkey;
249 int i, len;
250 u_int8_t data[14];
251
252 set80211(s, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL);
253
254 if(isdigit(val[0]) && val[1] == ':') {
255 txkey = val[0]-'0'-1;
256 val += 2;
257
258 for(i = 0; i < 4; i++) {
259 bzero(data, sizeof(data));
260 len = sizeof(data);
261 val = get_string(val, ",", data, &len);
262
263 set80211(s, IEEE80211_IOC_WEPKEY, i, len, data);
264 }
265 } else {
266 bzero(data, sizeof(data));
267 len = sizeof(data);
268 get_string(val, NULL, data, &len);
269 txkey = 0;
270
271 set80211(s, IEEE80211_IOC_WEPKEY, 0, len, data);
272
273 bzero(data, sizeof(data));
274 for(i = 1; i < 4; i++)
275 set80211(s, IEEE80211_IOC_WEPKEY, i, 0, data);
276 }
277
278 set80211(s, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL);
279}
280
281void
282ieee80211_status (s, info)
283 int s;
284 struct rt_addrinfo *info __unused;
285{
286 int i;
287 int num;
288 struct ieee80211req ireq;
289 u_int8_t data[32];
290 char spacer;
291
292 (void) memset(&ireq, 0, sizeof(ireq));
293 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
294 ireq.i_data = &data;
295
296 ireq.i_type = IEEE80211_IOC_SSID;
297 ireq.i_val = -1;
298 if (ioctl(s, SIOCG80211, &ireq) < 0) {
299 /* If we can't get the SSID, the this isn't an 802.11 device. */
300 return;
301 }
302 printf("\tssid ");
303 print_string(data, ireq.i_len);
304 num = 0;
305 ireq.i_type = IEEE80211_IOC_NUMSSIDS;
306 if (ioctl(s, SIOCG80211, &ireq) >= 0) {
307 num = ireq.i_val;
308 }
309 ireq.i_type = IEEE80211_IOC_SSID;
310 for (ireq.i_val = 0; ireq.i_val < num; ireq.i_val++) {
311 if (ioctl(s, SIOCG80211, &ireq) >= 0 && ireq.i_len > 0) {
312 printf(" %d:", ireq.i_val + 1);
313 print_string(data, ireq.i_len);
314 }
315 }
299 printf("\n");
300
301 ireq.i_type = IEEE80211_IOC_STATIONNAME;
302 if (ioctl(s, SIOCG80211, &ireq) != -1) {
303 printf("\tstationname ");
304 print_string(data, ireq.i_len);
305 printf("\n");
306 }
307
308 ireq.i_type = IEEE80211_IOC_CHANNEL;
309 if (ioctl(s, SIOCG80211, &ireq) < 0) {
310 goto end;
311 }
312 printf("\tchannel %d", ireq.i_val);
313
314 ireq.i_type = IEEE80211_IOC_AUTHMODE;
315 if (ioctl(s, SIOCG80211, &ireq) != -1) {
316 printf(" authmode");
317 switch (ireq.i_val) {
318 case IEEE80211_AUTH_NONE:
319 printf(" NONE");
320 break;
321 case IEEE80211_AUTH_OPEN:
322 printf(" OPEN");
323 break;
324 case IEEE80211_AUTH_SHARED:
325 printf(" SHARED");
326 break;
327 default:
328 printf(" UNKNOWN");
329 break;
330 }
331 }
332
333 ireq.i_type = IEEE80211_IOC_POWERSAVE;
334 if (ioctl(s, SIOCG80211, &ireq) != -1 &&
335 ireq.i_val != IEEE80211_POWERSAVE_NOSUP ) {
336 printf(" powersavemode");
337 switch (ireq.i_val) {
338 case IEEE80211_POWERSAVE_OFF:
339 printf(" OFF");
340 break;
341 case IEEE80211_POWERSAVE_CAM:
342 printf(" CAM");
343 break;
344 case IEEE80211_POWERSAVE_PSP:
345 printf(" PSP");
346 break;
347 case IEEE80211_POWERSAVE_PSP_CAM:
348 printf(" PSP-CAM");
349 break;
350 }
351
352 ireq.i_type = IEEE80211_IOC_POWERSAVESLEEP;
353 if (ioctl(s, SIOCG80211, &ireq) != -1) {
354 if(ireq.i_val)
355 printf(" powersavesleep %d", ireq.i_val);
356 }
357 }
358
359 printf("\n");
360
361 ireq.i_type = IEEE80211_IOC_WEP;
362 if (ioctl(s, SIOCG80211, &ireq) != -1 &&
363 ireq.i_val != IEEE80211_WEP_NOSUP) {
364 printf("\twepmode");
365 switch (ireq.i_val) {
366 case IEEE80211_WEP_OFF:
367 printf(" OFF");
368 break;
369 case IEEE80211_WEP_ON:
370 printf(" ON");
371 break;
372 case IEEE80211_WEP_MIXED:
373 printf(" MIXED");
374 break;
375 default:
376 printf(" UNKNOWN");
377 break;
378 }
379
380 /*
381 * If we get here then we've got WEP support so we need
382 * to print WEP status.
383 */
384
385 ireq.i_type = IEEE80211_IOC_WEPTXKEY;
386 if (ioctl(s, SIOCG80211, &ireq) < 0) {
387 warn("WEP support, but no tx key!");
388 goto end;
389 }
390 printf(" weptxkey %d", ireq.i_val+1);
391
392 ireq.i_type = IEEE80211_IOC_NUMWEPKEYS;
393 if (ioctl(s, SIOCG80211, &ireq) < 0) {
394 warn("WEP support, but no NUMWEPKEYS support!");
395 goto end;
396 }
397 num = ireq.i_val;
398
399 printf("\n");
400
401 ireq.i_type = IEEE80211_IOC_WEPKEY;
402 spacer = '\t';
403 for(i = 0; i < num; i++) {
404 ireq.i_val = i;
405 if (ioctl(s, SIOCG80211, &ireq) < 0) {
406 warn("WEP support, but can get keys!");
407 goto end;
408 }
409 if(ireq.i_len == 0 || ireq.i_len > 13)
410 continue;
411 printf("%cwepkey %d:%s", spacer, i+1,
412 ireq.i_len <= 5 ? "64-bit" : "128-bit");
413 if(spacer == '\t')
414 spacer = ' ';
415 }
416 if (spacer == ' ')
417 printf("\n");
418 }
419
420end:
421 return;
422}
423
424static void
425set80211(int s, int type, int val, int len, u_int8_t *data)
426{
427 struct ieee80211req ireq;
428
429 (void) memset(&ireq, 0, sizeof(ireq));
430 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
431 ireq.i_type = type;
432 ireq.i_val = val;
433 ireq.i_len = len;
434 ireq.i_data = data;
435 if(ioctl(s, SIOCS80211, &ireq) < 0)
436 err(1, "SIOCS80211");
437}
438
439static const char *
440get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp)
441{
442 int len;
443 int hexstr;
444 u_int8_t *p;
445
446 len = *lenp;
447 p = buf;
448 hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x');
449 if (hexstr)
450 val += 2;
451 for (;;) {
452 if (*val == '\0')
453 break;
454 if (sep != NULL && strchr(sep, *val) != NULL) {
455 val++;
456 break;
457 }
458 if (hexstr) {
459 if (!isxdigit((u_char)val[0]) ||
460 !isxdigit((u_char)val[1])) {
461 warnx("bad hexadecimal digits");
462 return NULL;
463 }
464 }
465 if (p > buf + len) {
466 if (hexstr)
467 warnx("hexadecimal digits too long");
468 else
469 warnx("strings too long");
470 return NULL;
471 }
472 if (hexstr) {
473#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
474 *p++ = (tohex((u_char)val[0]) << 4) |
475 tohex((u_char)val[1]);
476#undef tohex
477 val += 2;
478 } else
479 *p++ = *val++;
480 }
481 len = p - buf;
482 /* The string "-" is treated as the empty string. */
483 if (!hexstr && len == 1 && buf[0] == '-')
484 len = 0;
485 if (len < *lenp)
486 memset(p, 0, *lenp - len);
487 *lenp = len;
488 return val;
489}
490
491static void
492print_string(const u_int8_t *buf, int len)
493{
494 int i;
495 int hasspc;
496
497 i = 0;
498 hasspc = 0;
499 for(; i < len; i++) {
500 if (!isprint(buf[i]) && buf[i] != '\0')
501 break;
502 if (isspace(buf[i]))
503 hasspc++;
504 }
505 if (i == len) {
506 if (hasspc || len == 0 || buf[0] == '\0')
507 printf("\"%.*s\"", len, buf);
508 else
509 printf("%.*s", len, buf);
510 } else {
511 printf("0x");
512 for (i = 0; i < len; i++)
513 printf("%02x", buf[i]);
514 }
515}
516
316 printf("\n");
317
318 ireq.i_type = IEEE80211_IOC_STATIONNAME;
319 if (ioctl(s, SIOCG80211, &ireq) != -1) {
320 printf("\tstationname ");
321 print_string(data, ireq.i_len);
322 printf("\n");
323 }
324
325 ireq.i_type = IEEE80211_IOC_CHANNEL;
326 if (ioctl(s, SIOCG80211, &ireq) < 0) {
327 goto end;
328 }
329 printf("\tchannel %d", ireq.i_val);
330
331 ireq.i_type = IEEE80211_IOC_AUTHMODE;
332 if (ioctl(s, SIOCG80211, &ireq) != -1) {
333 printf(" authmode");
334 switch (ireq.i_val) {
335 case IEEE80211_AUTH_NONE:
336 printf(" NONE");
337 break;
338 case IEEE80211_AUTH_OPEN:
339 printf(" OPEN");
340 break;
341 case IEEE80211_AUTH_SHARED:
342 printf(" SHARED");
343 break;
344 default:
345 printf(" UNKNOWN");
346 break;
347 }
348 }
349
350 ireq.i_type = IEEE80211_IOC_POWERSAVE;
351 if (ioctl(s, SIOCG80211, &ireq) != -1 &&
352 ireq.i_val != IEEE80211_POWERSAVE_NOSUP ) {
353 printf(" powersavemode");
354 switch (ireq.i_val) {
355 case IEEE80211_POWERSAVE_OFF:
356 printf(" OFF");
357 break;
358 case IEEE80211_POWERSAVE_CAM:
359 printf(" CAM");
360 break;
361 case IEEE80211_POWERSAVE_PSP:
362 printf(" PSP");
363 break;
364 case IEEE80211_POWERSAVE_PSP_CAM:
365 printf(" PSP-CAM");
366 break;
367 }
368
369 ireq.i_type = IEEE80211_IOC_POWERSAVESLEEP;
370 if (ioctl(s, SIOCG80211, &ireq) != -1) {
371 if(ireq.i_val)
372 printf(" powersavesleep %d", ireq.i_val);
373 }
374 }
375
376 printf("\n");
377
378 ireq.i_type = IEEE80211_IOC_WEP;
379 if (ioctl(s, SIOCG80211, &ireq) != -1 &&
380 ireq.i_val != IEEE80211_WEP_NOSUP) {
381 printf("\twepmode");
382 switch (ireq.i_val) {
383 case IEEE80211_WEP_OFF:
384 printf(" OFF");
385 break;
386 case IEEE80211_WEP_ON:
387 printf(" ON");
388 break;
389 case IEEE80211_WEP_MIXED:
390 printf(" MIXED");
391 break;
392 default:
393 printf(" UNKNOWN");
394 break;
395 }
396
397 /*
398 * If we get here then we've got WEP support so we need
399 * to print WEP status.
400 */
401
402 ireq.i_type = IEEE80211_IOC_WEPTXKEY;
403 if (ioctl(s, SIOCG80211, &ireq) < 0) {
404 warn("WEP support, but no tx key!");
405 goto end;
406 }
407 printf(" weptxkey %d", ireq.i_val+1);
408
409 ireq.i_type = IEEE80211_IOC_NUMWEPKEYS;
410 if (ioctl(s, SIOCG80211, &ireq) < 0) {
411 warn("WEP support, but no NUMWEPKEYS support!");
412 goto end;
413 }
414 num = ireq.i_val;
415
416 printf("\n");
417
418 ireq.i_type = IEEE80211_IOC_WEPKEY;
419 spacer = '\t';
420 for(i = 0; i < num; i++) {
421 ireq.i_val = i;
422 if (ioctl(s, SIOCG80211, &ireq) < 0) {
423 warn("WEP support, but can get keys!");
424 goto end;
425 }
426 if(ireq.i_len == 0 || ireq.i_len > 13)
427 continue;
428 printf("%cwepkey %d:%s", spacer, i+1,
429 ireq.i_len <= 5 ? "64-bit" : "128-bit");
430 if(spacer == '\t')
431 spacer = ' ';
432 }
433 if (spacer == ' ')
434 printf("\n");
435 }
436
437end:
438 return;
439}
440
441static void
442set80211(int s, int type, int val, int len, u_int8_t *data)
443{
444 struct ieee80211req ireq;
445
446 (void) memset(&ireq, 0, sizeof(ireq));
447 (void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
448 ireq.i_type = type;
449 ireq.i_val = val;
450 ireq.i_len = len;
451 ireq.i_data = data;
452 if(ioctl(s, SIOCS80211, &ireq) < 0)
453 err(1, "SIOCS80211");
454}
455
456static const char *
457get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp)
458{
459 int len;
460 int hexstr;
461 u_int8_t *p;
462
463 len = *lenp;
464 p = buf;
465 hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x');
466 if (hexstr)
467 val += 2;
468 for (;;) {
469 if (*val == '\0')
470 break;
471 if (sep != NULL && strchr(sep, *val) != NULL) {
472 val++;
473 break;
474 }
475 if (hexstr) {
476 if (!isxdigit((u_char)val[0]) ||
477 !isxdigit((u_char)val[1])) {
478 warnx("bad hexadecimal digits");
479 return NULL;
480 }
481 }
482 if (p > buf + len) {
483 if (hexstr)
484 warnx("hexadecimal digits too long");
485 else
486 warnx("strings too long");
487 return NULL;
488 }
489 if (hexstr) {
490#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
491 *p++ = (tohex((u_char)val[0]) << 4) |
492 tohex((u_char)val[1]);
493#undef tohex
494 val += 2;
495 } else
496 *p++ = *val++;
497 }
498 len = p - buf;
499 /* The string "-" is treated as the empty string. */
500 if (!hexstr && len == 1 && buf[0] == '-')
501 len = 0;
502 if (len < *lenp)
503 memset(p, 0, *lenp - len);
504 *lenp = len;
505 return val;
506}
507
508static void
509print_string(const u_int8_t *buf, int len)
510{
511 int i;
512 int hasspc;
513
514 i = 0;
515 hasspc = 0;
516 for(; i < len; i++) {
517 if (!isprint(buf[i]) && buf[i] != '\0')
518 break;
519 if (isspace(buf[i]))
520 hasspc++;
521 }
522 if (i == len) {
523 if (hasspc || len == 0 || buf[0] == '\0')
524 printf("\"%.*s\"", len, buf);
525 else
526 printf("%.*s", len, buf);
527 } else {
528 printf("0x");
529 for (i = 0; i < len; i++)
530 printf("%02x", buf[i]);
531 }
532}
533