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