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