Rename remaining instances of ALL to PROGRAMS
[madwifi/.git] / tools / athchans.c
1 /*-
2  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
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, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  * 3. Neither the names of the above-listed copyright holders nor the names
16  *    of any contributors may be used to endorse or promote products derived
17  *    from this software without specific prior written permission.
18  *
19  * Alternatively, this software may be distributed under the terms of the
20  * GNU General Public License ("GPL") version 2 as published by the Free
21  * Software Foundation.
22  *
23  * NO WARRANTY
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
29  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34  * THE POSSIBILITY OF SUCH DAMAGES.
35  *
36  * $Id$
37  */
38
39 /*
40  * athchans [-i interface] chan ...
41  * (default interface is wifi0).
42  */
43 #include <sys/types.h>
44 #include <sys/file.h>
45 #include <sys/ioctl.h>
46 #include <sys/socket.h>
47
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <ctype.h>
52 #include <getopt.h>
53 #include <err.h>
54
55 #include <include/compat.h>
56
57 #include "wireless_copy.h"
58 #include "net80211/ieee80211.h"
59 #include "net80211/ieee80211_crypto.h"
60 #include "net80211/ieee80211_ioctl.h"
61
62 static  int s = -1;
63 static const char *progname;
64
65 static void
66 checksocket()
67 {
68         if (s < 0 ? (s = socket(AF_INET, SOCK_DGRAM, 0)) == -1 : 0)
69                 perror("socket(SOCK_DGRAM)");
70 }
71
72 #define IOCTL_ERR(x) [x - SIOCIWFIRSTPRIV] = "ioctl[" #x "]"
73 static int
74 set80211priv(const char *dev, int op, void *data, int len, int show_err)
75 {
76         struct iwreq iwr;
77
78         checksocket();
79
80         memset(&iwr, 0, sizeof(iwr));
81         strncpy(iwr.ifr_name, dev, IFNAMSIZ);
82         if (len < IFNAMSIZ) {
83                 /*
84                  * Argument data fits inline; put it there.
85                  */
86                 memcpy(iwr.u.name, data, len);
87         } else {
88                 /*
89                  * Argument data too big for inline transfer; setup a
90                  * parameter block instead; the kernel will transfer
91                  * the data for the driver.
92                  */
93                 iwr.u.data.pointer = data;
94                 iwr.u.data.length = len;
95         }
96
97         if (ioctl(s, op, &iwr) < 0) {
98                 if (show_err) {
99                         static const char *opnames[] = {
100                                 IOCTL_ERR(IEEE80211_IOCTL_SETPARAM),
101                                 IOCTL_ERR(IEEE80211_IOCTL_GETPARAM),
102                                 IOCTL_ERR(IEEE80211_IOCTL_SETMODE),
103                                 IOCTL_ERR(IEEE80211_IOCTL_GETMODE),
104                                 IOCTL_ERR(IEEE80211_IOCTL_SETWMMPARAMS),
105                                 IOCTL_ERR(IEEE80211_IOCTL_GETWMMPARAMS),
106                                 IOCTL_ERR(IEEE80211_IOCTL_SETCHANLIST),
107                                 IOCTL_ERR(IEEE80211_IOCTL_GETCHANLIST),
108                                 IOCTL_ERR(IEEE80211_IOCTL_CHANSWITCH),
109                                 IOCTL_ERR(IEEE80211_IOCTL_GETCHANINFO),
110                                 IOCTL_ERR(IEEE80211_IOCTL_SETOPTIE),
111                                 IOCTL_ERR(IEEE80211_IOCTL_GETOPTIE),
112                                 IOCTL_ERR(IEEE80211_IOCTL_SETMLME),
113                                 IOCTL_ERR(IEEE80211_IOCTL_RADAR),
114                                 IOCTL_ERR(IEEE80211_IOCTL_SETKEY),
115                                 IOCTL_ERR(IEEE80211_IOCTL_DELKEY),
116                                 IOCTL_ERR(IEEE80211_IOCTL_HALMAP),
117                                 IOCTL_ERR(IEEE80211_IOCTL_ADDMAC),
118                                 IOCTL_ERR(IEEE80211_IOCTL_DELMAC),
119                                 IOCTL_ERR(IEEE80211_IOCTL_WDSADDMAC),
120                                 IOCTL_ERR(IEEE80211_IOCTL_WDSDELMAC),
121                                 IOCTL_ERR(IEEE80211_IOCTL_READREG),
122                                 IOCTL_ERR(IEEE80211_IOCTL_WRITEREG),
123                         };
124                         if (IEEE80211_IOCTL_SETPARAM <= op &&
125                             op <= IEEE80211_IOCTL_SETCHANLIST)
126                                 perror(opnames[op - SIOCIWFIRSTPRIV]);
127                         else
128                                 perror("ioctl[unknown???]");
129                 }
130                 return -1;
131         }
132         return 0;
133 }
134
135 static void
136 usage(void)
137 {
138         fprintf(stderr, "usage: %s [-i device] channels...\n", progname);
139         exit(-1);
140 }
141
142 #define MAXCHAN ((int)(sizeof(struct ieee80211req_chanlist) * NBBY))
143 int
144 main(int argc, char *argv[])
145 {
146         const char *ifname = "wifi0";
147         struct ieee80211req_chanlist chanlist;
148         int c;
149
150         progname = argv[0];
151         while ((c = getopt(argc, argv, "i:")) != -1)
152                 switch (c) {
153                 case 'i':
154                         ifname = optarg;
155                         break;
156                 default:
157                         usage();
158                         /*NOTREACHED*/
159                 }
160         argc -= optind;
161         argv += optind;
162         if (argc < 1)
163                 usage();
164
165         memset(&chanlist, 0, sizeof(chanlist));
166         for (; argc > 0; argc--, argv++) {
167                 int first, last, f;
168
169                 switch (sscanf(argv[0], "%u-%u", &first, &last)) {
170                 case 1:
171                         if (first > MAXCHAN)
172                                 errx(-1, "%s: channel %u out of range, max %u",
173                                         progname, first, MAXCHAN);
174                         setbit(chanlist.ic_channels, first);
175                         break;
176                 case 2:
177                         if (first > MAXCHAN)
178                                 errx(-1, "%s: channel %u out of range, max %u",
179                                         progname, first, MAXCHAN);
180                         if (last > MAXCHAN)
181                                 errx(-1, "%s: channel %u out of range, max %u",
182                                         progname, last, MAXCHAN);
183                         if (first > last)
184                                 errx(-1, "%s: void channel range, %u > %u",
185                                         progname, first, last);
186                         for (f = first; f <= last; f++)
187                                 setbit(chanlist.ic_channels, f);
188                         break;
189                 }
190         }
191         return set80211priv(ifname, IEEE80211_IOCTL_SETCHANLIST,
192                 &chanlist, sizeof(chanlist), 1);
193 }