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