- Add multi pseudo network interface support for vkernel
[dragonfly.git] / usr.sbin / ipwcontrol / ipwcontrol.c
blobb0474ba560c8abb5e54d465ba5991d3eb65136e4
1 /*-
2 * Copyright (c) 2004, 2005
3 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR CONTRIBUTORS 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.
27 * $Id: ipwcontrol.c,v 1.5.2.1 2005/01/13 20:01:05 damien Exp $
28 * $DragonFly: src/usr.sbin/ipwcontrol/Attic/ipwcontrol.c,v 1.3 2005/12/05 01:04:01 swildner Exp $
31 #include <sys/cdefs.h>
33 #include <sys/types.h>
34 #include <sys/ioctl.h>
35 #include <sys/mman.h>
36 #include <sys/socket.h>
37 #include <sys/stat.h>
38 #include <sys/sysctl.h>
40 #include <net/if.h>
42 #include <err.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <sysexits.h>
49 #include <unistd.h>
51 #define SIOCSLOADFW _IOW('i', 137, struct ifreq)
52 #define SIOCSKILLFW _IOW('i', 138, struct ifreq)
54 static void usage(void);
55 static int do_req(const char *, unsigned long, void *);
56 static void load_firmware(const char *, const char *);
57 static void kill_firmware(const char *);
58 static void get_radio_state(const char *);
59 static void get_statistics(const char *);
61 int
62 main(int argc, char **argv)
64 int ch;
65 const char *iface;
67 opterr = 0;
68 ch = getopt(argc, argv, "i:");
69 if (ch == 'i') {
70 iface = optarg;
71 } else {
72 if (argc > 1 && argv[1][0] != '-') {
73 iface = argv[1];
74 optind = 2;
75 } else {
76 iface = "ipw0";
77 optind = 1;
79 optreset = 1;
81 opterr = 1;
83 while ((ch = getopt(argc, argv, "f:kr")) != -1) {
84 switch (ch) {
85 case 'f':
86 load_firmware(iface, optarg);
87 return EX_OK;
89 case 'k':
90 kill_firmware(iface);
91 return EX_OK;
93 case 'r':
94 get_radio_state(iface);
95 return EX_OK;
97 default:
98 usage();
102 get_statistics(iface);
104 return EX_OK;
107 extern char *__progname;
109 static void
110 usage(void)
112 fprintf(stderr, "usage: %s -i iface\n"
113 "\t%s -i iface -f firmware\n"
114 "\t%s -i iface -k\n"
115 "\t%s -i iface -r\n", __progname, __progname, __progname,
116 __progname);
118 exit(EX_USAGE);
121 static int
122 do_req(const char *iface, unsigned long req, void *data)
124 int s;
125 struct ifreq ifr;
126 int error;
128 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
129 err(EX_OSERR, "Can't create socket");
131 memset(&ifr, 0, sizeof(ifr));
132 strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
133 ifr.ifr_data = data;
134 error = ioctl(s, req, &ifr);
136 close(s);
138 return error;
141 static void
142 load_firmware(const char *iface, const char *firmware)
144 int fd;
145 struct stat st;
146 void *map;
148 if ((fd = open(firmware, O_RDONLY)) == -1)
149 err(EX_OSERR, "%s", firmware);
151 if (fstat(fd, &st) == -1)
152 err(EX_OSERR, "Unable to stat %s", firmware);
154 if ((map = mmap(NULL, st.st_size, PROT_READ, 0, fd, 0)) == NULL)
155 err(EX_OSERR, "Can't map %s into memory", firmware);
157 if (do_req(iface, SIOCSLOADFW, map) == -1)
158 err(EX_OSERR, "Can't load %s to driver", firmware);
160 munmap(map, st.st_size);
161 close(fd);
164 static void
165 kill_firmware(const char *iface)
167 if (do_req(iface, SIOCSKILLFW, NULL) == -1)
168 err(EX_OSERR, "Can't kill firmware");
171 static void
172 get_radio_state(const char *iface)
174 int radio, len;
175 char sysctl_name[24];
177 len = snprintf(sysctl_name, sizeof(sysctl_name), "hw.%s.radio", iface);
178 if (len == -1 || len > (int)sizeof(sysctl_name))
179 err(EX_OSERR, "Could not get radio transmitter state");
181 len = sizeof radio;
182 if (sysctlbyname(sysctl_name, &radio, &len, NULL, 0) == -1)
183 err(EX_OSERR, "Could not get radio transmitter state");
185 printf("Radio is %s\n", radio ? "ON" : "OFF");
188 struct statistic {
189 int index;
190 const char *desc;
191 int unit;
192 #define INT 1
193 #define HEX 2
194 #define MASK HEX
195 #define PERCENTAGE 3
196 #define BOOL 4
200 * TIM = Traffic Information Message
201 * DTIM = Delivery TIM
202 * ATIM = Announcement TIM
203 * PSP = Power Save Poll
204 * RTS = Request To Send
205 * CTS = Clear To Send
206 * RSSI = Received Signal Strength Indicator
209 static const struct statistic tbl[] = {
210 { 1, "Number of frames submitted for transfer", INT },
211 { 2, "Number of frames transmitted", INT },
212 { 3, "Number of unicast frames transmitted", INT },
213 { 4, "Number of unicast frames transmitted at 1Mb/s", INT },
214 { 5, "Number of unicast frames transmitted at 2Mb/s", INT },
215 { 6, "Number of unicast frames transmitted at 5.5Mb/s", INT },
216 { 7, "Number of unicast frames transmitted at 11Mb/s", INT },
218 { 13, "Number of multicast frames transmitted at 1Mb/s", INT },
219 { 14, "Number of multicast frames transmitted at 2Mb/s", INT },
220 { 15, "Number of multicast frames transmitted at 5.5Mb/s", INT },
221 { 16, "Number of multicast frames transmitted at 11Mb/s", INT },
223 { 21, "Number of null frames transmitted", INT },
224 { 22, "Number of RTS frames transmitted", INT },
225 { 23, "Number of CTS frames transmitted", INT },
226 { 24, "Number of ACK frames transmitted", INT },
227 { 25, "Number of association requests transmitted", INT },
228 { 26, "Number of association responses transmitted", INT },
229 { 27, "Number of reassociation requests transmitted", INT },
230 { 28, "Number of reassociation responses transmitted", INT },
231 { 29, "Number of probe requests transmitted", INT },
232 { 30, "Number of probe reponses transmitted", INT },
233 { 31, "Number of beacons transmitted", INT },
234 { 32, "Number of ATIM frames transmitted", INT },
235 { 33, "Number of disassociation requests transmitted", INT },
236 { 34, "Number of authentication requests transmitted", INT },
237 { 35, "Number of deauthentication requests transmitted", INT },
239 { 41, "Number of bytes transmitted", INT },
240 { 42, "Number of transmission retries", INT },
241 { 43, "Number of transmission retries at 1Mb/s", INT },
242 { 44, "Number of transmission retries at 2Mb/s", INT },
243 { 45, "Number of transmission retries at 5.5Mb/s", INT },
244 { 46, "Number of transmission retries at 11Mb/s", INT },
246 { 51, "Number of transmission failures", INT },
248 { 54, "Number of transmission aborted due to DMA", INT },
250 { 56, "Number of disassociation failures", INT },
252 { 58, "Number of spanning tree frames transmitted", INT },
253 { 59, "Number of transmission errors due to missing ACK", INT },
255 { 61, "Number of frames received", INT },
256 { 62, "Number of unicast frames received", INT },
257 { 63, "Number of unicast frames received at 1Mb/s", INT },
258 { 64, "Number of unicast frames received at 2Mb/s", INT },
259 { 65, "Number of unicast frames received at 5.5Mb/s", INT },
260 { 66, "Number of unicast frames received at 11Mb/s", INT },
262 { 71, "Number of multicast frames received", INT },
263 { 72, "Number of multicast frames received at 1Mb/s", INT },
264 { 73, "Number of multicast frames received at 2Mb/s", INT },
265 { 74, "Number of multicast frames received at 5.5Mb/s", INT },
266 { 75, "Number of multicast frames received at 11Mb/s", INT },
268 { 80, "Number of null frames received", INT },
269 { 81, "Number of poll frames received", INT },
270 { 82, "Number of RTS frames received", INT },
271 { 83, "Number of CTS frames received", INT },
272 { 84, "Number of ACK frames received", INT },
273 { 85, "Number of CF-End frames received", INT },
274 { 86, "Number of CF-End + CF-Ack frames received", INT },
275 { 87, "Number of association requests received", INT },
276 { 88, "Number of association responses received", INT },
277 { 89, "Number of reassociation requests received", INT },
278 { 90, "Number of reassociation responses received", INT },
279 { 91, "Number of probe requests received", INT },
280 { 92, "Number of probe reponses received", INT },
281 { 93, "Number of beacons received", INT },
282 { 94, "Number of ATIM frames received", INT },
283 { 95, "Number of disassociation requests received", INT },
284 { 96, "Number of authentication requests received", INT },
285 { 97, "Number of deauthentication requests received", INT },
287 { 101, "Number of bytes received", INT },
288 { 102, "Number of frames with a bad CRC received", INT },
289 { 103, "Number of frames with a bad CRC received at 1Mb/s", INT },
290 { 104, "Number of frames with a bad CRC received at 2Mb/s", INT },
291 { 105, "Number of frames with a bad CRC received at 5.5Mb/s", INT },
292 { 106, "Number of frames with a bad CRC received at 11Mb/s", INT },
294 { 112, "Number of duplicated frames received at 1Mb/s", INT },
295 { 113, "Number of duplicated frames received at 2Mb/s", INT },
296 { 114, "Number of duplicated frames received at 5.5Mb/s", INT },
297 { 115, "Number of duplicated frames received at 11Mb/s", INT },
299 { 119, "Number of duplicated frames received", INT },
301 { 123, "Number of frames with a bad protocol received", INT },
302 { 124, "Boot time", INT },
303 { 125, "Number of frames dropped due to missing buffer", INT },
304 { 126, "Number of frames dropped due to DMA", INT },
306 { 128, "Number of frames dropped due to missing fragment", INT },
307 { 129, "Number of frames dropped due to non-seq fragment", INT },
308 { 130, "Number of frames dropped due to missing first frame", INT },
309 { 131, "Number of frames dropped due to uncompleted frame", INT },
311 { 137, "Number of times adapter suspended", INT },
312 { 138, "Beacon timeout", INT },
313 { 139, "Number of poll response timeouts", INT },
315 { 141, "Number of PSP DTIM frames received", INT },
316 { 142, "Number of PSP TIM frames received", INT },
317 { 143, "PSP station Id", INT },
319 { 147, "RTC time of last association", INT },
320 { 148, "Percentage of missed beacons", PERCENTAGE },
321 { 149, "Percentage of missed transmission retries", PERCENTAGE },
323 { 151, "Number of access points in access points table", INT },
325 { 153, "Number of associations", INT },
326 { 154, "Number of association failures", INT },
327 { 156, "Number of full scans", INT },
328 { 157, "Card disabled", BOOL },
330 { 160, "RSSI at time of association", INT },
331 { 161, "Number of reassociations due to no probe response", INT },
332 { 162, "Number of reassociations due to poor line quality", INT },
333 { 163, "Number of reassociations due to load", INT },
334 { 164, "Number of reassociations due to access point RSSI level", INT },
335 { 165, "Number of reassociations due to load leveling", INT },
337 { 170, "Number of times authentication failed", INT },
338 { 171, "Number of times authentication response failed", INT },
339 { 172, "Number of entries in association table", INT },
340 { 173, "Average RSSI", INT },
342 { 176, "Self test status", INT },
343 { 177, "Power mode", INT },
344 { 178, "Power index", INT },
345 { 179, "IEEE country code", HEX },
346 { 180, "Channels supported for this country", MASK },
347 { 181, "Number of adapter warm resets", INT },
348 { 182, "Beacon interval", INT },
350 { 184, "Princeton version", INT },
351 { 185, "Antenna diversity disabled", BOOL },
352 { 186, "CCA RSSI", INT },
353 { 187, "Number of times EEPROM updated", INT },
354 { 188, "Beacon intervals between DTIM", INT },
355 { 189, "Current channel", INT },
356 { 190, "RTC time", INT },
357 { 191, "Operating mode", INT },
358 { 192, "Transmission rate", HEX },
359 { 193, "Supported transmission rates", MASK },
360 { 194, "ATIM window", INT },
361 { 195, "Supported basic transmission rates", MASK },
362 { 196, "Adapter highest rate", HEX },
363 { 197, "Access point highest rate", HEX },
364 { 198, "Management frame capability", BOOL },
365 { 199, "Type of authentication", INT },
366 { 200, "Adapter card platform type", INT },
367 { 201, "RTS threshold", INT },
368 { 202, "International mode", BOOL },
369 { 203, "Fragmentation threshold", INT },
371 { 213, "Microcode version", INT },
373 { 0, NULL, 0 }
376 static void
377 get_statistics(const char *iface)
379 static u_int32_t stats[256];
380 const struct statistic *st;
381 int len;
382 char sysctl_name[24];
384 len = snprintf(sysctl_name, sizeof(sysctl_name), "hw.%s.stats", iface);
385 if (len == -1 || len > (int)sizeof(sysctl_name))
386 err(EX_OSERR, "Can't retrieve statistics");
388 len = sizeof stats;
389 if (sysctlbyname(sysctl_name, stats, &len, NULL, 0) == -1)
390 err(EX_OSERR, "Can't retrieve statistics");
392 for (st = tbl; st->index != 0; st++) {
393 printf("%-60s[", st->desc);
394 switch (st->unit) {
395 case INT:
396 printf("%u", stats[st->index]);
397 break;
399 case BOOL:
400 printf(stats[st->index] ? "true" : "false");
401 break;
403 case PERCENTAGE:
404 printf("%u%%", stats[st->index]);
405 break;
407 case HEX:
408 default:
409 printf("0x%08X", stats[st->index]);
411 printf("]\n");