• 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 };
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(&param, 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, &param, 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(&param, 0, sizeof(param));
2449 	param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
2450 	os_memcpy(param.sta_addr, addr, ETH_ALEN);
2451 	return hostapd_ioctl(drv, &param, 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