]> git.ipfire.org Git - thirdparty/iw.git/blame - util.c
add missing newline
[thirdparty/iw.git] / util.c
CommitLineData
748f8489 1#include <ctype.h>
51e9bd80
JB
2#include <netlink/attr.h>
3#include <errno.h>
4#include <stdbool.h>
ded1f078
JB
5#include <net/if.h>
6#include <string.h>
7#include <sys/ioctl.h>
8#include <unistd.h>
3d1e8704 9#include "iw.h"
f5f7b1d0 10#include "nl80211.h"
3d1e8704 11
febeb0c0 12void mac_addr_n2a(char *mac_addr, unsigned char *arg)
3d1e8704 13{
53e5ce7a 14 int i, l;
3d1e8704
LCC
15
16 l = 0;
17 for (i = 0; i < ETH_ALEN ; i++) {
18 if (i == 0) {
53e5ce7a 19 sprintf(mac_addr+l, "%02x", arg[i]);
3d1e8704
LCC
20 l += 2;
21 } else {
53e5ce7a 22 sprintf(mac_addr+l, ":%02x", arg[i]);
3d1e8704
LCC
23 l += 3;
24 }
25 }
3d1e8704
LCC
26}
27
28int mac_addr_a2n(unsigned char *mac_addr, char *arg)
29{
30 int i;
31
32 for (i = 0; i < ETH_ALEN ; i++) {
33 int temp;
34 char *cp = strchr(arg, ':');
35 if (cp) {
36 *cp = 0;
37 cp++;
38 }
39 if (sscanf(arg, "%x", &temp) != 1)
40 return -1;
41 if (temp < 0 || temp > 255)
42 return -1;
43
44 mac_addr[i] = temp;
45 if (!cp)
46 break;
47 arg = cp;
48 }
49 if (i < ETH_ALEN - 1)
50 return -1;
51
52 return 0;
53}
541ef425
JB
54
55static const char *ifmodes[NL80211_IFTYPE_MAX + 1] = {
56 "unspecified",
57 "IBSS",
34e78ed0 58 "managed",
541ef425 59 "AP",
34e78ed0 60 "AP/VLAN",
541ef425 61 "WDS",
34e78ed0 62 "monitor",
541ef425
JB
63 "mesh point"
64};
65
66static char modebuf[100];
67
68const char *iftype_name(enum nl80211_iftype iftype)
69{
70 if (iftype <= NL80211_IFTYPE_MAX)
71 return ifmodes[iftype];
72 sprintf(modebuf, "Unknown mode (%d)", iftype);
73 return modebuf;
74}
379f8397
JB
75
76int ieee80211_channel_to_frequency(int chan)
77{
78 if (chan < 14)
79 return 2407 + chan * 5;
80
81 if (chan == 14)
82 return 2484;
83
84 /* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */
85 return (chan + 1000) * 5;
86}
87
88int ieee80211_frequency_to_channel(int freq)
89{
90 if (freq == 2484)
91 return 14;
92
93 if (freq < 2484)
94 return (freq - 2407) / 5;
95
96 /* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */
97 return freq/5 - 1000;
98}
748f8489
JB
99
100void print_ssid_escaped(const uint8_t len, const uint8_t *data)
101{
102 int i;
103
104 for (i = 0; i < len; i++) {
105 if (isprint(data[i]))
106 printf("%c", data[i]);
107 else
108 printf("\\x%.2x", data[i]);
109 }
110}
51e9bd80
JB
111
112static int hex2num(char digit)
113{
114 if (!isxdigit(digit))
115 return -1;
116 if (isdigit(digit))
117 return digit - '0';
118 return tolower(digit) - 'a' + 10;
119}
120
121static int hex2byte(char *hex)
122{
123 int d1, d2;
124
125 d1 = hex2num(hex[0]);
126 if (d1 < 0)
127 return -1;
128 d2 = hex2num(hex[1]);
129 if (d2 < 0)
130 return -1;
131 return (d1 << 4) | d2;
132}
133
134static char *hex2bin(char *hex, char *buf)
135{
136 char *result = buf;
137 int d;
138
139 while (hex[0]) {
140 d = hex2byte(hex);
141 if (d < 0)
142 return NULL;
143 buf[0] = d;
144 buf++;
145 hex += 2;
146 }
147
148 return result;
149}
150
151int parse_keys(struct nl_msg *msg, char **argv, int argc)
152{
153 struct nlattr *keys;
154 int i = 0;
155 char keybuf[13];
156
157 if (!argc)
158 return 1;
159
160 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
161
162 keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
163 if (!keys)
164 return -ENOBUFS;
165
166 do {
167 char *arg = *argv;
168 int pos = 0, keylen;
169 struct nlattr *key = nla_nest_start(msg, ++i);
170 char *keydata;
171
172 if (!key)
173 return -ENOBUFS;
174
175 if (arg[pos] == 'd') {
176 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
177 pos++;
178 if (arg[pos] == ':')
179 pos++;
180 }
181
182 if (!isdigit(arg[pos]))
183 goto explain;
184 NLA_PUT_U8(msg, NL80211_KEY_IDX, arg[pos++] - '0');
185 if (arg[pos++] != ':')
186 goto explain;
187 keydata = arg + pos;
188 switch (strlen(keydata)) {
189 case 10:
190 keydata = hex2bin(keydata, keybuf);
191 case 5:
192 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC01);
193 keylen = 5;
194 break;
195 case 26:
196 keydata = hex2bin(keydata, keybuf);
197 case 13:
198 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC05);
199 keylen = 13;
200 break;
201 default:
202 goto explain;
203 }
204
205 if (!keydata)
206 goto explain;
207
208 NLA_PUT(msg, NL80211_KEY_DATA, keylen, keydata);
209
210 nla_nest_end(msg, key);
211 argv++;
212 argc--;
213 } while (argc);
214
215 nla_nest_end(msg, keys);
216
217 return 0;
218 nla_put_failure:
219 return -ENOBUFS;
220 explain:
221 fprintf(stderr, "key must be [d:]index:data where\n"
222 " 'd:' means default (transmit) key\n"
223 " 'index:' is a single digit (0-3)\n"
224 " 'data' must be 5 or 13 ascii chars\n"
225 " or 10 or 26 hex digits\n"
226 "for example: d:2:6162636465 is the same as d:2:abcde\n");
227 return 2;
228}
ded1f078
JB
229
230int set_interface_up(const char *ifname)
231{
232 struct ifreq ifr;
233 int fd = socket(PF_INET, SOCK_DGRAM, 0);
234 int err = 0;
235
236 if (fd < 0)
237 return -errno;
238
239 memset(&ifr, 0, sizeof(ifr));
240 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
241 if (ioctl(fd, SIOCGIFFLAGS, &ifr)) {
242 err = -errno;
243 goto out;
244 }
245
246 if (ifr.ifr_flags & IFF_UP)
247 goto out;
248
249 ifr.ifr_flags |= IFF_UP;
250 if (ioctl(fd, SIOCSIFFLAGS, &ifr))
251 err = -errno;
252
253 out:
254 close(fd);
255 return err;
256}