1 /*
2 * WPA Supplicant - driver interaction with generic Linux Wireless Extensions
3 * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 *
14 * This file implements a driver interface for the Linux Wireless Extensions.
15 * When used with WE-18 or newer, this interface can be used as-is with number
16 * of drivers. In addition to this, some of the common functions in this file
17 * can be used by other driver interface implementations that use generic WE
18 * ioctls, but require private ioctls for some of the functionality.
19 */
20
21 #include "includes.h"
22 #include <sys/ioctl.h>
23 #include <net/if_arp.h>
24 #include <net/if.h>
25
26 #include "wireless_copy.h"
27 #include "common.h"
28 #include "driver.h"
29 #include "eloop.h"
30 #include "priv_netlink.h"
31 #include "driver_wext.h"
32 #include "ieee802_11_defs.h"
33 #include "wpa_common.h"
34 #include "wpa_ctrl.h"
35 #include "wpa_supplicant_i.h"
36 #include "config.h"
37
38
39 static int wpa_driver_wext_flush_pmkid(void *priv);
40 static int wpa_driver_wext_get_range(void *priv);
41 static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
42 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv);
43
44
wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data * drv,int linkmode,int operstate)45 static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
46 int linkmode, int operstate)
47 {
48 struct {
49 struct nlmsghdr hdr;
50 struct ifinfomsg ifinfo;
51 char opts[16];
52 } req;
53 struct rtattr *rta;
54 static int nl_seq;
55 ssize_t ret;
56
57 os_memset(&req, 0, sizeof(req));
58
59 req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
60 req.hdr.nlmsg_type = RTM_SETLINK;
61 req.hdr.nlmsg_flags = NLM_F_REQUEST;
62 req.hdr.nlmsg_seq = ++nl_seq;
63 req.hdr.nlmsg_pid = 0;
64
65 req.ifinfo.ifi_family = AF_UNSPEC;
66 req.ifinfo.ifi_type = 0;
67 req.ifinfo.ifi_index = drv->ifindex;
68 req.ifinfo.ifi_flags = 0;
69 req.ifinfo.ifi_change = 0;
70
71 if (linkmode != -1) {
72 rta = aliasing_hide_typecast(
73 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
74 struct rtattr);
75 rta->rta_type = IFLA_LINKMODE;
76 rta->rta_len = RTA_LENGTH(sizeof(char));
77 *((char *) RTA_DATA(rta)) = linkmode;
78 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
79 RTA_LENGTH(sizeof(char));
80 }
81 if (operstate != -1) {
82 rta = (struct rtattr *)
83 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
84 rta->rta_type = IFLA_OPERSTATE;
85 rta->rta_len = RTA_LENGTH(sizeof(char));
86 *((char *) RTA_DATA(rta)) = operstate;
87 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
88 RTA_LENGTH(sizeof(char));
89 }
90
91 wpa_printf(MSG_DEBUG, "WEXT: Operstate: linkmode=%d, operstate=%d",
92 linkmode, operstate);
93
94 ret = send(drv->event_sock, &req, req.hdr.nlmsg_len, 0);
95 if (ret < 0) {
96 wpa_printf(MSG_DEBUG, "WEXT: Sending operstate IFLA failed: "
97 "%s (assume operstate is not supported)",
98 strerror(errno));
99 }
100
101 return ret < 0 ? -1 : 0;
102 }
103
104
wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data * drv,int idx,u32 value)105 int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv,
106 int idx, u32 value)
107 {
108 struct iwreq iwr;
109 int ret = 0;
110
111 os_memset(&iwr, 0, sizeof(iwr));
112 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
113 iwr.u.param.flags = idx & IW_AUTH_INDEX;
114 iwr.u.param.value = value;
115
116 if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) {
117 if (errno != EOPNOTSUPP) {
118 wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d "
119 "value 0x%x) failed: %s)",
120 idx, value, strerror(errno));
121 }
122 ret = errno == EOPNOTSUPP ? -2 : -1;
123 }
124
125 return ret;
126 }
127
128
129 /**
130 * wpa_driver_wext_get_bssid - Get BSSID, SIOCGIWAP
131 * @priv: Pointer to private wext data from wpa_driver_wext_init()
132 * @bssid: Buffer for BSSID
133 * Returns: 0 on success, -1 on failure
134 */
wpa_driver_wext_get_bssid(void * priv,u8 * bssid)135 int wpa_driver_wext_get_bssid(void *priv, u8 *bssid)
136 {
137 struct wpa_driver_wext_data *drv = priv;
138 struct iwreq iwr;
139 int ret = 0;
140
141 os_memset(&iwr, 0, sizeof(iwr));
142 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
143
144 if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) {
145 wpa_printf(MSG_ERROR, "ioctl[SIOCGIWAP]");
146 ret = -1;
147 }
148 os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN);
149
150 return ret;
151 }
152
153
154 /**
155 * wpa_driver_wext_set_bssid - Set BSSID, SIOCSIWAP
156 * @priv: Pointer to private wext data from wpa_driver_wext_init()
157 * @bssid: BSSID
158 * Returns: 0 on success, -1 on failure
159 */
wpa_driver_wext_set_bssid(void * priv,const u8 * bssid)160 int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid)
161 {
162 struct wpa_driver_wext_data *drv = priv;
163 struct iwreq iwr;
164 int ret = 0;
165
166 os_memset(&iwr, 0, sizeof(iwr));
167 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
168 iwr.u.ap_addr.sa_family = ARPHRD_ETHER;
169 if (bssid)
170 os_memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN);
171 else
172 os_memset(iwr.u.ap_addr.sa_data, 0, ETH_ALEN);
173
174 if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr) < 0) {
175 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWAP]");
176 ret = -1;
177 }
178
179 return ret;
180 }
181
182
183 /**
184 * wpa_driver_wext_get_ssid - Get SSID, SIOCGIWESSID
185 * @priv: Pointer to private wext data from wpa_driver_wext_init()
186 * @ssid: Buffer for the SSID; must be at least 32 bytes long
187 * Returns: SSID length on success, -1 on failure
188 */
wpa_driver_wext_get_ssid(void * priv,u8 * ssid)189 int wpa_driver_wext_get_ssid(void *priv, u8 *ssid)
190 {
191 struct wpa_driver_wext_data *drv = priv;
192 struct iwreq iwr;
193 int ret = 0;
194
195 os_memset(&iwr, 0, sizeof(iwr));
196 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
197 iwr.u.essid.pointer = (caddr_t) ssid;
198 iwr.u.essid.length = 32;
199
200 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
201 wpa_printf(MSG_ERROR, "ioctl[SIOCGIWESSID]");
202 ret = -1;
203 } else {
204 ret = iwr.u.essid.length;
205 if (ret > 32)
206 ret = 32;
207 /* Some drivers include nul termination in the SSID, so let's
208 * remove it here before further processing. WE-21 changes this
209 * to explicitly require the length _not_ to include nul
210 * termination. */
211 if (ret > 0 && ssid[ret - 1] == '\0' &&
212 drv->we_version_compiled < 21)
213 ret--;
214 }
215
216 return ret;
217 }
218
219
220 /**
221 * wpa_driver_wext_set_ssid - Set SSID, SIOCSIWESSID
222 * @priv: Pointer to private wext data from wpa_driver_wext_init()
223 * @ssid: SSID
224 * @ssid_len: Length of SSID (0..32)
225 * Returns: 0 on success, -1 on failure
226 */
wpa_driver_wext_set_ssid(void * priv,const u8 * ssid,size_t ssid_len)227 int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len)
228 {
229 struct wpa_driver_wext_data *drv = priv;
230 struct iwreq iwr;
231 int ret = 0;
232 char buf[33];
233
234 if (ssid_len > 32)
235 return -1;
236
237 os_memset(&iwr, 0, sizeof(iwr));
238 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
239 /* flags: 1 = ESSID is active, 0 = not (promiscuous) */
240 iwr.u.essid.flags = (ssid_len != 0);
241 os_memset(buf, 0, sizeof(buf));
242 os_memcpy(buf, ssid, ssid_len);
243 iwr.u.essid.pointer = (caddr_t) buf;
244 if (drv->we_version_compiled < 21) {
245 /* For historic reasons, set SSID length to include one extra
246 * character, C string nul termination, even though SSID is
247 * really an octet string that should not be presented as a C
248 * string. Some Linux drivers decrement the length by one and
249 * can thus end up missing the last octet of the SSID if the
250 * length is not incremented here. WE-21 changes this to
251 * explicitly require the length _not_ to include nul
252 * termination. */
253 if (ssid_len)
254 ssid_len++;
255 }
256 iwr.u.essid.length = ssid_len;
257
258 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
259 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWESSID]");
260 ret = -1;
261 }
262
263 return ret;
264 }
265
266
267 /**
268 * wpa_driver_wext_set_freq - Set frequency/channel, SIOCSIWFREQ
269 * @priv: Pointer to private wext data from wpa_driver_wext_init()
270 * @freq: Frequency in MHz
271 * Returns: 0 on success, -1 on failure
272 */
wpa_driver_wext_set_freq(void * priv,int freq)273 int wpa_driver_wext_set_freq(void *priv, int freq)
274 {
275 struct wpa_driver_wext_data *drv = priv;
276 struct iwreq iwr;
277 int ret = 0;
278
279 os_memset(&iwr, 0, sizeof(iwr));
280 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
281 iwr.u.freq.m = freq * 100000;
282 iwr.u.freq.e = 1;
283
284 if (ioctl(drv->ioctl_sock, SIOCSIWFREQ, &iwr) < 0) {
285 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWFREQ]");
286 ret = -1;
287 }
288
289 return ret;
290 }
291
292
293 static void
wpa_driver_wext_event_wireless_custom(void * ctx,char * custom)294 wpa_driver_wext_event_wireless_custom(void *ctx, char *custom)
295 {
296 union wpa_event_data data;
297
298 wpa_printf(MSG_MSGDUMP, "WEXT: Custom wireless event: '%s'",
299 custom);
300
301 os_memset(&data, 0, sizeof(data));
302 /* Host AP driver */
303 if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
304 data.michael_mic_failure.unicast =
305 os_strstr(custom, " unicast ") != NULL;
306 /* TODO: parse parameters(?) */
307 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
308 } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) {
309 char *spos;
310 int bytes;
311
312 spos = custom + 17;
313
314 bytes = strspn(spos, "0123456789abcdefABCDEF");
315 if (!bytes || (bytes & 1))
316 return;
317 bytes /= 2;
318
319 data.assoc_info.req_ies = os_malloc(bytes);
320 if (data.assoc_info.req_ies == NULL)
321 return;
322
323 data.assoc_info.req_ies_len = bytes;
324 hexstr2bin(spos, data.assoc_info.req_ies, bytes);
325
326 spos += bytes * 2;
327
328 data.assoc_info.resp_ies = NULL;
329 data.assoc_info.resp_ies_len = 0;
330
331 if (os_strncmp(spos, " RespIEs=", 9) == 0) {
332 spos += 9;
333
334 bytes = strspn(spos, "0123456789abcdefABCDEF");
335 if (!bytes || (bytes & 1))
336 goto done;
337 bytes /= 2;
338
339 data.assoc_info.resp_ies = os_malloc(bytes);
340 if (data.assoc_info.resp_ies == NULL)
341 goto done;
342
343 data.assoc_info.resp_ies_len = bytes;
344 hexstr2bin(spos, data.assoc_info.resp_ies, bytes);
345 }
346
347 wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data);
348
349 done:
350 os_free(data.assoc_info.resp_ies);
351 os_free(data.assoc_info.req_ies);
352 #ifdef CONFIG_PEERKEY
353 } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) {
354 if (hwaddr_aton(custom + 17, data.stkstart.peer)) {
355 wpa_printf(MSG_DEBUG, "WEXT: unrecognized "
356 "STKSTART.request '%s'", custom + 17);
357 return;
358 }
359 wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
360 #endif /* CONFIG_PEERKEY */
361 #ifdef ANDROID
362 } else if (os_strncmp(custom, "STOP", 4) == 0) {
363 wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
364 } else if (os_strncmp(custom, "START", 5) == 0) {
365 wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
366 } else if (os_strncmp(custom, "HANG", 4) == 0) {
367 wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
368 #endif /* ANDROID */
369 }
370 }
371
372
wpa_driver_wext_event_wireless_michaelmicfailure(void * ctx,const char * ev,size_t len)373 static int wpa_driver_wext_event_wireless_michaelmicfailure(
374 void *ctx, const char *ev, size_t len)
375 {
376 const struct iw_michaelmicfailure *mic;
377 union wpa_event_data data;
378
379 if (len < sizeof(*mic))
380 return -1;
381
382 mic = (const struct iw_michaelmicfailure *) ev;
383
384 wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: "
385 "flags=0x%x src_addr=" MACSTR, mic->flags,
386 MAC2STR(mic->src_addr.sa_data));
387
388 os_memset(&data, 0, sizeof(data));
389 data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP);
390 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
391
392 return 0;
393 }
394
395
wpa_driver_wext_event_wireless_pmkidcand(struct wpa_driver_wext_data * drv,const char * ev,size_t len)396 static int wpa_driver_wext_event_wireless_pmkidcand(
397 struct wpa_driver_wext_data *drv, const char *ev, size_t len)
398 {
399 const struct iw_pmkid_cand *cand;
400 union wpa_event_data data;
401 const u8 *addr;
402
403 if (len < sizeof(*cand))
404 return -1;
405
406 cand = (const struct iw_pmkid_cand *) ev;
407 addr = (const u8 *) cand->bssid.sa_data;
408
409 wpa_printf(MSG_DEBUG, "PMKID candidate wireless event: "
410 "flags=0x%x index=%d bssid=" MACSTR, cand->flags,
411 cand->index, MAC2STR(addr));
412
413 os_memset(&data, 0, sizeof(data));
414 os_memcpy(data.pmkid_candidate.bssid, addr, ETH_ALEN);
415 data.pmkid_candidate.index = cand->index;
416 data.pmkid_candidate.preauth = cand->flags & IW_PMKID_CAND_PREAUTH;
417 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
418
419 return 0;
420 }
421
422
wpa_driver_wext_event_wireless_assocreqie(struct wpa_driver_wext_data * drv,const char * ev,int len)423 static int wpa_driver_wext_event_wireless_assocreqie(
424 struct wpa_driver_wext_data *drv, const char *ev, int len)
425 {
426 if (len < 0)
427 return -1;
428
429 wpa_hexdump(MSG_DEBUG, "AssocReq IE wireless event", (const u8 *) ev,
430 len);
431 os_free(drv->assoc_req_ies);
432 drv->assoc_req_ies = os_malloc(len);
433 if (drv->assoc_req_ies == NULL) {
434 drv->assoc_req_ies_len = 0;
435 return -1;
436 }
437 os_memcpy(drv->assoc_req_ies, ev, len);
438 drv->assoc_req_ies_len = len;
439
440 return 0;
441 }
442
443
wpa_driver_wext_event_wireless_assocrespie(struct wpa_driver_wext_data * drv,const char * ev,int len)444 static int wpa_driver_wext_event_wireless_assocrespie(
445 struct wpa_driver_wext_data *drv, const char *ev, int len)
446 {
447 if (len < 0)
448 return -1;
449
450 wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev,
451 len);
452 os_free(drv->assoc_resp_ies);
453 drv->assoc_resp_ies = os_malloc(len);
454 if (drv->assoc_resp_ies == NULL) {
455 drv->assoc_resp_ies_len = 0;
456 return -1;
457 }
458 os_memcpy(drv->assoc_resp_ies, ev, len);
459 drv->assoc_resp_ies_len = len;
460
461 return 0;
462 }
463
464
wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data * drv)465 static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv)
466 {
467 union wpa_event_data data;
468
469 if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL)
470 return;
471
472 os_memset(&data, 0, sizeof(data));
473 if (drv->assoc_req_ies) {
474 data.assoc_info.req_ies = drv->assoc_req_ies;
475 drv->assoc_req_ies = NULL;
476 data.assoc_info.req_ies_len = drv->assoc_req_ies_len;
477 }
478 if (drv->assoc_resp_ies) {
479 data.assoc_info.resp_ies = drv->assoc_resp_ies;
480 drv->assoc_resp_ies = NULL;
481 data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len;
482 }
483
484 wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);
485
486 os_free(data.assoc_info.req_ies);
487 os_free(data.assoc_info.resp_ies);
488 }
489
490
wpa_driver_wext_event_wireless(struct wpa_driver_wext_data * drv,void * ctx,char * data,int len)491 static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
492 void *ctx, char *data, int len)
493 {
494 struct iw_event iwe_buf, *iwe = &iwe_buf;
495 char *pos, *end, *custom, *buf;
496
497 pos = data;
498 end = data + len;
499
500 while (pos + IW_EV_LCP_LEN <= end) {
501 /* Event data may be unaligned, so make a local, aligned copy
502 * before processing. */
503 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
504 wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d",
505 iwe->cmd, iwe->len);
506 if (iwe->len <= IW_EV_LCP_LEN)
507 return;
508
509 custom = pos + IW_EV_POINT_LEN;
510 if (drv->we_version_compiled > 18 &&
511 (iwe->cmd == IWEVMICHAELMICFAILURE ||
512 iwe->cmd == IWEVCUSTOM ||
513 iwe->cmd == IWEVASSOCREQIE ||
514 iwe->cmd == IWEVASSOCRESPIE ||
515 iwe->cmd == IWEVPMKIDCAND)) {
516 /* WE-19 removed the pointer from struct iw_point */
517 char *dpos = (char *) &iwe_buf.u.data.length;
518 int dlen = dpos - (char *) &iwe_buf;
519 os_memcpy(dpos, pos + IW_EV_LCP_LEN,
520 sizeof(struct iw_event) - dlen);
521 } else {
522 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
523 custom += IW_EV_POINT_OFF;
524 }
525
526 switch (iwe->cmd) {
527 case SIOCGIWAP:
528 wpa_printf(MSG_DEBUG, "Wireless event: new AP: "
529 MACSTR,
530 MAC2STR((u8 *) iwe->u.ap_addr.sa_data));
531 if (is_zero_ether_addr(
532 (const u8 *) iwe->u.ap_addr.sa_data) ||
533 os_memcmp(iwe->u.ap_addr.sa_data,
534 "\x44\x44\x44\x44\x44\x44", ETH_ALEN) ==
535 0) {
536 os_free(drv->assoc_req_ies);
537 drv->assoc_req_ies = NULL;
538 os_free(drv->assoc_resp_ies);
539 drv->assoc_resp_ies = NULL;
540 #ifdef ANDROID
541 if (!drv->skip_disconnect) {
542 drv->skip_disconnect = 1;
543 #endif
544 wpa_supplicant_event(ctx, EVENT_DISASSOC,
545 NULL);
546 #ifdef ANDROID
547 wpa_driver_wext_disconnect(drv);
548 }
549 #endif
550
551 } else {
552 #ifdef ANDROID
553 drv->skip_disconnect = 0;
554 #endif
555 wpa_driver_wext_event_assoc_ies(drv);
556 wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
557 }
558 break;
559 case IWEVMICHAELMICFAILURE:
560 if (custom + iwe->u.data.length > end) {
561 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
562 "IWEVMICHAELMICFAILURE length");
563 return;
564 }
565 wpa_driver_wext_event_wireless_michaelmicfailure(
566 ctx, custom, iwe->u.data.length);
567 break;
568 case IWEVCUSTOM:
569 if (custom + iwe->u.data.length > end) {
570 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
571 "IWEVCUSTOM length");
572 return;
573 }
574 buf = os_malloc(iwe->u.data.length + 1);
575 if (buf == NULL)
576 return;
577 os_memcpy(buf, custom, iwe->u.data.length);
578 buf[iwe->u.data.length] = '\0';
579 wpa_driver_wext_event_wireless_custom(ctx, buf);
580 os_free(buf);
581 break;
582 case SIOCGIWSCAN:
583 drv->scan_complete_events = 1;
584 eloop_cancel_timeout(wpa_driver_wext_scan_timeout,
585 drv, ctx);
586 wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
587 break;
588 case IWEVASSOCREQIE:
589 if (custom + iwe->u.data.length > end) {
590 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
591 "IWEVASSOCREQIE length");
592 return;
593 }
594 wpa_driver_wext_event_wireless_assocreqie(
595 drv, custom, iwe->u.data.length);
596 break;
597 case IWEVASSOCRESPIE:
598 if (custom + iwe->u.data.length > end) {
599 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
600 "IWEVASSOCRESPIE length");
601 return;
602 }
603 wpa_driver_wext_event_wireless_assocrespie(
604 drv, custom, iwe->u.data.length);
605 break;
606 case IWEVPMKIDCAND:
607 if (custom + iwe->u.data.length > end) {
608 wpa_printf(MSG_DEBUG, "WEXT: Invalid "
609 "IWEVPMKIDCAND length");
610 return;
611 }
612 wpa_driver_wext_event_wireless_pmkidcand(
613 drv, custom, iwe->u.data.length);
614 break;
615 }
616
617 pos += iwe->len;
618 }
619 }
620
621
wpa_driver_wext_event_link(struct wpa_driver_wext_data * drv,void * ctx,char * buf,size_t len,int del)622 static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv,
623 void *ctx, char *buf, size_t len,
624 int del)
625 {
626 union wpa_event_data event;
627
628 os_memset(&event, 0, sizeof(event));
629 if (len > sizeof(event.interface_status.ifname))
630 len = sizeof(event.interface_status.ifname) - 1;
631 os_memcpy(event.interface_status.ifname, buf, len);
632 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
633 EVENT_INTERFACE_ADDED;
634
635 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
636 del ? "DEL" : "NEW",
637 event.interface_status.ifname,
638 del ? "removed" : "added");
639
640 if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
641 if (del)
642 drv->if_removed = 1;
643 else
644 drv->if_removed = 0;
645 }
646
647 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
648 }
649
650
wpa_driver_wext_own_ifname(struct wpa_driver_wext_data * drv,struct nlmsghdr * h)651 static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv,
652 struct nlmsghdr *h)
653 {
654 struct ifinfomsg *ifi;
655 int attrlen, nlmsg_len, rta_len;
656 struct rtattr *attr;
657
658 ifi = NLMSG_DATA(h);
659
660 nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
661
662 attrlen = h->nlmsg_len - nlmsg_len;
663 if (attrlen < 0)
664 return 0;
665
666 attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
667
668 rta_len = RTA_ALIGN(sizeof(struct rtattr));
669 while (RTA_OK(attr, attrlen)) {
670 if (attr->rta_type == IFLA_IFNAME) {
671 if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
672 == 0)
673 return 1;
674 else
675 break;
676 }
677 attr = RTA_NEXT(attr, attrlen);
678 }
679
680 return 0;
681 }
682
683
wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data * drv,int ifindex,struct nlmsghdr * h)684 static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv,
685 int ifindex, struct nlmsghdr *h)
686 {
687 if (drv->ifindex == ifindex || drv->ifindex2 == ifindex)
688 return 1;
689
690 if (drv->if_removed && wpa_driver_wext_own_ifname(drv, h)) {
691 drv->ifindex = if_nametoindex(drv->ifname);
692 wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed "
693 "interface");
694 wpa_driver_wext_finish_drv_init(drv);
695 return 1;
696 }
697
698 return 0;
699 }
700
701
wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data * drv,void * ctx,struct nlmsghdr * h,size_t len)702 static void wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data *drv,
703 void *ctx, struct nlmsghdr *h,
704 size_t len)
705 {
706 struct ifinfomsg *ifi;
707 int attrlen, nlmsg_len, rta_len;
708 struct rtattr * attr;
709
710 if (len < sizeof(*ifi))
711 return;
712
713 ifi = NLMSG_DATA(h);
714
715 if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, h)) {
716 wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
717 ifi->ifi_index);
718 return;
719 }
720
721 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
722 "(%s%s%s%s)",
723 drv->operstate, ifi->ifi_flags,
724 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
725 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
726 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
727 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
728 /*
729 * Some drivers send the association event before the operup event--in
730 * this case, lifting operstate in wpa_driver_wext_set_operstate()
731 * fails. This will hit us when wpa_supplicant does not need to do
732 * IEEE 802.1X authentication
733 */
734 if (drv->operstate == 1 &&
735 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
736 !(ifi->ifi_flags & IFF_RUNNING))
737 wpa_driver_wext_send_oper_ifla(drv, -1, IF_OPER_UP);
738
739 nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
740
741 attrlen = h->nlmsg_len - nlmsg_len;
742 if (attrlen < 0)
743 return;
744
745 attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
746
747 rta_len = RTA_ALIGN(sizeof(struct rtattr));
748 while (RTA_OK(attr, attrlen)) {
749 if (attr->rta_type == IFLA_WIRELESS) {
750 wpa_driver_wext_event_wireless(
751 drv, ctx, ((char *) attr) + rta_len,
752 attr->rta_len - rta_len);
753 } else if (attr->rta_type == IFLA_IFNAME) {
754 wpa_driver_wext_event_link(drv, ctx,
755 ((char *) attr) + rta_len,
756 attr->rta_len - rta_len, 0);
757 }
758 attr = RTA_NEXT(attr, attrlen);
759 }
760 }
761
762
wpa_driver_wext_event_rtm_dellink(struct wpa_driver_wext_data * drv,void * ctx,struct nlmsghdr * h,size_t len)763 static void wpa_driver_wext_event_rtm_dellink(struct wpa_driver_wext_data *drv,
764 void *ctx, struct nlmsghdr *h,
765 size_t len)
766 {
767 struct ifinfomsg *ifi;
768 int attrlen, nlmsg_len, rta_len;
769 struct rtattr * attr;
770
771 if (len < sizeof(*ifi))
772 return;
773
774 ifi = NLMSG_DATA(h);
775
776 nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
777
778 attrlen = h->nlmsg_len - nlmsg_len;
779 if (attrlen < 0)
780 return;
781
782 attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
783
784 rta_len = RTA_ALIGN(sizeof(struct rtattr));
785 while (RTA_OK(attr, attrlen)) {
786 if (attr->rta_type == IFLA_IFNAME) {
787 wpa_driver_wext_event_link(drv, ctx,
788 ((char *) attr) + rta_len,
789 attr->rta_len - rta_len, 1);
790 }
791 attr = RTA_NEXT(attr, attrlen);
792 }
793 }
794
795
wpa_driver_wext_event_receive(int sock,void * eloop_ctx,void * sock_ctx)796 static void wpa_driver_wext_event_receive(int sock, void *eloop_ctx,
797 void *sock_ctx)
798 {
799 char buf[8192];
800 int left;
801 struct sockaddr_nl from;
802 socklen_t fromlen;
803 struct nlmsghdr *h;
804 int max_events = 10;
805
806 try_again:
807 fromlen = sizeof(from);
808 left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
809 (struct sockaddr *) &from, &fromlen);
810 if (left < 0) {
811 if (errno != EINTR && errno != EAGAIN)
812 wpa_printf(MSG_ERROR, "%s: recvfrom(netlink): %d", __func__, errno);
813 return;
814 }
815
816 h = (struct nlmsghdr *) buf;
817 while (left >= (int) sizeof(*h)) {
818 int len, plen;
819
820 len = h->nlmsg_len;
821 plen = len - sizeof(*h);
822 if (len > left || plen < 0) {
823 wpa_printf(MSG_DEBUG, "Malformed netlink message: "
824 "len=%d left=%d plen=%d",
825 len, left, plen);
826 break;
827 }
828
829 switch (h->nlmsg_type) {
830 case RTM_NEWLINK:
831 wpa_driver_wext_event_rtm_newlink(eloop_ctx, sock_ctx,
832 h, plen);
833 break;
834 case RTM_DELLINK:
835 wpa_driver_wext_event_rtm_dellink(eloop_ctx, sock_ctx,
836 h, plen);
837 break;
838 }
839
840 len = NLMSG_ALIGN(len);
841 left -= len;
842 h = (struct nlmsghdr *) ((char *) h + len);
843 }
844
845 if (left > 0) {
846 wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "
847 "message", left);
848 }
849
850 if (--max_events > 0) {
851 /*
852 * Try to receive all events in one eloop call in order to
853 * limit race condition on cases where AssocInfo event, Assoc
854 * event, and EAPOL frames are received more or less at the
855 * same time. We want to process the event messages first
856 * before starting EAPOL processing.
857 */
858 goto try_again;
859 }
860 }
861
862
wpa_driver_wext_get_ifflags_ifname(struct wpa_driver_wext_data * drv,const char * ifname,int * flags)863 static int wpa_driver_wext_get_ifflags_ifname(struct wpa_driver_wext_data *drv,
864 const char *ifname, int *flags)
865 {
866 struct ifreq ifr;
867
868 os_memset(&ifr, 0, sizeof(ifr));
869 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
870 if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
871 wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]");
872 return -1;
873 }
874 *flags = ifr.ifr_flags & 0xffff;
875 return 0;
876 }
877
878
879 /**
880 * wpa_driver_wext_get_ifflags - Get interface flags (SIOCGIFFLAGS)
881 * @drv: driver_wext private data
882 * @flags: Pointer to returned flags value
883 * Returns: 0 on success, -1 on failure
884 */
wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data * drv,int * flags)885 int wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data *drv, int *flags)
886 {
887 return wpa_driver_wext_get_ifflags_ifname(drv, drv->ifname, flags);
888 }
889
890
wpa_driver_wext_set_ifflags_ifname(struct wpa_driver_wext_data * drv,const char * ifname,int flags)891 static int wpa_driver_wext_set_ifflags_ifname(struct wpa_driver_wext_data *drv,
892 const char *ifname, int flags)
893 {
894 struct ifreq ifr;
895
896 os_memset(&ifr, 0, sizeof(ifr));
897 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
898 ifr.ifr_flags = flags & 0xffff;
899 if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
900 wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]");
901 return -1;
902 }
903 return 0;
904 }
905
906
907 /**
908 * wpa_driver_wext_set_ifflags - Set interface flags (SIOCSIFFLAGS)
909 * @drv: driver_wext private data
910 * @flags: New value for flags
911 * Returns: 0 on success, -1 on failure
912 */
wpa_driver_wext_set_ifflags(struct wpa_driver_wext_data * drv,int flags)913 int wpa_driver_wext_set_ifflags(struct wpa_driver_wext_data *drv, int flags)
914 {
915 return wpa_driver_wext_set_ifflags_ifname(drv, drv->ifname, flags);
916 }
917
918
919 /**
920 * wpa_driver_wext_init - Initialize WE driver interface
921 * @ctx: context to be used when calling wpa_supplicant functions,
922 * e.g., wpa_supplicant_event()
923 * @ifname: interface name, e.g., wlan0
924 * Returns: Pointer to private data, %NULL on failure
925 */
wpa_driver_wext_init(void * ctx,const char * ifname)926 void * wpa_driver_wext_init(void *ctx, const char *ifname)
927 {
928 int s;
929 struct sockaddr_nl local;
930 struct wpa_driver_wext_data *drv;
931
932 drv = os_zalloc(sizeof(*drv));
933 if (drv == NULL)
934 return NULL;
935 drv->ctx = ctx;
936 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
937
938 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
939 if (drv->ioctl_sock < 0) {
940 wpa_printf(MSG_ERROR, "%s: socket(PF_INET,SOCK_DGRAM)", __func__);
941 os_free(drv);
942 return NULL;
943 }
944
945 s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
946 if (s < 0) {
947 wpa_printf(MSG_ERROR, "%s: socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)", __func__);
948 close(drv->ioctl_sock);
949 os_free(drv);
950 return NULL;
951 }
952
953 os_memset(&local, 0, sizeof(local));
954 local.nl_family = AF_NETLINK;
955 local.nl_groups = RTMGRP_LINK;
956 if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
957 wpa_printf(MSG_ERROR, "bind(netlink)");
958 close(s);
959 close(drv->ioctl_sock);
960 os_free(drv);
961 return NULL;
962 }
963
964 eloop_register_read_sock(s, wpa_driver_wext_event_receive, drv, ctx);
965 drv->event_sock = s;
966
967 drv->mlme_sock = -1;
968 #ifdef ANDROID
969 drv->errors = 0;
970 drv->driver_is_started = TRUE;
971 drv->skip_disconnect = 0;
972 drv->bgscan_enabled = 0;
973 #endif
974 wpa_driver_wext_finish_drv_init(drv);
975
976 return drv;
977 }
978
979
wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data * drv)980 static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
981 {
982 int flags;
983
984 if (wpa_driver_wext_get_ifflags(drv, &flags) != 0)
985 printf("Could not get interface '%s' flags\n", drv->ifname);
986 else if (!(flags & IFF_UP)) {
987 if (wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
988 printf("Could not set interface '%s' UP\n",
989 drv->ifname);
990 } else {
991 /*
992 * Wait some time to allow driver to initialize before
993 * starting configuring the driver. This seems to be
994 * needed at least some drivers that load firmware etc.
995 * when the interface is set up.
996 */
997 wpa_printf(MSG_DEBUG, "Interface %s set UP - waiting "
998 "a second for the driver to complete "
999 "initialization", drv->ifname);
1000 sleep(1);
1001 }
1002 }
1003
1004 /*
1005 * Make sure that the driver does not have any obsolete PMKID entries.
1006 */
1007 wpa_driver_wext_flush_pmkid(drv);
1008
1009 if (wpa_driver_wext_set_mode(drv, 0) < 0) {
1010 printf("Could not configure driver to use managed mode\n");
1011 }
1012
1013 wpa_driver_wext_get_range(drv);
1014
1015 /*
1016 * Unlock the driver's BSSID and force to a random SSID to clear any
1017 * previous association the driver might have when the supplicant
1018 * starts up.
1019 */
1020 wpa_driver_wext_disconnect(drv);
1021
1022 drv->ifindex = if_nametoindex(drv->ifname);
1023
1024 if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
1025 /*
1026 * Host AP driver may use both wlan# and wifi# interface in
1027 * wireless events. Since some of the versions included WE-18
1028 * support, let's add the alternative ifindex also from
1029 * driver_wext.c for the time being. This may be removed at
1030 * some point once it is believed that old versions of the
1031 * driver are not in use anymore.
1032 */
1033 char ifname2[IFNAMSIZ + 1];
1034 os_strlcpy(ifname2, drv->ifname, sizeof(ifname2));
1035 os_memcpy(ifname2, "wifi", 4);
1036 wpa_driver_wext_alternative_ifindex(drv, ifname2);
1037 }
1038
1039 wpa_driver_wext_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
1040 }
1041
1042
1043 /**
1044 * wpa_driver_wext_deinit - Deinitialize WE driver interface
1045 * @priv: Pointer to private wext data from wpa_driver_wext_init()
1046 *
1047 * Shut down driver interface and processing of driver events. Free
1048 * private data buffer if one was allocated in wpa_driver_wext_init().
1049 */
wpa_driver_wext_deinit(void * priv)1050 void wpa_driver_wext_deinit(void *priv)
1051 {
1052 struct wpa_driver_wext_data *drv = priv;
1053 int flags;
1054
1055 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
1056
1057 /*
1058 * Clear possibly configured driver parameters in order to make it
1059 * easier to use the driver after wpa_supplicant has been terminated.
1060 */
1061 wpa_driver_wext_disconnect(drv);
1062
1063 wpa_driver_wext_send_oper_ifla(priv, 0, IF_OPER_UP);
1064
1065 eloop_unregister_read_sock(drv->event_sock);
1066 if (drv->mlme_sock >= 0)
1067 eloop_unregister_read_sock(drv->mlme_sock);
1068
1069 if (wpa_driver_wext_get_ifflags(drv, &flags) == 0)
1070 (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
1071
1072 close(drv->event_sock);
1073 close(drv->ioctl_sock);
1074 if (drv->mlme_sock >= 0)
1075 close(drv->mlme_sock);
1076 os_free(drv->assoc_req_ies);
1077 os_free(drv->assoc_resp_ies);
1078 os_free(drv);
1079 }
1080
1081 /**
1082 * wpa_driver_wext_scan_timeout - Scan timeout to report scan completion
1083 * @eloop_ctx: Unused
1084 * @timeout_ctx: ctx argument given to wpa_driver_wext_init()
1085 *
1086 * This function can be used as registered timeout when starting a scan to
1087 * generate a scan completed event if the driver does not report this.
1088 */
wpa_driver_wext_scan_timeout(void * eloop_ctx,void * timeout_ctx)1089 void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1090 {
1091 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
1092 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
1093 }
1094
1095 /**
1096 * wpa_driver_wext_set_scan_timeout - Set scan timeout to report scan completion
1097 * @priv: Pointer to private wext data from wpa_driver_wext_init()
1098 *
1099 * This function can be used to set registered timeout when starting a scan to
1100 * generate a scan completed event if the driver does not report this.
1101 */
wpa_driver_wext_set_scan_timeout(void * priv)1102 static void wpa_driver_wext_set_scan_timeout(void *priv)
1103 {
1104 struct wpa_driver_wext_data *drv = priv;
1105 int timeout = 10; /* In case scan A and B bands it can be long */
1106
1107 /* Not all drivers generate "scan completed" wireless event, so try to
1108 * read results after a timeout. */
1109 if (drv->scan_complete_events) {
1110 /*
1111 * The driver seems to deliver SIOCGIWSCAN events to notify
1112 * when scan is complete, so use longer timeout to avoid race
1113 * conditions with scanning and following association request.
1114 */
1115 timeout = 30;
1116 }
1117 wpa_printf(MSG_DEBUG, "Scan requested - scan timeout %d seconds",
1118 timeout);
1119 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
1120 eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
1121 drv->ctx);
1122 }
1123
1124 /**
1125 * wpa_driver_wext_scan - Request the driver to initiate scan
1126 * @priv: Pointer to private wext data from wpa_driver_wext_init()
1127 * @ssid: Specific SSID to scan for (ProbeReq) or %NULL to scan for
1128 * all SSIDs (either active scan with broadcast SSID or passive
1129 * scan
1130 * @ssid_len: Length of the SSID
1131 * Returns: 0 on success, -1 on failure
1132 */
wpa_driver_wext_scan(void * priv,const u8 * ssid,size_t ssid_len)1133 int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len)
1134 {
1135 struct wpa_driver_wext_data *drv = priv;
1136 struct iwreq iwr;
1137 int ret = 0;
1138 struct iw_scan_req req;
1139 #ifdef ANDROID
1140 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
1141 int scan_probe_flag = 0;
1142 #endif
1143
1144 wpa_printf(MSG_ERROR, "%s: Start", __func__);
1145
1146 if (ssid_len > IW_ESSID_MAX_SIZE) {
1147 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
1148 __FUNCTION__, (unsigned long) ssid_len);
1149 return -1;
1150 }
1151
1152 os_memset(&iwr, 0, sizeof(iwr));
1153 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1154
1155 #ifdef ANDROID
1156 if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) {
1157 scan_probe_flag = wpa_s->prev_scan_ssid->scan_ssid;
1158 }
1159 wpa_printf(MSG_DEBUG, "%s: specific scan = %d", __func__,
1160 (scan_probe_flag && (ssid && ssid_len)) ? 1 : 0);
1161 if (scan_probe_flag && (ssid && ssid_len)) {
1162 #else
1163 if (ssid && ssid_len) {
1164 #endif
1165 os_memset(&req, 0, sizeof(req));
1166 req.essid_len = ssid_len;
1167 req.bssid.sa_family = ARPHRD_ETHER;
1168 os_memset(req.bssid.sa_data, 0xff, ETH_ALEN);
1169 os_memcpy(req.essid, ssid, ssid_len);
1170 iwr.u.data.pointer = (caddr_t) &req;
1171 iwr.u.data.length = sizeof(req);
1172 iwr.u.data.flags = IW_SCAN_THIS_ESSID;
1173 }
1174
1175 if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
1176 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWSCAN]");
1177 ret = -1;
1178 }
1179
1180 wpa_driver_wext_set_scan_timeout(priv);
1181
1182 return ret;
1183 }
1184
1185 /**
1186 * wpa_driver_wext_combo_scan - Request the driver to initiate combo scan
1187 * @priv: Pointer to private wext data from wpa_driver_wext_init()
1188 * @ssid_ptr: Pointer to current SSID from configuration list or %NULL to
1189 * scan for all SSIDs (either active scan with broadcast SSID or passive
1190 * scan)
1191 * @ssid_conf: SSID list from the configuration
1192 * Returns: 0 on success, -1 on failure
1193 * Also updates @ssid_ptr to next specific scan item
1194 */
1195 int wpa_driver_wext_combo_scan(void *priv, struct wpa_ssid **ssid_ptr,
1196 struct wpa_ssid *ssid_conf)
1197 {
1198 char buf[WEXT_CSCAN_BUF_LEN];
1199 struct wpa_driver_wext_data *drv = priv;
1200 struct iwreq iwr;
1201 int ret = 0, timeout, i = 0, bp;
1202 struct wpa_ssid *ssid, *ssid_orig;
1203 u8 *ssid_nm = NULL;
1204 size_t ssid_len = 0;
1205
1206 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
1207 int scan_probe_flag = 0;
1208
1209 if (!drv->driver_is_started) {
1210 wpa_printf(MSG_DEBUG, "%s: Driver stopped", __func__);
1211 return 0;
1212 }
1213
1214 wpa_printf(MSG_DEBUG, "%s: Start", __func__);
1215
1216 /* Set list of SSIDs */
1217 ssid_orig = (*ssid_ptr);
1218 ssid = (*ssid_ptr) ? (*ssid_ptr) : ssid_conf;
1219 bp = WEXT_CSCAN_HEADER_SIZE;
1220 os_memcpy(buf, WEXT_CSCAN_HEADER, bp);
1221 while (i < WEXT_CSCAN_AMOUNT) {
1222 if ((bp + IW_ESSID_MAX_SIZE + 10) >= (int)sizeof(buf))
1223 break;
1224 *ssid_ptr = ssid;
1225 if (ssid == NULL)
1226 break;
1227 if (!ssid->disabled && ssid->scan_ssid) {
1228 wpa_printf(MSG_DEBUG, "For Scan: %s", ssid->ssid);
1229 buf[bp++] = WEXT_CSCAN_SSID_SECTION;
1230 buf[bp++] = ssid->ssid_len;
1231 os_memcpy(&buf[bp], ssid->ssid, ssid->ssid_len);
1232 bp += ssid->ssid_len;
1233 i++;
1234 }
1235 ssid = ssid->next;
1236 }
1237
1238 /* Set list of channels */
1239 buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
1240 buf[bp++] = 0;
1241
1242 /* Set passive dwell time (default is 250) */
1243 buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION;
1244 buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME;
1245 buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME >> 8);
1246
1247 /* Set home dwell time (default is 40) */
1248 buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION;
1249 buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME;
1250 buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8);
1251
1252 os_memset(&iwr, 0, sizeof(iwr));
1253 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1254 iwr.u.data.pointer = buf;
1255 iwr.u.data.length = bp;
1256
1257 if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) {
1258 if (!drv->bgscan_enabled)
1259 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (cscan): %d", ret);
1260 else
1261 ret = 0; /* Hide error in case of bg scan */
1262 *ssid_ptr = ssid_orig;
1263 /* goto old_scan; */
1264 }
1265
1266 wpa_driver_wext_set_scan_timeout(priv);
1267
1268 return ret;
1269
1270 old_scan:
1271 if (*ssid_ptr) {
1272 ssid_nm = (*ssid_ptr)->ssid;
1273 ssid_len = (*ssid_ptr)->ssid_len;
1274 }
1275
1276 return wpa_driver_wext_scan(priv, ssid_nm, ssid_len);
1277 }
1278
1279
1280 static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv,
1281 size_t *len)
1282 {
1283 struct iwreq iwr;
1284 u8 *res_buf;
1285 size_t res_buf_len;
1286
1287 res_buf_len = IW_SCAN_MAX_DATA;
1288 for (;;) {
1289 res_buf = os_malloc(res_buf_len);
1290 if (res_buf == NULL)
1291 return NULL;
1292 os_memset(&iwr, 0, sizeof(iwr));
1293 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1294 iwr.u.data.pointer = res_buf;
1295 iwr.u.data.length = res_buf_len;
1296
1297 if (ioctl(drv->ioctl_sock, SIOCGIWSCAN, &iwr) == 0)
1298 break;
1299
1300 if (errno == E2BIG && res_buf_len < 65535) {
1301 os_free(res_buf);
1302 res_buf = NULL;
1303 res_buf_len *= 2;
1304 if (res_buf_len > 65535)
1305 res_buf_len = 65535; /* 16-bit length field */
1306 wpa_printf(MSG_DEBUG, "Scan results did not fit - "
1307 "trying larger buffer (%lu bytes)",
1308 (unsigned long) res_buf_len);
1309 } else {
1310 wpa_printf(MSG_ERROR, "ioctl[SIOCGIWSCAN]: %d", errno);
1311 os_free(res_buf);
1312 return NULL;
1313 }
1314 }
1315
1316 if (iwr.u.data.length > res_buf_len) {
1317 os_free(res_buf);
1318 return NULL;
1319 }
1320 *len = iwr.u.data.length;
1321
1322 return res_buf;
1323 }
1324
1325
1326 /*
1327 * Data structure for collecting WEXT scan results. This is needed to allow
1328 * the various methods of reporting IEs to be combined into a single IE buffer.
1329 */
1330 struct wext_scan_data {
1331 struct wpa_scan_res res;
1332 u8 *ie;
1333 size_t ie_len;
1334 u8 ssid[32];
1335 size_t ssid_len;
1336 int maxrate;
1337 };
1338
1339
1340 static void wext_get_scan_mode(struct iw_event *iwe,
1341 struct wext_scan_data *res)
1342 {
1343 if (iwe->u.mode == IW_MODE_ADHOC)
1344 res->res.caps |= IEEE80211_CAP_IBSS;
1345 else if (iwe->u.mode == IW_MODE_MASTER || iwe->u.mode == IW_MODE_INFRA)
1346 res->res.caps |= IEEE80211_CAP_ESS;
1347 }
1348
1349
1350 static void wext_get_scan_ssid(struct iw_event *iwe,
1351 struct wext_scan_data *res, char *custom,
1352 char *end)
1353 {
1354 int ssid_len = iwe->u.essid.length;
1355 if (custom + ssid_len > end)
1356 return;
1357 if (iwe->u.essid.flags &&
1358 ssid_len > 0 &&
1359 ssid_len <= IW_ESSID_MAX_SIZE) {
1360 os_memcpy(res->ssid, custom, ssid_len);
1361 res->ssid_len = ssid_len;
1362 }
1363 }
1364
1365
1366 static void wext_get_scan_freq(struct iw_event *iwe,
1367 struct wext_scan_data *res)
1368 {
1369 int divi = 1000000, i;
1370
1371 if (iwe->u.freq.e == 0) {
1372 /*
1373 * Some drivers do not report frequency, but a channel.
1374 * Try to map this to frequency by assuming they are using
1375 * IEEE 802.11b/g. But don't overwrite a previously parsed
1376 * frequency if the driver sends both frequency and channel,
1377 * since the driver may be sending an A-band channel that we
1378 * don't handle here.
1379 */
1380
1381 if (res->res.freq)
1382 return;
1383
1384 if (iwe->u.freq.m >= 1 && iwe->u.freq.m <= 13) {
1385 res->res.freq = 2407 + 5 * iwe->u.freq.m;
1386 return;
1387 } else if (iwe->u.freq.m == 14) {
1388 res->res.freq = 2484;
1389 return;
1390 }
1391 }
1392
1393 if (iwe->u.freq.e > 6) {
1394 wpa_printf(MSG_DEBUG, "Invalid freq in scan results (BSSID="
1395 MACSTR " m=%d e=%d)",
1396 MAC2STR(res->res.bssid), iwe->u.freq.m,
1397 iwe->u.freq.e);
1398 return;
1399 }
1400
1401 for (i = 0; i < iwe->u.freq.e; i++)
1402 divi /= 10;
1403 res->res.freq = iwe->u.freq.m / divi;
1404 }
1405
1406
1407 static void wext_get_scan_qual(struct iw_event *iwe,
1408 struct wext_scan_data *res)
1409 {
1410 res->res.qual = iwe->u.qual.qual;
1411 res->res.noise = iwe->u.qual.noise;
1412 res->res.level = iwe->u.qual.level;
1413 }
1414
1415
1416 static void wext_get_scan_encode(struct iw_event *iwe,
1417 struct wext_scan_data *res)
1418 {
1419 if (!(iwe->u.data.flags & IW_ENCODE_DISABLED))
1420 res->res.caps |= IEEE80211_CAP_PRIVACY;
1421 }
1422
1423
1424 static void wext_get_scan_rate(struct iw_event *iwe,
1425 struct wext_scan_data *res, char *pos,
1426 char *end)
1427 {
1428 int maxrate;
1429 char *custom = pos + IW_EV_LCP_LEN;
1430 struct iw_param p;
1431 size_t clen;
1432
1433 clen = iwe->len;
1434 if (custom + clen > end)
1435 return;
1436 maxrate = 0;
1437 while (((ssize_t) clen) >= (ssize_t) sizeof(struct iw_param)) {
1438 /* Note: may be misaligned, make a local, aligned copy */
1439 os_memcpy(&p, custom, sizeof(struct iw_param));
1440 if (p.value > maxrate)
1441 maxrate = p.value;
1442 clen -= sizeof(struct iw_param);
1443 custom += sizeof(struct iw_param);
1444 }
1445
1446 /* Convert the maxrate from WE-style (b/s units) to
1447 * 802.11 rates (500000 b/s units).
1448 */
1449 res->maxrate = maxrate / 500000;
1450 }
1451
1452
1453 static void wext_get_scan_iwevgenie(struct iw_event *iwe,
1454 struct wext_scan_data *res, char *custom,
1455 char *end)
1456 {
1457 char *genie, *gpos, *gend;
1458 u8 *tmp;
1459
1460 if (iwe->u.data.length == 0)
1461 return;
1462
1463 gpos = genie = custom;
1464 gend = genie + iwe->u.data.length;
1465 if (gend > end) {
1466 wpa_printf(MSG_INFO, "IWEVGENIE overflow");
1467 return;
1468 }
1469
1470 tmp = os_realloc(res->ie, res->ie_len + gend - gpos);
1471 if (tmp == NULL)
1472 return;
1473 os_memcpy(tmp + res->ie_len, gpos, gend - gpos);
1474 res->ie = tmp;
1475 res->ie_len += gend - gpos;
1476 }
1477
1478
1479 static void wext_get_scan_custom(struct iw_event *iwe,
1480 struct wext_scan_data *res, char *custom,
1481 char *end)
1482 {
1483 size_t clen;
1484 u8 *tmp;
1485
1486 clen = iwe->u.data.length;
1487 if (custom + clen > end)
1488 return;
1489
1490 if (clen > 7 && os_strncmp(custom, "wpa_ie=", 7) == 0) {
1491 char *spos;
1492 int bytes;
1493 spos = custom + 7;
1494 bytes = custom + clen - spos;
1495 if (bytes & 1 || bytes == 0)
1496 return;
1497 bytes /= 2;
1498 tmp = os_realloc(res->ie, res->ie_len + bytes);
1499 if (tmp == NULL)
1500 return;
1501 hexstr2bin(spos, tmp + res->ie_len, bytes);
1502 res->ie = tmp;
1503 res->ie_len += bytes;
1504 } else if (clen > 7 && os_strncmp(custom, "rsn_ie=", 7) == 0) {
1505 char *spos;
1506 int bytes;
1507 spos = custom + 7;
1508 bytes = custom + clen - spos;
1509 if (bytes & 1 || bytes == 0)
1510 return;
1511 bytes /= 2;
1512 tmp = os_realloc(res->ie, res->ie_len + bytes);
1513 if (tmp == NULL)
1514 return;
1515 hexstr2bin(spos, tmp + res->ie_len, bytes);
1516 res->ie = tmp;
1517 res->ie_len += bytes;
1518 } else if (clen > 4 && os_strncmp(custom, "tsf=", 4) == 0) {
1519 char *spos;
1520 int bytes;
1521 u8 bin[8];
1522 spos = custom + 4;
1523 bytes = custom + clen - spos;
1524 if (bytes != 16) {
1525 wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes);
1526 return;
1527 }
1528 bytes /= 2;
1529 hexstr2bin(spos, bin, bytes);
1530 res->res.tsf += WPA_GET_BE64(bin);
1531 }
1532 }
1533
1534
1535 static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd)
1536 {
1537 return drv->we_version_compiled > 18 &&
1538 (cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE ||
1539 cmd == IWEVGENIE || cmd == IWEVCUSTOM);
1540 }
1541
1542
1543 static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res,
1544 struct wext_scan_data *data)
1545 {
1546 struct wpa_scan_res **tmp;
1547 struct wpa_scan_res *r;
1548 size_t extra_len;
1549 u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL;
1550
1551 /* Figure out whether we need to fake any IEs */
1552 pos = data->ie;
1553 end = pos + data->ie_len;
1554 while (pos && pos + 1 < end) {
1555 if (pos + 2 + pos[1] > end)
1556 break;
1557 if (pos[0] == WLAN_EID_SSID)
1558 ssid_ie = pos;
1559 else if (pos[0] == WLAN_EID_SUPP_RATES)
1560 rate_ie = pos;
1561 else if (pos[0] == WLAN_EID_EXT_SUPP_RATES)
1562 rate_ie = pos;
1563 pos += 2 + pos[1];
1564 }
1565
1566 extra_len = 0;
1567 if (ssid_ie == NULL)
1568 extra_len += 2 + data->ssid_len;
1569 if (rate_ie == NULL && data->maxrate)
1570 extra_len += 3;
1571
1572 r = os_zalloc(sizeof(*r) + extra_len + data->ie_len);
1573 if (r == NULL)
1574 return;
1575 os_memcpy(r, &data->res, sizeof(*r));
1576 r->ie_len = extra_len + data->ie_len;
1577 pos = (u8 *) (r + 1);
1578 if (ssid_ie == NULL) {
1579 /*
1580 * Generate a fake SSID IE since the driver did not report
1581 * a full IE list.
1582 */
1583 *pos++ = WLAN_EID_SSID;
1584 *pos++ = data->ssid_len;
1585 os_memcpy(pos, data->ssid, data->ssid_len);
1586 pos += data->ssid_len;
1587 }
1588 if (rate_ie == NULL && data->maxrate) {
1589 /*
1590 * Generate a fake Supported Rates IE since the driver did not
1591 * report a full IE list.
1592 */
1593 *pos++ = WLAN_EID_SUPP_RATES;
1594 *pos++ = 1;
1595 *pos++ = data->maxrate;
1596 }
1597 if (data->ie)
1598 os_memcpy(pos, data->ie, data->ie_len);
1599
1600 tmp = os_realloc(res->res,
1601 (res->num + 1) * sizeof(struct wpa_scan_res *));
1602 if (tmp == NULL) {
1603 os_free(r);
1604 return;
1605 }
1606 tmp[res->num++] = r;
1607 res->res = tmp;
1608 }
1609
1610
1611 /**
1612 * wpa_driver_wext_get_scan_results - Fetch the latest scan results
1613 * @priv: Pointer to private wext data from wpa_driver_wext_init()
1614 * Returns: Scan results on success, -1 on failure
1615 */
1616 struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv)
1617 {
1618 struct wpa_driver_wext_data *drv = priv;
1619 size_t ap_num = 0, len;
1620 int first;
1621 u8 *res_buf;
1622 struct iw_event iwe_buf, *iwe = &iwe_buf;
1623 char *pos, *end, *custom;
1624 struct wpa_scan_results *res;
1625 struct wext_scan_data data;
1626
1627 #ifdef ANDROID
1628 /* To make sure correctly parse scan results which is impacted by wext
1629 * version, first check range->we_version, if it is default value (0),
1630 * update again here */
1631 if (drv->we_version_compiled == 0)
1632 wpa_driver_wext_get_range(drv);
1633 #endif
1634
1635 res_buf = wpa_driver_wext_giwscan(drv, &len);
1636 if (res_buf == NULL)
1637 return NULL;
1638
1639 ap_num = 0;
1640 first = 1;
1641
1642 res = os_zalloc(sizeof(*res));
1643 if (res == NULL) {
1644 os_free(res_buf);
1645 return NULL;
1646 }
1647
1648 pos = (char *) res_buf;
1649 end = (char *) res_buf + len;
1650 os_memset(&data, 0, sizeof(data));
1651
1652 while (pos + IW_EV_LCP_LEN <= end) {
1653 /* Event data may be unaligned, so make a local, aligned copy
1654 * before processing. */
1655 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
1656 if (iwe->len <= IW_EV_LCP_LEN)
1657 break;
1658
1659 custom = pos + IW_EV_POINT_LEN;
1660 if (wext_19_iw_point(drv, iwe->cmd)) {
1661 /* WE-19 removed the pointer from struct iw_point */
1662 char *dpos = (char *) &iwe_buf.u.data.length;
1663 int dlen = dpos - (char *) &iwe_buf;
1664 os_memcpy(dpos, pos + IW_EV_LCP_LEN,
1665 sizeof(struct iw_event) - dlen);
1666 } else {
1667 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
1668 custom += IW_EV_POINT_OFF;
1669 }
1670
1671 switch (iwe->cmd) {
1672 case SIOCGIWAP:
1673 if (!first)
1674 wpa_driver_wext_add_scan_entry(res, &data);
1675 first = 0;
1676 os_free(data.ie);
1677 os_memset(&data, 0, sizeof(data));
1678 os_memcpy(data.res.bssid,
1679 iwe->u.ap_addr.sa_data, ETH_ALEN);
1680 break;
1681 case SIOCGIWMODE:
1682 wext_get_scan_mode(iwe, &data);
1683 break;
1684 case SIOCGIWESSID:
1685 wext_get_scan_ssid(iwe, &data, custom, end);
1686 break;
1687 case SIOCGIWFREQ:
1688 wext_get_scan_freq(iwe, &data);
1689 break;
1690 case IWEVQUAL:
1691 wext_get_scan_qual(iwe, &data);
1692 break;
1693 case SIOCGIWENCODE:
1694 wext_get_scan_encode(iwe, &data);
1695 break;
1696 case SIOCGIWRATE:
1697 wext_get_scan_rate(iwe, &data, pos, end);
1698 break;
1699 case IWEVGENIE:
1700 wext_get_scan_iwevgenie(iwe, &data, custom, end);
1701 break;
1702 case IWEVCUSTOM:
1703 wext_get_scan_custom(iwe, &data, custom, end);
1704 break;
1705 }
1706
1707 pos += iwe->len;
1708 }
1709 os_free(res_buf);
1710 res_buf = NULL;
1711 if (!first)
1712 wpa_driver_wext_add_scan_entry(res, &data);
1713 os_free(data.ie);
1714
1715 wpa_printf(MSG_DEBUG, "Received %lu bytes of scan results (%lu BSSes)",
1716 (unsigned long) len, (unsigned long) res->num);
1717
1718 return res;
1719 }
1720
1721
1722 static int wpa_driver_wext_get_range(void *priv)
1723 {
1724 struct wpa_driver_wext_data *drv = priv;
1725 struct iw_range *range;
1726 struct iwreq iwr;
1727 int minlen;
1728 size_t buflen;
1729
1730 /*
1731 * Use larger buffer than struct iw_range in order to allow the
1732 * structure to grow in the future.
1733 */
1734 buflen = sizeof(struct iw_range) + 500;
1735 range = os_zalloc(buflen);
1736 if (range == NULL)
1737 return -1;
1738
1739 os_memset(&iwr, 0, sizeof(iwr));
1740 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1741 iwr.u.data.pointer = (caddr_t) range;
1742 iwr.u.data.length = buflen;
1743
1744 minlen = ((char *) &range->enc_capa) - (char *) range +
1745 sizeof(range->enc_capa);
1746
1747 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
1748 wpa_printf(MSG_ERROR, "ioctl[SIOCGIRANGE]");
1749 os_free(range);
1750 return -1;
1751 } else if (iwr.u.data.length >= minlen &&
1752 range->we_version_compiled >= 18) {
1753 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
1754 "WE(source)=%d enc_capa=0x%x",
1755 range->we_version_compiled,
1756 range->we_version_source,
1757 range->enc_capa);
1758 drv->has_capability = 1;
1759 drv->we_version_compiled = range->we_version_compiled;
1760 if (range->enc_capa & IW_ENC_CAPA_WPA) {
1761 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1762 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
1763 }
1764 if (range->enc_capa & IW_ENC_CAPA_WPA2) {
1765 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1766 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1767 }
1768 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
1769 WPA_DRIVER_CAPA_ENC_WEP104;
1770 if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
1771 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
1772 if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
1773 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
1774 if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
1775 drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
1776 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
1777 WPA_DRIVER_AUTH_SHARED |
1778 WPA_DRIVER_AUTH_LEAP;
1779
1780 wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x "
1781 "flags 0x%x",
1782 drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);
1783 } else {
1784 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - "
1785 "assuming WPA is not supported");
1786 }
1787
1788 os_free(range);
1789 return 0;
1790 }
1791
1792
1793 static int wpa_driver_wext_set_wpa(void *priv, int enabled)
1794 {
1795 struct wpa_driver_wext_data *drv = priv;
1796 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1797
1798 return wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED,
1799 enabled);
1800 }
1801
1802
1803 static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv,
1804 const u8 *psk)
1805 {
1806 struct iw_encode_ext *ext;
1807 struct iwreq iwr;
1808 int ret;
1809
1810 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1811
1812 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
1813 return 0;
1814
1815 if (!psk)
1816 return 0;
1817
1818 os_memset(&iwr, 0, sizeof(iwr));
1819 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1820
1821 ext = os_zalloc(sizeof(*ext) + PMK_LEN);
1822 if (ext == NULL)
1823 return -1;
1824
1825 iwr.u.encoding.pointer = (caddr_t) ext;
1826 iwr.u.encoding.length = sizeof(*ext) + PMK_LEN;
1827 ext->key_len = PMK_LEN;
1828 os_memcpy(&ext->key, psk, ext->key_len);
1829 ext->alg = IW_ENCODE_ALG_PMK;
1830
1831 ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr);
1832 if (ret < 0)
1833 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODEEXT] PMK");
1834 os_free(ext);
1835
1836 return ret;
1837 }
1838
1839
1840 static int wpa_driver_wext_set_key_ext(void *priv, wpa_alg alg,
1841 const u8 *addr, int key_idx,
1842 int set_tx, const u8 *seq,
1843 size_t seq_len,
1844 const u8 *key, size_t key_len)
1845 {
1846 struct wpa_driver_wext_data *drv = priv;
1847 struct iwreq iwr;
1848 int ret = 0;
1849 struct iw_encode_ext *ext;
1850
1851 if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) {
1852 wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu",
1853 __FUNCTION__, (unsigned long) seq_len);
1854 return -1;
1855 }
1856
1857 ext = os_zalloc(sizeof(*ext) + key_len);
1858 if (ext == NULL)
1859 return -1;
1860 os_memset(&iwr, 0, sizeof(iwr));
1861 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1862 iwr.u.encoding.flags = key_idx + 1;
1863 iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1864 if (alg == WPA_ALG_NONE)
1865 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1866 iwr.u.encoding.pointer = (caddr_t) ext;
1867 iwr.u.encoding.length = sizeof(*ext) + key_len;
1868
1869 if (addr == NULL ||
1870 os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
1871 ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY;
1872 if (set_tx)
1873 ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY;
1874
1875 ext->addr.sa_family = ARPHRD_ETHER;
1876 if (addr)
1877 os_memcpy(ext->addr.sa_data, addr, ETH_ALEN);
1878 else
1879 os_memset(ext->addr.sa_data, 0xff, ETH_ALEN);
1880 if (key && key_len) {
1881 os_memcpy(ext + 1, key, key_len);
1882 ext->key_len = key_len;
1883 }
1884 switch (alg) {
1885 case WPA_ALG_NONE:
1886 ext->alg = IW_ENCODE_ALG_NONE;
1887 break;
1888 case WPA_ALG_WEP:
1889 ext->alg = IW_ENCODE_ALG_WEP;
1890 break;
1891 case WPA_ALG_TKIP:
1892 ext->alg = IW_ENCODE_ALG_TKIP;
1893 break;
1894 case WPA_ALG_CCMP:
1895 ext->alg = IW_ENCODE_ALG_CCMP;
1896 break;
1897 case WPA_ALG_PMK:
1898 ext->alg = IW_ENCODE_ALG_PMK;
1899 break;
1900 #ifdef CONFIG_IEEE80211W
1901 case WPA_ALG_IGTK:
1902 ext->alg = IW_ENCODE_ALG_AES_CMAC;
1903 break;
1904 #endif /* CONFIG_IEEE80211W */
1905 default:
1906 wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
1907 __FUNCTION__, alg);
1908 os_free(ext);
1909 return -1;
1910 }
1911
1912 if (seq && seq_len) {
1913 ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID;
1914 os_memcpy(ext->rx_seq, seq, seq_len);
1915 }
1916
1917 if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) {
1918 ret = errno == EOPNOTSUPP ? -2 : -1;
1919 if (errno == ENODEV) {
1920 /*
1921 * ndiswrapper seems to be returning incorrect error
1922 * code.. */
1923 ret = -2;
1924 }
1925
1926 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODEEXT]");
1927 }
1928
1929 os_free(ext);
1930 return ret;
1931 }
1932
1933
1934 /**
1935 * wpa_driver_wext_set_key - Configure encryption key
1936 * @priv: Pointer to private wext data from wpa_driver_wext_init()
1937 * @priv: Private driver interface data
1938 * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP,
1939 * %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key.
1940 * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for
1941 * broadcast/default keys
1942 * @key_idx: key index (0..3), usually 0 for unicast keys
1943 * @set_tx: Configure this key as the default Tx key (only used when
1944 * driver does not support separate unicast/individual key
1945 * @seq: Sequence number/packet number, seq_len octets, the next
1946 * packet number to be used for in replay protection; configured
1947 * for Rx keys (in most cases, this is only used with broadcast
1948 * keys and set to zero for unicast keys)
1949 * @seq_len: Length of the seq, depends on the algorithm:
1950 * TKIP: 6 octets, CCMP: 6 octets
1951 * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key,
1952 * 8-byte Rx Mic Key
1953 * @key_len: Length of the key buffer in octets (WEP: 5 or 13,
1954 * TKIP: 32, CCMP: 16)
1955 * Returns: 0 on success, -1 on failure
1956 *
1957 * This function uses SIOCSIWENCODEEXT by default, but tries to use
1958 * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key.
1959 */
1960 int wpa_driver_wext_set_key(void *priv, wpa_alg alg,
1961 const u8 *addr, int key_idx,
1962 int set_tx, const u8 *seq, size_t seq_len,
1963 const u8 *key, size_t key_len)
1964 {
1965 struct wpa_driver_wext_data *drv = priv;
1966 struct iwreq iwr;
1967 int ret = 0;
1968
1969 wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
1970 "key_len=%lu",
1971 __FUNCTION__, alg, key_idx, set_tx,
1972 (unsigned long) seq_len, (unsigned long) key_len);
1973
1974 ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx,
1975 seq, seq_len, key, key_len);
1976 if (ret == 0)
1977 return 0;
1978
1979 if (ret == -2 &&
1980 (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) {
1981 wpa_printf(MSG_DEBUG, "Driver did not support "
1982 "SIOCSIWENCODEEXT, trying SIOCSIWENCODE");
1983 ret = 0;
1984 } else {
1985 wpa_printf(MSG_DEBUG, "Driver did not support "
1986 "SIOCSIWENCODEEXT");
1987 return ret;
1988 }
1989
1990 os_memset(&iwr, 0, sizeof(iwr));
1991 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1992 iwr.u.encoding.flags = key_idx + 1;
1993 iwr.u.encoding.flags |= IW_ENCODE_TEMP;
1994 if (alg == WPA_ALG_NONE)
1995 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
1996 iwr.u.encoding.pointer = (caddr_t) key;
1997 iwr.u.encoding.length = key_len;
1998
1999 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
2000 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE]");
2001 ret = -1;
2002 }
2003
2004 if (set_tx && alg != WPA_ALG_NONE) {
2005 os_memset(&iwr, 0, sizeof(iwr));
2006 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2007 iwr.u.encoding.flags = key_idx + 1;
2008 iwr.u.encoding.flags |= IW_ENCODE_TEMP;
2009 iwr.u.encoding.pointer = (caddr_t) NULL;
2010 iwr.u.encoding.length = 0;
2011 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
2012 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE] (set_tx)");
2013 ret = -1;
2014 }
2015 }
2016
2017 return ret;
2018 }
2019
2020
2021 static int wpa_driver_wext_set_countermeasures(void *priv,
2022 int enabled)
2023 {
2024 struct wpa_driver_wext_data *drv = priv;
2025 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
2026 return wpa_driver_wext_set_auth_param(drv,
2027 IW_AUTH_TKIP_COUNTERMEASURES,
2028 enabled);
2029 }
2030
2031
2032 static int wpa_driver_wext_set_drop_unencrypted(void *priv,
2033 int enabled)
2034 {
2035 struct wpa_driver_wext_data *drv = priv;
2036 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
2037 drv->use_crypt = enabled;
2038 return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
2039 enabled);
2040 }
2041
2042
2043 static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv,
2044 const u8 *addr, int cmd, int reason_code)
2045 {
2046 struct iwreq iwr;
2047 struct iw_mlme mlme;
2048 int ret = 0;
2049
2050 os_memset(&iwr, 0, sizeof(iwr));
2051 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2052 os_memset(&mlme, 0, sizeof(mlme));
2053 mlme.cmd = cmd;
2054 mlme.reason_code = reason_code;
2055 mlme.addr.sa_family = ARPHRD_ETHER;
2056 os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
2057 iwr.u.data.pointer = (caddr_t) &mlme;
2058 iwr.u.data.length = sizeof(mlme);
2059
2060 if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
2061 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWMLME]");
2062 ret = -1;
2063 }
2064
2065 return ret;
2066 }
2067
2068
2069 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
2070 {
2071 struct iwreq iwr;
2072 const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
2073 #ifndef ANDROID
2074 u8 ssid[32];
2075 int i;
2076 #endif
2077
2078 /*
2079 * Only force-disconnect when the card is in infrastructure mode,
2080 * otherwise the driver might interpret the cleared BSSID and random
2081 * SSID as an attempt to create a new ad-hoc network.
2082 */
2083 os_memset(&iwr, 0, sizeof(iwr));
2084 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2085 if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
2086 wpa_printf(MSG_ERROR, "ioctl[SIOCGIWMODE]");
2087 iwr.u.mode = IW_MODE_INFRA;
2088 }
2089
2090 if (iwr.u.mode == IW_MODE_INFRA) {
2091 /*
2092 * Clear the BSSID selection and set a random SSID to make sure
2093 * the driver will not be trying to associate with something
2094 * even if it does not understand SIOCSIWMLME commands (or
2095 * tries to associate automatically after deauth/disassoc).
2096 */
2097 wpa_driver_wext_set_bssid(drv, null_bssid);
2098 #ifndef ANDROID
2099 for (i = 0; i < 32; i++)
2100 ssid[i] = rand() & 0xFF;
2101 wpa_driver_wext_set_ssid(drv, ssid, 32);
2102 #endif
2103 }
2104 }
2105
2106
2107 static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr,
2108 int reason_code)
2109 {
2110 struct wpa_driver_wext_data *drv = priv;
2111 int ret;
2112 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
2113 ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
2114 wpa_driver_wext_disconnect(drv);
2115 return ret;
2116 }
2117
2118
2119 static int wpa_driver_wext_disassociate(void *priv, const u8 *addr,
2120 int reason_code)
2121 {
2122 struct wpa_driver_wext_data *drv = priv;
2123 int ret;
2124 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
2125 ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
2126 wpa_driver_wext_disconnect(drv);
2127 return ret;
2128 }
2129
2130
2131 static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie,
2132 size_t ie_len)
2133 {
2134 struct wpa_driver_wext_data *drv = priv;
2135 struct iwreq iwr;
2136 int ret = 0;
2137
2138 os_memset(&iwr, 0, sizeof(iwr));
2139 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2140 iwr.u.data.pointer = (caddr_t) ie;
2141 iwr.u.data.length = ie_len;
2142
2143 if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
2144 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWGENIE]");
2145 ret = -1;
2146 }
2147
2148 return ret;
2149 }
2150
2151
2152 int wpa_driver_wext_cipher2wext(int cipher)
2153 {
2154 switch (cipher) {
2155 case CIPHER_NONE:
2156 return IW_AUTH_CIPHER_NONE;
2157 case CIPHER_WEP40:
2158 return IW_AUTH_CIPHER_WEP40;
2159 case CIPHER_TKIP:
2160 return IW_AUTH_CIPHER_TKIP;
2161 case CIPHER_CCMP:
2162 return IW_AUTH_CIPHER_CCMP;
2163 case CIPHER_WEP104:
2164 return IW_AUTH_CIPHER_WEP104;
2165 default:
2166 return 0;
2167 }
2168 }
2169
2170
2171 int wpa_driver_wext_keymgmt2wext(int keymgmt)
2172 {
2173 switch (keymgmt) {
2174 case KEY_MGMT_802_1X:
2175 case KEY_MGMT_802_1X_NO_WPA:
2176 return IW_AUTH_KEY_MGMT_802_1X;
2177 case KEY_MGMT_PSK:
2178 return IW_AUTH_KEY_MGMT_PSK;
2179 default:
2180 return 0;
2181 }
2182 }
2183
2184
2185 static int
2186 wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv,
2187 struct wpa_driver_associate_params *params)
2188 {
2189 struct iwreq iwr;
2190 int ret = 0;
2191
2192 wpa_printf(MSG_DEBUG, "WEXT: Driver did not support "
2193 "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE");
2194
2195 os_memset(&iwr, 0, sizeof(iwr));
2196 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2197 /* Just changing mode, not actual keys */
2198 iwr.u.encoding.flags = 0;
2199 iwr.u.encoding.pointer = (caddr_t) NULL;
2200 iwr.u.encoding.length = 0;
2201
2202 /*
2203 * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two
2204 * different things. Here they are used to indicate Open System vs.
2205 * Shared Key authentication algorithm. However, some drivers may use
2206 * them to select between open/restricted WEP encrypted (open = allow
2207 * both unencrypted and encrypted frames; restricted = only allow
2208 * encrypted frames).
2209 */
2210
2211 if (!drv->use_crypt) {
2212 iwr.u.encoding.flags |= IW_ENCODE_DISABLED;
2213 } else {
2214 if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
2215 iwr.u.encoding.flags |= IW_ENCODE_OPEN;
2216 if (params->auth_alg & AUTH_ALG_SHARED_KEY)
2217 iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED;
2218 }
2219
2220 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) {
2221 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWENCODE]");
2222 ret = -1;
2223 }
2224
2225 return ret;
2226 }
2227
2228
2229 int wpa_driver_wext_associate(void *priv,
2230 struct wpa_driver_associate_params *params)
2231 {
2232 struct wpa_driver_wext_data *drv = priv;
2233 int ret = 0;
2234 int allow_unencrypted_eapol;
2235 int value, flags;
2236
2237 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
2238
2239 #ifdef ANDROID
2240 drv->skip_disconnect = 0;
2241 #endif
2242
2243 if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
2244 if (!(flags & IFF_UP)) {
2245 wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
2246 }
2247 }
2248
2249 /*
2250 * If the driver did not support SIOCSIWAUTH, fallback to
2251 * SIOCSIWENCODE here.
2252 */
2253 if (drv->auth_alg_fallback &&
2254 wpa_driver_wext_auth_alg_fallback(drv, params) < 0)
2255 ret = -1;
2256
2257 if (!params->bssid &&
2258 wpa_driver_wext_set_bssid(drv, NULL) < 0)
2259 ret = -1;
2260
2261 /* TODO: should consider getting wpa version and cipher/key_mgmt suites
2262 * from configuration, not from here, where only the selected suite is
2263 * available */
2264 if (wpa_driver_wext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len)
2265 < 0)
2266 ret = -1;
2267 if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
2268 value = IW_AUTH_WPA_VERSION_DISABLED;
2269 else if (params->wpa_ie[0] == WLAN_EID_RSN)
2270 value = IW_AUTH_WPA_VERSION_WPA2;
2271 else
2272 value = IW_AUTH_WPA_VERSION_WPA;
2273 if (wpa_driver_wext_set_auth_param(drv,
2274 IW_AUTH_WPA_VERSION, value) < 0)
2275 ret = -1;
2276 value = wpa_driver_wext_cipher2wext(params->pairwise_suite);
2277 if (wpa_driver_wext_set_auth_param(drv,
2278 IW_AUTH_CIPHER_PAIRWISE, value) < 0)
2279 ret = -1;
2280 value = wpa_driver_wext_cipher2wext(params->group_suite);
2281 if (wpa_driver_wext_set_auth_param(drv,
2282 IW_AUTH_CIPHER_GROUP, value) < 0)
2283 ret = -1;
2284 value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite);
2285 if (wpa_driver_wext_set_auth_param(drv,
2286 IW_AUTH_KEY_MGMT, value) < 0)
2287 ret = -1;
2288 value = params->key_mgmt_suite != KEY_MGMT_NONE ||
2289 params->pairwise_suite != CIPHER_NONE ||
2290 params->group_suite != CIPHER_NONE ||
2291 params->wpa_ie_len;
2292 if (wpa_driver_wext_set_auth_param(drv,
2293 IW_AUTH_PRIVACY_INVOKED, value) < 0)
2294 ret = -1;
2295
2296 /* Allow unencrypted EAPOL messages even if pairwise keys are set when
2297 * not using WPA. IEEE 802.1X specifies that these frames are not
2298 * encrypted, but WPA encrypts them when pairwise keys are in use. */
2299 if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
2300 params->key_mgmt_suite == KEY_MGMT_PSK)
2301 allow_unencrypted_eapol = 0;
2302 else
2303 allow_unencrypted_eapol = 1;
2304
2305 if (wpa_driver_wext_set_psk(drv, params->psk) < 0)
2306 ret = -1;
2307 if (wpa_driver_wext_set_auth_param(drv,
2308 IW_AUTH_RX_UNENCRYPTED_EAPOL,
2309 allow_unencrypted_eapol) < 0)
2310 ret = -1;
2311 #ifdef CONFIG_IEEE80211W
2312 switch (params->mgmt_frame_protection) {
2313 case NO_MGMT_FRAME_PROTECTION:
2314 value = IW_AUTH_MFP_DISABLED;
2315 break;
2316 case MGMT_FRAME_PROTECTION_OPTIONAL:
2317 value = IW_AUTH_MFP_OPTIONAL;
2318 break;
2319 case MGMT_FRAME_PROTECTION_REQUIRED:
2320 value = IW_AUTH_MFP_REQUIRED;
2321 break;
2322 };
2323 if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0)
2324 ret = -1;
2325 #endif /* CONFIG_IEEE80211W */
2326 if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
2327 ret = -1;
2328 if (wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)
2329 ret = -1;
2330 if (params->bssid &&
2331 wpa_driver_wext_set_bssid(drv, params->bssid) < 0)
2332 ret = -1;
2333
2334 return ret;
2335 }
2336
2337
2338 static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg)
2339 {
2340 struct wpa_driver_wext_data *drv = priv;
2341 int algs = 0, res;
2342
2343 if (auth_alg & AUTH_ALG_OPEN_SYSTEM)
2344 algs |= IW_AUTH_ALG_OPEN_SYSTEM;
2345 if (auth_alg & AUTH_ALG_SHARED_KEY)
2346 algs |= IW_AUTH_ALG_SHARED_KEY;
2347 if (auth_alg & AUTH_ALG_LEAP)
2348 algs |= IW_AUTH_ALG_LEAP;
2349 if (algs == 0) {
2350 /* at least one algorithm should be set */
2351 algs = IW_AUTH_ALG_OPEN_SYSTEM;
2352 }
2353
2354 res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG,
2355 algs);
2356 drv->auth_alg_fallback = res == -2;
2357 return res;
2358 }
2359
2360
2361 /**
2362 * wpa_driver_wext_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE
2363 * @priv: Pointer to private wext data from wpa_driver_wext_init()
2364 * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS
2365 * Returns: 0 on success, -1 on failure
2366 */
2367 int wpa_driver_wext_set_mode(void *priv, int mode)
2368 {
2369 struct wpa_driver_wext_data *drv = priv;
2370 struct iwreq iwr;
2371 int ret = -1, flags;
2372 unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
2373
2374 os_memset(&iwr, 0, sizeof(iwr));
2375 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2376 iwr.u.mode = new_mode;
2377 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) == 0) {
2378 ret = 0;
2379 goto done;
2380 }
2381
2382 if (errno != EBUSY) {
2383 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWMODE]");
2384 goto done;
2385 }
2386
2387 /* mac80211 doesn't allow mode changes while the device is up, so if
2388 * the device isn't in the mode we're about to change to, take device
2389 * down, try to set the mode again, and bring it back up.
2390 */
2391 if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
2392 wpa_printf(MSG_ERROR, "ioctl[SIOCGIWMODE]");
2393 goto done;
2394 }
2395
2396 if (iwr.u.mode == new_mode) {
2397 ret = 0;
2398 goto done;
2399 }
2400
2401 if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
2402 (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
2403
2404 /* Try to set the mode again while the interface is down */
2405 iwr.u.mode = new_mode;
2406 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0)
2407 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWMODE]");
2408 else
2409 ret = 0;
2410
2411 /* Ignore return value of get_ifflags to ensure that the device
2412 * is always up like it was before this function was called.
2413 */
2414 (void) wpa_driver_wext_get_ifflags(drv, &flags);
2415 (void) wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
2416 }
2417
2418 done:
2419 return ret;
2420 }
2421
2422
2423 static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv,
2424 u32 cmd, const u8 *bssid, const u8 *pmkid)
2425 {
2426 struct iwreq iwr;
2427 struct iw_pmksa pmksa;
2428 int ret = 0;
2429
2430 os_memset(&iwr, 0, sizeof(iwr));
2431 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2432 os_memset(&pmksa, 0, sizeof(pmksa));
2433 pmksa.cmd = cmd;
2434 pmksa.bssid.sa_family = ARPHRD_ETHER;
2435 if (bssid)
2436 os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN);
2437 if (pmkid)
2438 os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN);
2439 iwr.u.data.pointer = (caddr_t) &pmksa;
2440 iwr.u.data.length = sizeof(pmksa);
2441
2442 if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {
2443 if (errno != EOPNOTSUPP)
2444 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPMKSA]");
2445 ret = -1;
2446 }
2447
2448 return ret;
2449 }
2450
2451
2452 static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid,
2453 const u8 *pmkid)
2454 {
2455 struct wpa_driver_wext_data *drv = priv;
2456 return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);
2457 }
2458
2459
2460 static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid,
2461 const u8 *pmkid)
2462 {
2463 struct wpa_driver_wext_data *drv = priv;
2464 return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);
2465 }
2466
2467
2468 static int wpa_driver_wext_flush_pmkid(void *priv)
2469 {
2470 struct wpa_driver_wext_data *drv = priv;
2471 return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL);
2472 }
2473
2474
2475 int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa)
2476 {
2477 struct wpa_driver_wext_data *drv = priv;
2478 if (!drv->has_capability)
2479 return -1;
2480 os_memcpy(capa, &drv->capa, sizeof(*capa));
2481 return 0;
2482 }
2483
2484
2485 int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv,
2486 const char *ifname)
2487 {
2488 if (ifname == NULL) {
2489 drv->ifindex2 = -1;
2490 return 0;
2491 }
2492
2493 drv->ifindex2 = if_nametoindex(ifname);
2494 if (drv->ifindex2 <= 0)
2495 return -1;
2496
2497 wpa_printf(MSG_DEBUG, "Added alternative ifindex %d (%s) for "
2498 "wireless events", drv->ifindex2, ifname);
2499
2500 return 0;
2501 }
2502
2503
2504 int wpa_driver_wext_set_operstate(void *priv, int state)
2505 {
2506 struct wpa_driver_wext_data *drv = priv;
2507
2508 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
2509 __func__, drv->operstate, state, state ? "UP" : "DORMANT");
2510 drv->operstate = state;
2511 return wpa_driver_wext_send_oper_ifla(
2512 drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT);
2513 }
2514
2515
2516 int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv)
2517 {
2518 return drv->we_version_compiled;
2519 }
2520
2521
2522 #ifdef ANDROID
2523 static int wpa_driver_wext_set_cscan_params(char *buf, size_t buf_len, char *cmd)
2524 {
2525 char *pasv_ptr;
2526 int bp, i;
2527 u16 pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF;
2528 u8 channel;
2529
2530 wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd);
2531
2532 /* Get command parameters */
2533 pasv_ptr = os_strstr(cmd, ",TIME=");
2534 if (pasv_ptr) {
2535 *pasv_ptr = '\0';
2536 pasv_ptr += 6;
2537 pasv_dwell = (u16)atoi(pasv_ptr);
2538 if (pasv_dwell == 0)
2539 pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF;
2540 }
2541 channel = (u8)atoi(cmd + 5);
2542
2543 bp = WEXT_CSCAN_HEADER_SIZE;
2544 os_memcpy(buf, WEXT_CSCAN_HEADER, bp);
2545
2546 /* Set list of channels */
2547 buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
2548 buf[bp++] = channel;
2549 if (channel != 0) {
2550 i = (pasv_dwell - 1) / WEXT_CSCAN_PASV_DWELL_TIME_DEF;
2551 for (; i > 0; i--) {
2552 if ((size_t)(bp + 12) >= buf_len)
2553 break;
2554 buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
2555 buf[bp++] = channel;
2556 }
2557 } else {
2558 if (pasv_dwell > WEXT_CSCAN_PASV_DWELL_TIME_MAX)
2559 pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_MAX;
2560 }
2561
2562 /* Set passive dwell time (default is 250) */
2563 buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION;
2564 if (channel != 0) {
2565 buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME_DEF;
2566 buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME_DEF >> 8);
2567 } else {
2568 buf[bp++] = (u8)pasv_dwell;
2569 buf[bp++] = (u8)(pasv_dwell >> 8);
2570 }
2571
2572 /* Set home dwell time (default is 40) */
2573 buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION;
2574 buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME;
2575 buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8);
2576
2577 /* Set cscan type */
2578 buf[bp++] = WEXT_CSCAN_TYPE_SECTION;
2579 buf[bp++] = WEXT_CSCAN_TYPE_PASSIVE;
2580 return bp;
2581 }
2582
2583 static char *wpa_driver_get_country_code(int channels)
2584 {
2585 char *country = "US"; /* WEXT_NUMBER_SCAN_CHANNELS_FCC */
2586
2587 if (channels == WEXT_NUMBER_SCAN_CHANNELS_ETSI)
2588 country = "EU";
2589 else if( channels == WEXT_NUMBER_SCAN_CHANNELS_MKK1)
2590 country = "JP";
2591 return country;
2592 }
2593
2594 static int wpa_driver_set_backgroundscan_params(void *priv)
2595 {
2596 struct wpa_driver_wext_data *drv = priv;
2597 struct wpa_supplicant *wpa_s;
2598 struct iwreq iwr;
2599 int ret = 0, i = 0, bp;
2600 char buf[WEXT_PNO_MAX_COMMAND_SIZE];
2601 struct wpa_ssid *ssid_conf;
2602
2603 if (drv == NULL){
2604 wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__);
2605 return -1;
2606 }
2607 if (drv->ctx == NULL){
2608 wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__);
2609 return -1;
2610 }
2611 wpa_s = (struct wpa_supplicant *)(drv->ctx);
2612 if (wpa_s->conf == NULL) {
2613 wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__);
2614 return -1;
2615 }
2616 ssid_conf = wpa_s->conf->ssid;
2617
2618 bp = WEXT_PNOSETUP_HEADER_SIZE;
2619 os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
2620 buf[bp++] = 'S';
2621 buf[bp++] = WEXT_PNO_TLV_VERSION;
2622 buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
2623 buf[bp++] = WEXT_PNO_TLV_RESERVED;
2624
2625 while ((i < WEXT_PNO_AMOUNT) && (ssid_conf != NULL)) {
2626 /* Check that there is enough space needed for 1 more SSID, the other sections and null termination */
2627 if ((bp + WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int)sizeof(buf))
2628 break;
2629 if ((!ssid_conf->disabled) && (ssid_conf->ssid_len <= IW_ESSID_MAX_SIZE)){
2630 wpa_printf(MSG_DEBUG, "For PNO Scan: %s", ssid_conf->ssid);
2631 buf[bp++] = WEXT_PNO_SSID_SECTION;
2632 buf[bp++] = ssid_conf->ssid_len;
2633 os_memcpy(&buf[bp], ssid_conf->ssid, ssid_conf->ssid_len);
2634 bp += ssid_conf->ssid_len;
2635 i++;
2636 }
2637 ssid_conf = ssid_conf->next;
2638 }
2639
2640 buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
2641 os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x", WEXT_PNO_SCAN_INTERVAL);
2642 bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
2643
2644 buf[bp++] = WEXT_PNO_REPEAT_SECTION;
2645 os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x", WEXT_PNO_REPEAT);
2646 bp += WEXT_PNO_REPEAT_LENGTH;
2647
2648 buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
2649 os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x", WEXT_PNO_MAX_REPEAT);
2650 bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
2651
2652 os_memset(&iwr, 0, sizeof(iwr));
2653 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2654 iwr.u.data.pointer = buf;
2655 iwr.u.data.length = bp;
2656
2657 ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
2658
2659 if (ret < 0) {
2660 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", ret);
2661 drv->errors++;
2662 if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) {
2663 drv->errors = 0;
2664 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
2665 }
2666 } else {
2667 drv->errors = 0;
2668 }
2669 return ret;
2670
2671 }
2672
2673 static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
2674 {
2675 struct wpa_driver_wext_data *drv = priv;
2676 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
2677 struct iwreq iwr;
2678 int ret = 0, flags;
2679
2680 wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
2681
2682 if (!drv->driver_is_started && (os_strcasecmp(cmd, "START") != 0)) {
2683 wpa_printf(MSG_ERROR,"WEXT: Driver not initialized yet");
2684 return -1;
2685 }
2686
2687 if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) {
2688 os_strncpy(cmd, "RSSI", MAX_DRV_CMD_SIZE);
2689 } else if( os_strncasecmp(cmd, "SCAN-CHANNELS", 13) == 0 ) {
2690 int no_of_chan;
2691
2692 no_of_chan = atoi(cmd + 13);
2693 os_snprintf(cmd, MAX_DRV_CMD_SIZE, "COUNTRY %s",
2694 wpa_driver_get_country_code(no_of_chan));
2695 } else if (os_strcasecmp(cmd, "STOP") == 0) {
2696 if ((wpa_driver_wext_get_ifflags(drv, &flags) == 0) &&
2697 (flags & IFF_UP)) {
2698 wpa_printf(MSG_ERROR, "WEXT: %s when iface is UP", cmd);
2699 wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
2700 }
2701 } else if( os_strcasecmp(cmd, "RELOAD") == 0 ) {
2702 wpa_printf(MSG_DEBUG,"Reload command");
2703 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
2704 return ret;
2705 } else if( os_strcasecmp(cmd, "BGSCAN-START") == 0 ) {
2706 ret = wpa_driver_set_backgroundscan_params(priv);
2707 if (ret < 0) {
2708 return ret;
2709 }
2710 os_strncpy(cmd, "PNOFORCE 1", MAX_DRV_CMD_SIZE);
2711 drv->bgscan_enabled = 1;
2712 } else if( os_strcasecmp(cmd, "BGSCAN-STOP") == 0 ) {
2713 os_strncpy(cmd, "PNOFORCE 0", MAX_DRV_CMD_SIZE);
2714 drv->bgscan_enabled = 0;
2715 }
2716
2717 os_memset(&iwr, 0, sizeof(iwr));
2718 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
2719 os_memcpy(buf, cmd, strlen(cmd) + 1);
2720 iwr.u.data.pointer = buf;
2721 iwr.u.data.length = buf_len;
2722
2723 if( os_strncasecmp(cmd, "CSCAN", 5) == 0 ) {
2724 if (!wpa_s->scanning && ((wpa_s->wpa_state <= WPA_SCANNING) ||
2725 (wpa_s->wpa_state >= WPA_COMPLETED))) {
2726 iwr.u.data.length = wpa_driver_wext_set_cscan_params(buf, buf_len, cmd);
2727 } else {
2728 wpa_printf(MSG_ERROR, "Ongoing Scan action...");
2729 return ret;
2730 }
2731 }
2732
2733 ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
2734
2735 if (ret < 0) {
2736 wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, cmd);
2737 drv->errors++;
2738 if (drv->errors > WEXT_NUMBER_SEQUENTIAL_ERRORS) {
2739 drv->errors = 0;
2740 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
2741 }
2742 } else {
2743 drv->errors = 0;
2744 ret = 0;
2745 if ((os_strcasecmp(cmd, "RSSI") == 0) ||
2746 (os_strcasecmp(cmd, "LINKSPEED") == 0) ||
2747 (os_strcasecmp(cmd, "MACADDR") == 0) ||
2748 (os_strcasecmp(cmd, "GETPOWER") == 0) ||
2749 (os_strcasecmp(cmd, "GETBAND") == 0)) {
2750 ret = strlen(buf);
2751 } else if (os_strcasecmp(cmd, "START") == 0) {
2752 drv->driver_is_started = TRUE;
2753 /* os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
2754 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); */
2755 } else if (os_strcasecmp(cmd, "STOP") == 0) {
2756 drv->driver_is_started = FALSE;
2757 /* wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); */
2758 } else if (os_strncasecmp(cmd, "CSCAN", 5) == 0) {
2759 wpa_driver_wext_set_scan_timeout(priv);
2760 wpa_supplicant_notify_scanning(wpa_s, 1);
2761 }
2762 wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
2763 }
2764 return ret;
2765 }
2766 #endif
2767
2768
2769 const struct wpa_driver_ops wpa_driver_wext_ops = {
2770 .name = "wext",
2771 .desc = "Linux wireless extensions (generic)",
2772 .get_bssid = wpa_driver_wext_get_bssid,
2773 .get_ssid = wpa_driver_wext_get_ssid,
2774 .set_wpa = wpa_driver_wext_set_wpa,
2775 .set_key = wpa_driver_wext_set_key,
2776 .set_countermeasures = wpa_driver_wext_set_countermeasures,
2777 .set_drop_unencrypted = wpa_driver_wext_set_drop_unencrypted,
2778 .scan = wpa_driver_wext_scan,
2779 .combo_scan = wpa_driver_wext_combo_scan,
2780 .get_scan_results2 = wpa_driver_wext_get_scan_results,
2781 .deauthenticate = wpa_driver_wext_deauthenticate,
2782 .disassociate = wpa_driver_wext_disassociate,
2783 .set_mode = wpa_driver_wext_set_mode,
2784 .associate = wpa_driver_wext_associate,
2785 .set_auth_alg = wpa_driver_wext_set_auth_alg,
2786 .init = wpa_driver_wext_init,
2787 .deinit = wpa_driver_wext_deinit,
2788 .add_pmkid = wpa_driver_wext_add_pmkid,
2789 .remove_pmkid = wpa_driver_wext_remove_pmkid,
2790 .flush_pmkid = wpa_driver_wext_flush_pmkid,
2791 .get_capa = wpa_driver_wext_get_capa,
2792 .set_operstate = wpa_driver_wext_set_operstate,
2793 #ifdef ANDROID
2794 .driver_cmd = wpa_driver_priv_driver_cmd,
2795 #endif
2796 };
2797