]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/common/wpa_helpers.c
Update hostapd/wpa_supplicant to 2.8 to fix multiple vulnerabilities.
[FreeBSD/FreeBSD.git] / contrib / wpa / src / common / wpa_helpers.c
1 /*
2  * wpa_supplicant ctrl_iface helpers
3  * Copyright (c) 2010-2011, Atheros Communications, Inc.
4  * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9
10 #include "includes.h"
11 #include <time.h>
12
13 #include "common.h"
14 #include "wpa_ctrl.h"
15 #include "wpa_helpers.h"
16
17
18 char *wpas_ctrl_path = "/var/run/wpa_supplicant/";
19 static int default_timeout = 60;
20
21
22 static struct wpa_ctrl * wpa_open_ctrl(const char *ifname)
23 {
24         char buf[128];
25         struct wpa_ctrl *ctrl;
26
27         os_snprintf(buf, sizeof(buf), "%s%s", wpas_ctrl_path, ifname);
28         ctrl = wpa_ctrl_open(buf);
29         if (ctrl == NULL)
30                 printf("wpa_command: wpa_ctrl_open(%s) failed\n", buf);
31         return ctrl;
32 }
33
34
35 int wpa_command(const char *ifname, const char *cmd)
36 {
37         struct wpa_ctrl *ctrl;
38         char buf[128];
39         size_t len;
40
41         printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
42         ctrl = wpa_open_ctrl(ifname);
43         if (ctrl == NULL)
44                 return -1;
45         len = sizeof(buf);
46         if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
47                 printf("wpa_command: wpa_ctrl_request failed\n");
48                 wpa_ctrl_close(ctrl);
49                 return -1;
50         }
51         wpa_ctrl_close(ctrl);
52         buf[len] = '\0';
53         if (strncmp(buf, "FAIL", 4) == 0) {
54                 printf("wpa_command: Command failed (FAIL received)\n");
55                 return -1;
56         }
57         return 0;
58 }
59
60
61 int wpa_command_resp(const char *ifname, const char *cmd,
62                      char *resp, size_t resp_size)
63 {
64         struct wpa_ctrl *ctrl;
65         size_t len;
66
67         printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
68         ctrl = wpa_open_ctrl(ifname);
69         if (ctrl == NULL)
70                 return -1;
71         len = resp_size;
72         if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) {
73                 printf("wpa_command: wpa_ctrl_request failed\n");
74                 wpa_ctrl_close(ctrl);
75                 return -1;
76         }
77         wpa_ctrl_close(ctrl);
78         resp[len] = '\0';
79         return 0;
80 }
81
82
83 struct wpa_ctrl * open_wpa_mon(const char *ifname)
84 {
85         struct wpa_ctrl *ctrl;
86
87         ctrl = wpa_open_ctrl(ifname);
88         if (ctrl == NULL)
89                 return NULL;
90         if (wpa_ctrl_attach(ctrl) < 0) {
91                 wpa_ctrl_close(ctrl);
92                 return NULL;
93         }
94
95         return ctrl;
96 }
97
98
99 int get_wpa_cli_event2(struct wpa_ctrl *mon,
100                        const char *event, const char *event2,
101                        char *buf, size_t buf_size)
102 {
103         int fd, ret;
104         fd_set rfd;
105         char *pos;
106         struct timeval tv;
107         time_t start, now;
108
109         printf("Waiting for wpa_cli event %s\n", event);
110         fd = wpa_ctrl_get_fd(mon);
111         if (fd < 0)
112                 return -1;
113
114         time(&start);
115         while (1) {
116                 size_t len;
117
118                 FD_ZERO(&rfd);
119                 FD_SET(fd, &rfd);
120                 tv.tv_sec = default_timeout;
121                 tv.tv_usec = 0;
122                 ret = select(fd + 1, &rfd, NULL, NULL, &tv);
123                 if (ret == 0) {
124                         printf("Timeout on waiting for event %s\n", event);
125                         return -1;
126                 }
127                 if (ret < 0) {
128                         printf("select: %s\n", strerror(errno));
129                         return -1;
130                 }
131                 len = buf_size;
132                 if (wpa_ctrl_recv(mon, buf, &len) < 0) {
133                         printf("Failure while waiting for event %s\n", event);
134                         return -1;
135                 }
136                 if (len == buf_size)
137                         len--;
138                 buf[len] = '\0';
139
140                 pos = strchr(buf, '>');
141                 if (pos &&
142                     (strncmp(pos + 1, event, strlen(event)) == 0 ||
143                      (event2 &&
144                       strncmp(pos + 1, event2, strlen(event2)) == 0)))
145                         return 0; /* Event found */
146
147                 time(&now);
148                 if ((int) (now - start) > default_timeout) {
149                         printf("Timeout on waiting for event %s\n", event);
150                         return -1;
151                 }
152         }
153 }
154
155
156 int get_wpa_cli_event(struct wpa_ctrl *mon,
157                       const char *event, char *buf, size_t buf_size)
158 {
159         return get_wpa_cli_event2(mon, event, NULL, buf, buf_size);
160 }
161
162
163 int get_wpa_status(const char *ifname, const char *field, char *obuf,
164                    size_t obuf_size)
165 {
166         struct wpa_ctrl *ctrl;
167         char buf[4096];
168         char *pos, *end;
169         size_t len, flen;
170
171         ctrl = wpa_open_ctrl(ifname);
172         if (ctrl == NULL)
173                 return -1;
174         len = sizeof(buf);
175         if (wpa_ctrl_request(ctrl, "STATUS-NO_EVENTS", 16, buf, &len,
176                              NULL) < 0) {
177                 wpa_ctrl_close(ctrl);
178                 return -1;
179         }
180         wpa_ctrl_close(ctrl);
181         buf[len] = '\0';
182
183         flen = strlen(field);
184         pos = buf;
185         while (pos + flen < buf + len) {
186                 if (pos > buf) {
187                         if (*pos != '\n') {
188                                 pos++;
189                                 continue;
190                         }
191                         pos++;
192                 }
193                 if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
194                         pos++;
195                         continue;
196                 }
197                 pos += flen + 1;
198                 end = strchr(pos, '\n');
199                 if (end == NULL)
200                         return -1;
201                 *end++ = '\0';
202                 if (end - pos > (int) obuf_size)
203                         return -1;
204                 memcpy(obuf, pos, end - pos);
205                 return 0;
206         }
207
208         return -1;
209 }
210
211
212 int wait_ip_addr(const char *ifname, int timeout)
213 {
214         char ip[30];
215         int count = timeout;
216         struct wpa_ctrl *ctrl;
217
218         while (count > 0) {
219                 printf("%s: ifname='%s' - %d seconds remaining\n",
220                        __func__, ifname, count);
221                 count--;
222                 if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0
223                     && strlen(ip) > 0) {
224                         printf("IP address found: '%s'\n", ip);
225                         if (strncmp(ip, "169.254.", 8) != 0)
226                                 return 0;
227                 }
228                 ctrl = wpa_open_ctrl(ifname);
229                 if (ctrl == NULL)
230                         return -1;
231                 wpa_ctrl_close(ctrl);
232                 sleep(1);
233         }
234         printf("%s: Could not get IP address for ifname='%s'", __func__,
235                ifname);
236         return -1;
237 }
238
239
240 int add_network(const char *ifname)
241 {
242         char res[30];
243
244         if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0)
245                 return -1;
246         return atoi(res);
247 }
248
249
250 int set_network(const char *ifname, int id, const char *field,
251                 const char *value)
252 {
253         char buf[200];
254         snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value);
255         return wpa_command(ifname, buf);
256 }
257
258
259 int set_network_quoted(const char *ifname, int id, const char *field,
260                        const char *value)
261 {
262         char buf[200];
263         snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"",
264                  id, field, value);
265         return wpa_command(ifname, buf);
266 }
267
268
269 int add_cred(const char *ifname)
270 {
271         char res[30];
272
273         if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0)
274                 return -1;
275         return atoi(res);
276 }
277
278
279 int set_cred(const char *ifname, int id, const char *field, const char *value)
280 {
281         char buf[200];
282         snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value);
283         return wpa_command(ifname, buf);
284 }
285
286
287 int set_cred_quoted(const char *ifname, int id, const char *field,
288                     const char *value)
289 {
290         char buf[200];
291         snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"",
292                  id, field, value);
293         return wpa_command(ifname, buf);
294 }