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