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