Home | History | Annotate | Download | only in drivers
      1 /*
      2  * WPA Supplicant - driver interaction with MADWIFI 802.11 driver
      3  * Copyright (c) 2004, Sam Leffler <sam (at) errno.com>
      4  * Copyright (c) 2004, Video54 Technologies
      5  * Copyright (c) 2004-2007, Jouni Malinen <j (at) w1.fi>
      6  *
      7  * This program is free software; you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License version 2 as
      9  * published by the Free Software Foundation.
     10  *
     11  * Alternatively, this software may be distributed under the terms of BSD
     12  * license.
     13  *
     14  * See README and COPYING for more details.
     15  *
     16  * While this driver wrapper supports both AP (hostapd) and station
     17  * (wpa_supplicant) operations, the station side is deprecated and
     18  * driver_wext.c should be used instead. This driver wrapper should only be
     19  * used with hostapd for AP mode functionality.
     20  */
     21 
     22 #include "includes.h"
     23 #include <sys/ioctl.h>
     24 
     25 #include "common.h"
     26 #include "driver.h"
     27 #include "driver_wext.h"
     28 #include "eloop.h"
     29 #include "common/ieee802_11_defs.h"
     30 #include "wireless_copy.h"
     31 
     32 /*
     33  * Avoid conflicts with wpa_supplicant definitions by undefining a definition.
     34  */
     35 #undef WME_OUI_TYPE
     36 
     37 #include <include/compat.h>
     38 #include <net80211/ieee80211.h>
     39 #ifdef WME_NUM_AC
     40 /* Assume this is built against BSD branch of madwifi driver. */
     41 #define MADWIFI_BSD
     42 #include <net80211/_ieee80211.h>
     43 #endif /* WME_NUM_AC */
     44 #include <net80211/ieee80211_crypto.h>
     45 #include <net80211/ieee80211_ioctl.h>
     46 
     47 #ifdef CONFIG_WPS
     48 #ifdef IEEE80211_IOCTL_FILTERFRAME
     49 #include <netpacket/packet.h>
     50 
     51 #ifndef ETH_P_80211_RAW
     52 #define ETH_P_80211_RAW 0x0019
     53 #endif
     54 #endif /* IEEE80211_IOCTL_FILTERFRAME */
     55 #endif /* CONFIG_WPS */
     56 
     57 /*
     58  * Avoid conflicts with hostapd definitions by undefining couple of defines
     59  * from madwifi header files.
     60  */
     61 #undef RSN_VERSION
     62 #undef WPA_VERSION
     63 #undef WPA_OUI_TYPE
     64 #undef WME_OUI_TYPE
     65 
     66 
     67 #ifdef IEEE80211_IOCTL_SETWMMPARAMS
     68 /* Assume this is built against madwifi-ng */
     69 #define MADWIFI_NG
     70 #endif /* IEEE80211_IOCTL_SETWMMPARAMS */
     71 
     72 #define WPA_KEY_RSC_LEN 8
     73 
     74 #ifdef HOSTAPD
     75 
     76 #include "priv_netlink.h"
     77 #include "netlink.h"
     78 #include "linux_ioctl.h"
     79 #include "l2_packet/l2_packet.h"
     80 
     81 
     82 struct madwifi_driver_data {
     83 	struct hostapd_data *hapd;		/* back pointer */
     84 
     85 	char	iface[IFNAMSIZ + 1];
     86 	int     ifindex;
     87 	struct l2_packet_data *sock_xmit;	/* raw packet xmit socket */
     88 	struct l2_packet_data *sock_recv;	/* raw packet recv socket */
     89 	int	ioctl_sock;			/* socket for ioctl() use */
     90 	struct netlink_data *netlink;
     91 	int	we_version;
     92 	u8	acct_mac[ETH_ALEN];
     93 	struct hostap_sta_driver_data acct_data;
     94 
     95 	struct l2_packet_data *sock_raw; /* raw 802.11 management frames */
     96 };
     97 
     98 static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
     99 			      int reason_code);
    100 
    101 static int
    102 set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len)
    103 {
    104 	struct iwreq iwr;
    105 	int do_inline = len < IFNAMSIZ;
    106 
    107 	memset(&iwr, 0, sizeof(iwr));
    108 	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
    109 #ifdef IEEE80211_IOCTL_FILTERFRAME
    110 	/* FILTERFRAME must be NOT inline, regardless of size. */
    111 	if (op == IEEE80211_IOCTL_FILTERFRAME)
    112 		do_inline = 0;
    113 #endif /* IEEE80211_IOCTL_FILTERFRAME */
    114 	if (op == IEEE80211_IOCTL_SET_APPIEBUF)
    115 		do_inline = 0;
    116 	if (do_inline) {
    117 		/*
    118 		 * Argument data fits inline; put it there.
    119 		 */
    120 		memcpy(iwr.u.name, data, len);
    121 	} else {
    122 		/*
    123 		 * Argument data too big for inline transfer; setup a
    124 		 * parameter block instead; the kernel will transfer
    125 		 * the data for the driver.
    126 		 */
    127 		iwr.u.data.pointer = data;
    128 		iwr.u.data.length = len;
    129 	}
    130 
    131 	if (ioctl(drv->ioctl_sock, op, &iwr) < 0) {
    132 #ifdef MADWIFI_NG
    133 		int first = IEEE80211_IOCTL_SETPARAM;
    134 		static const char *opnames[] = {
    135 			"ioctl[IEEE80211_IOCTL_SETPARAM]",
    136 			"ioctl[IEEE80211_IOCTL_GETPARAM]",
    137 			"ioctl[IEEE80211_IOCTL_SETMODE]",
    138 			"ioctl[IEEE80211_IOCTL_GETMODE]",
    139 			"ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
    140 			"ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
    141 			"ioctl[IEEE80211_IOCTL_SETCHANLIST]",
    142 			"ioctl[IEEE80211_IOCTL_GETCHANLIST]",
    143 			"ioctl[IEEE80211_IOCTL_CHANSWITCH]",
    144 			"ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
    145 			"ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
    146 			"ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
    147 			"ioctl[IEEE80211_IOCTL_FILTERFRAME]",
    148 			"ioctl[IEEE80211_IOCTL_GETCHANINFO]",
    149 			"ioctl[IEEE80211_IOCTL_SETOPTIE]",
    150 			"ioctl[IEEE80211_IOCTL_GETOPTIE]",
    151 			"ioctl[IEEE80211_IOCTL_SETMLME]",
    152 			NULL,
    153 			"ioctl[IEEE80211_IOCTL_SETKEY]",
    154 			NULL,
    155 			"ioctl[IEEE80211_IOCTL_DELKEY]",
    156 			NULL,
    157 			"ioctl[IEEE80211_IOCTL_ADDMAC]",
    158 			NULL,
    159 			"ioctl[IEEE80211_IOCTL_DELMAC]",
    160 			NULL,
    161 			"ioctl[IEEE80211_IOCTL_WDSMAC]",
    162 			NULL,
    163 			"ioctl[IEEE80211_IOCTL_WDSDELMAC]",
    164 			NULL,
    165 			"ioctl[IEEE80211_IOCTL_KICKMAC]",
    166 		};
    167 #else /* MADWIFI_NG */
    168 		int first = IEEE80211_IOCTL_SETPARAM;
    169 		static const char *opnames[] = {
    170 			"ioctl[IEEE80211_IOCTL_SETPARAM]",
    171 			"ioctl[IEEE80211_IOCTL_GETPARAM]",
    172 			"ioctl[IEEE80211_IOCTL_SETKEY]",
    173 			"ioctl[SIOCIWFIRSTPRIV+3]",
    174 			"ioctl[IEEE80211_IOCTL_DELKEY]",
    175 			"ioctl[SIOCIWFIRSTPRIV+5]",
    176 			"ioctl[IEEE80211_IOCTL_SETMLME]",
    177 			"ioctl[SIOCIWFIRSTPRIV+7]",
    178 			"ioctl[IEEE80211_IOCTL_SETOPTIE]",
    179 			"ioctl[IEEE80211_IOCTL_GETOPTIE]",
    180 			"ioctl[IEEE80211_IOCTL_ADDMAC]",
    181 			"ioctl[SIOCIWFIRSTPRIV+11]",
    182 			"ioctl[IEEE80211_IOCTL_DELMAC]",
    183 			"ioctl[SIOCIWFIRSTPRIV+13]",
    184 			"ioctl[IEEE80211_IOCTL_CHANLIST]",
    185 			"ioctl[SIOCIWFIRSTPRIV+15]",
    186 			"ioctl[IEEE80211_IOCTL_GETRSN]",
    187 			"ioctl[SIOCIWFIRSTPRIV+17]",
    188 			"ioctl[IEEE80211_IOCTL_GETKEY]",
    189 		};
    190 #endif /* MADWIFI_NG */
    191 		int idx = op - first;
    192 		if (first <= op &&
    193 		    idx < (int) (sizeof(opnames) / sizeof(opnames[0])) &&
    194 		    opnames[idx])
    195 			perror(opnames[idx]);
    196 		else
    197 			perror("ioctl[unknown???]");
    198 		return -1;
    199 	}
    200 	return 0;
    201 }
    202 
    203 static int
    204 set80211param(struct madwifi_driver_data *drv, int op, int arg)
    205 {
    206 	struct iwreq iwr;
    207 
    208 	memset(&iwr, 0, sizeof(iwr));
    209 	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
    210 	iwr.u.mode = op;
    211 	memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg));
    212 
    213 	if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
    214 		perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
    215 		wpa_printf(MSG_DEBUG, "%s: Failed to set parameter (op %d "
    216 			   "arg %d)", __func__, op, arg);
    217 		return -1;
    218 	}
    219 	return 0;
    220 }
    221 
    222 #ifndef CONFIG_NO_STDOUT_DEBUG
    223 static const char *
    224 ether_sprintf(const u8 *addr)
    225 {
    226 	static char buf[sizeof(MACSTR)];
    227 
    228 	if (addr != NULL)
    229 		snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
    230 	else
    231 		snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
    232 	return buf;
    233 }
    234 #endif /* CONFIG_NO_STDOUT_DEBUG */
    235 
    236 /*
    237  * Configure WPA parameters.
    238  */
    239 static int
    240 madwifi_configure_wpa(struct madwifi_driver_data *drv,
    241 		      struct wpa_bss_params *params)
    242 {
    243 	int v;
    244 
    245 	switch (params->wpa_group) {
    246 	case WPA_CIPHER_CCMP:
    247 		v = IEEE80211_CIPHER_AES_CCM;
    248 		break;
    249 	case WPA_CIPHER_TKIP:
    250 		v = IEEE80211_CIPHER_TKIP;
    251 		break;
    252 	case WPA_CIPHER_WEP104:
    253 		v = IEEE80211_CIPHER_WEP;
    254 		break;
    255 	case WPA_CIPHER_WEP40:
    256 		v = IEEE80211_CIPHER_WEP;
    257 		break;
    258 	case WPA_CIPHER_NONE:
    259 		v = IEEE80211_CIPHER_NONE;
    260 		break;
    261 	default:
    262 		wpa_printf(MSG_ERROR, "Unknown group key cipher %u",
    263 			   params->wpa_group);
    264 		return -1;
    265 	}
    266 	wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v);
    267 	if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) {
    268 		printf("Unable to set group key cipher to %u\n", v);
    269 		return -1;
    270 	}
    271 	if (v == IEEE80211_CIPHER_WEP) {
    272 		/* key length is done only for specific ciphers */
    273 		v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
    274 		if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) {
    275 			printf("Unable to set group key length to %u\n", v);
    276 			return -1;
    277 		}
    278 	}
    279 
    280 	v = 0;
    281 	if (params->wpa_pairwise & WPA_CIPHER_CCMP)
    282 		v |= 1<<IEEE80211_CIPHER_AES_CCM;
    283 	if (params->wpa_pairwise & WPA_CIPHER_TKIP)
    284 		v |= 1<<IEEE80211_CIPHER_TKIP;
    285 	if (params->wpa_pairwise & WPA_CIPHER_NONE)
    286 		v |= 1<<IEEE80211_CIPHER_NONE;
    287 	wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
    288 	if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) {
    289 		printf("Unable to set pairwise key ciphers to 0x%x\n", v);
    290 		return -1;
    291 	}
    292 
    293 	wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
    294 		   __func__, params->wpa_key_mgmt);
    295 	if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS,
    296 			  params->wpa_key_mgmt)) {
    297 		printf("Unable to set key management algorithms to 0x%x\n",
    298 			params->wpa_key_mgmt);
    299 		return -1;
    300 	}
    301 
    302 	v = 0;
    303 	if (params->rsn_preauth)
    304 		v |= BIT(0);
    305 	wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
    306 		   __func__, params->rsn_preauth);
    307 	if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) {
    308 		printf("Unable to set RSN capabilities to 0x%x\n", v);
    309 		return -1;
    310 	}
    311 
    312 	wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa);
    313 	if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) {
    314 		printf("Unable to set WPA to %u\n", params->wpa);
    315 		return -1;
    316 	}
    317 	return 0;
    318 }
    319 
    320 static int
    321 madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params)
    322 {
    323 	struct madwifi_driver_data *drv = priv;
    324 
    325 	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);
    326 
    327 	if (!params->enabled) {
    328 		/* XXX restore state */
    329 		return set80211param(priv, IEEE80211_PARAM_AUTHMODE,
    330 			IEEE80211_AUTH_AUTO);
    331 	}
    332 	if (!params->wpa && !params->ieee802_1x) {
    333 		hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
    334 			HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
    335 		return -1;
    336 	}
    337 	if (params->wpa && madwifi_configure_wpa(drv, params) != 0) {
    338 		hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
    339 			HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
    340 		return -1;
    341 	}
    342 	if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
    343 		(params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
    344 		hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
    345 			HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
    346 		return -1;
    347 	}
    348 
    349 	return 0;
    350 }
    351 
    352 static int
    353 madwifi_set_privacy(void *priv, int enabled)
    354 {
    355 	struct madwifi_driver_data *drv = priv;
    356 
    357 	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
    358 
    359 	return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled);
    360 }
    361 
    362 static int
    363 madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized)
    364 {
    365 	struct madwifi_driver_data *drv = priv;
    366 	struct ieee80211req_mlme mlme;
    367 	int ret;
    368 
    369 	wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
    370 		   __func__, ether_sprintf(addr), authorized);
    371 
    372 	if (authorized)
    373 		mlme.im_op = IEEE80211_MLME_AUTHORIZE;
    374 	else
    375 		mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
    376 	mlme.im_reason = 0;
    377 	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
    378 	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
    379 	if (ret < 0) {
    380 		wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR,
    381 			   __func__, authorized ? "" : "un", MAC2STR(addr));
    382 	}
    383 
    384 	return ret;
    385 }
    386 
    387 static int
    388 madwifi_sta_set_flags(void *priv, const u8 *addr,
    389 		      int total_flags, int flags_or, int flags_and)
    390 {
    391 	/* For now, only support setting Authorized flag */
    392 	if (flags_or & WPA_STA_AUTHORIZED)
    393 		return madwifi_set_sta_authorized(priv, addr, 1);
    394 	if (!(flags_and & WPA_STA_AUTHORIZED))
    395 		return madwifi_set_sta_authorized(priv, addr, 0);
    396 	return 0;
    397 }
    398 
    399 static int
    400 madwifi_del_key(void *priv, const u8 *addr, int key_idx)
    401 {
    402 	struct madwifi_driver_data *drv = priv;
    403 	struct ieee80211req_del_key wk;
    404 	int ret;
    405 
    406 	wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
    407 		   __func__, ether_sprintf(addr), key_idx);
    408 
    409 	memset(&wk, 0, sizeof(wk));
    410 	if (addr != NULL) {
    411 		memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
    412 		wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE;
    413 	} else {
    414 		wk.idk_keyix = key_idx;
    415 	}
    416 
    417 	ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk));
    418 	if (ret < 0) {
    419 		wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s"
    420 			   " key_idx %d)", __func__, ether_sprintf(addr),
    421 			   key_idx);
    422 	}
    423 
    424 	return ret;
    425 }
    426 
    427 static int
    428 wpa_driver_madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg,
    429 			   const u8 *addr, int key_idx, int set_tx,
    430 			   const u8 *seq, size_t seq_len,
    431 			   const u8 *key, size_t key_len)
    432 {
    433 	struct madwifi_driver_data *drv = priv;
    434 	struct ieee80211req_key wk;
    435 	u_int8_t cipher;
    436 	int ret;
    437 
    438 	if (alg == WPA_ALG_NONE)
    439 		return madwifi_del_key(drv, addr, key_idx);
    440 
    441 	wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d",
    442 		   __func__, alg, ether_sprintf(addr), key_idx);
    443 
    444 	if (alg == WPA_ALG_WEP)
    445 		cipher = IEEE80211_CIPHER_WEP;
    446 	else if (alg == WPA_ALG_TKIP)
    447 		cipher = IEEE80211_CIPHER_TKIP;
    448 	else if (alg == WPA_ALG_CCMP)
    449 		cipher = IEEE80211_CIPHER_AES_CCM;
    450 	else {
    451 		printf("%s: unknown/unsupported algorithm %d\n",
    452 			__func__, alg);
    453 		return -1;
    454 	}
    455 
    456 	if (key_len > sizeof(wk.ik_keydata)) {
    457 		printf("%s: key length %lu too big\n", __func__,
    458 		       (unsigned long) key_len);
    459 		return -3;
    460 	}
    461 
    462 	memset(&wk, 0, sizeof(wk));
    463 	wk.ik_type = cipher;
    464 	wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
    465 	if (addr == NULL || is_broadcast_ether_addr(addr)) {
    466 		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
    467 		wk.ik_keyix = key_idx;
    468 		wk.ik_flags |= IEEE80211_KEY_DEFAULT;
    469 	} else {
    470 		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
    471 		wk.ik_keyix = IEEE80211_KEYIX_NONE;
    472 	}
    473 	wk.ik_keylen = key_len;
    474 	memcpy(wk.ik_keydata, key, key_len);
    475 
    476 	ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));
    477 	if (ret < 0) {
    478 		wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s"
    479 			   " key_idx %d alg %d key_len %lu set_tx %d)",
    480 			   __func__, ether_sprintf(wk.ik_macaddr), key_idx,
    481 			   alg, (unsigned long) key_len, set_tx);
    482 	}
    483 
    484 	return ret;
    485 }
    486 
    487 
    488 static int
    489 madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
    490 		   u8 *seq)
    491 {
    492 	struct madwifi_driver_data *drv = priv;
    493 	struct ieee80211req_key wk;
    494 
    495 	wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
    496 		   __func__, ether_sprintf(addr), idx);
    497 
    498 	memset(&wk, 0, sizeof(wk));
    499 	if (addr == NULL)
    500 		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
    501 	else
    502 		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
    503 	wk.ik_keyix = idx;
    504 
    505 	if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) {
    506 		wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data "
    507 			   "(addr " MACSTR " key_idx %d)",
    508 			   __func__, MAC2STR(wk.ik_macaddr), idx);
    509 		return -1;
    510 	}
    511 
    512 #ifdef WORDS_BIGENDIAN
    513 	{
    514 		/*
    515 		 * wk.ik_keytsc is in host byte order (big endian), need to
    516 		 * swap it to match with the byte order used in WPA.
    517 		 */
    518 		int i;
    519 		u8 tmp[WPA_KEY_RSC_LEN];
    520 		memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
    521 		for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
    522 			seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
    523 		}
    524 	}
    525 #else /* WORDS_BIGENDIAN */
    526 	memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
    527 #endif /* WORDS_BIGENDIAN */
    528 	return 0;
    529 }
    530 
    531 
    532 static int
    533 madwifi_flush(void *priv)
    534 {
    535 #ifdef MADWIFI_BSD
    536 	u8 allsta[IEEE80211_ADDR_LEN];
    537 	memset(allsta, 0xff, IEEE80211_ADDR_LEN);
    538 	return madwifi_sta_deauth(priv, NULL, allsta,
    539 				  IEEE80211_REASON_AUTH_LEAVE);
    540 #else /* MADWIFI_BSD */
    541 	return 0;		/* XXX */
    542 #endif /* MADWIFI_BSD */
    543 }
    544 
    545 
    546 static int
    547 madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
    548 			     const u8 *addr)
    549 {
    550 	struct madwifi_driver_data *drv = priv;
    551 
    552 #ifdef MADWIFI_BSD
    553 	struct ieee80211req_sta_stats stats;
    554 
    555 	memset(data, 0, sizeof(*data));
    556 
    557 	/*
    558 	 * Fetch statistics for station from the system.
    559 	 */
    560 	memset(&stats, 0, sizeof(stats));
    561 	memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
    562 	if (set80211priv(drv,
    563 #ifdef MADWIFI_NG
    564 			 IEEE80211_IOCTL_STA_STATS,
    565 #else /* MADWIFI_NG */
    566 			 IEEE80211_IOCTL_GETSTASTATS,
    567 #endif /* MADWIFI_NG */
    568 			 &stats, sizeof(stats))) {
    569 		wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr "
    570 			   MACSTR ")", __func__, MAC2STR(addr));
    571 		if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
    572 			memcpy(data, &drv->acct_data, sizeof(*data));
    573 			return 0;
    574 		}
    575 
    576 		printf("Failed to get station stats information element.\n");
    577 		return -1;
    578 	}
    579 
    580 	data->rx_packets = stats.is_stats.ns_rx_data;
    581 	data->rx_bytes = stats.is_stats.ns_rx_bytes;
    582 	data->tx_packets = stats.is_stats.ns_tx_data;
    583 	data->tx_bytes = stats.is_stats.ns_tx_bytes;
    584 	return 0;
    585 
    586 #else /* MADWIFI_BSD */
    587 
    588 	char buf[1024], line[128], *pos;
    589 	FILE *f;
    590 	unsigned long val;
    591 
    592 	memset(data, 0, sizeof(*data));
    593 	snprintf(buf, sizeof(buf), "/proc/net/madwifi/%s/" MACSTR,
    594 		 drv->iface, MAC2STR(addr));
    595 
    596 	f = fopen(buf, "r");
    597 	if (!f) {
    598 		if (memcmp(addr, drv->acct_mac, ETH_ALEN) != 0)
    599 			return -1;
    600 		memcpy(data, &drv->acct_data, sizeof(*data));
    601 		return 0;
    602 	}
    603 	/* Need to read proc file with in one piece, so use large enough
    604 	 * buffer. */
    605 	setbuffer(f, buf, sizeof(buf));
    606 
    607 	while (fgets(line, sizeof(line), f)) {
    608 		pos = strchr(line, '=');
    609 		if (!pos)
    610 			continue;
    611 		*pos++ = '\0';
    612 		val = strtoul(pos, NULL, 10);
    613 		if (strcmp(line, "rx_packets") == 0)
    614 			data->rx_packets = val;
    615 		else if (strcmp(line, "tx_packets") == 0)
    616 			data->tx_packets = val;
    617 		else if (strcmp(line, "rx_bytes") == 0)
    618 			data->rx_bytes = val;
    619 		else if (strcmp(line, "tx_bytes") == 0)
    620 			data->tx_bytes = val;
    621 	}
    622 
    623 	fclose(f);
    624 
    625 	return 0;
    626 #endif /* MADWIFI_BSD */
    627 }
    628 
    629 
    630 static int
    631 madwifi_sta_clear_stats(void *priv, const u8 *addr)
    632 {
    633 #if defined(MADWIFI_BSD) && defined(IEEE80211_MLME_CLEAR_STATS)
    634 	struct madwifi_driver_data *drv = priv;
    635 	struct ieee80211req_mlme mlme;
    636 	int ret;
    637 
    638 	wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr));
    639 
    640 	mlme.im_op = IEEE80211_MLME_CLEAR_STATS;
    641 	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
    642 	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
    643 			   sizeof(mlme));
    644 	if (ret < 0) {
    645 		wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr "
    646 			   MACSTR ")", __func__, MAC2STR(addr));
    647 	}
    648 
    649 	return ret;
    650 #else /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
    651 	return 0; /* FIX */
    652 #endif /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
    653 }
    654 
    655 
    656 static int
    657 madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
    658 {
    659 	/*
    660 	 * Do nothing; we setup parameters at startup that define the
    661 	 * contents of the beacon information element.
    662 	 */
    663 	return 0;
    664 }
    665 
    666 static int
    667 madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
    668 		   int reason_code)
    669 {
    670 	struct madwifi_driver_data *drv = priv;
    671 	struct ieee80211req_mlme mlme;
    672 	int ret;
    673 
    674 	wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
    675 		   __func__, ether_sprintf(addr), reason_code);
    676 
    677 	mlme.im_op = IEEE80211_MLME_DEAUTH;
    678 	mlme.im_reason = reason_code;
    679 	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
    680 	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
    681 	if (ret < 0) {
    682 		wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR
    683 			   " reason %d)",
    684 			   __func__, MAC2STR(addr), reason_code);
    685 	}
    686 
    687 	return ret;
    688 }
    689 
    690 static int
    691 madwifi_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
    692 		     int reason_code)
    693 {
    694 	struct madwifi_driver_data *drv = priv;
    695 	struct ieee80211req_mlme mlme;
    696 	int ret;
    697 
    698 	wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
    699 		   __func__, ether_sprintf(addr), reason_code);
    700 
    701 	mlme.im_op = IEEE80211_MLME_DISASSOC;
    702 	mlme.im_reason = reason_code;
    703 	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
    704 	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
    705 	if (ret < 0) {
    706 		wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr "
    707 			   MACSTR " reason %d)",
    708 			   __func__, MAC2STR(addr), reason_code);
    709 	}
    710 
    711 	return ret;
    712 }
    713 
    714 #ifdef CONFIG_WPS
    715 #ifdef IEEE80211_IOCTL_FILTERFRAME
    716 static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
    717 				size_t len)
    718 {
    719 	struct madwifi_driver_data *drv = ctx;
    720 	const struct ieee80211_mgmt *mgmt;
    721 	u16 fc;
    722 	union wpa_event_data event;
    723 
    724 	/* Send Probe Request information to WPS processing */
    725 
    726 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
    727 		return;
    728 	mgmt = (const struct ieee80211_mgmt *) buf;
    729 
    730 	fc = le_to_host16(mgmt->frame_control);
    731 	if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
    732 	    WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ)
    733 		return;
    734 
    735 	os_memset(&event, 0, sizeof(event));
    736 	event.rx_probe_req.sa = mgmt->sa;
    737 	event.rx_probe_req.ie = mgmt->u.probe_req.variable;
    738 	event.rx_probe_req.ie_len =
    739 		len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
    740 	wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event);
    741 }
    742 #endif /* IEEE80211_IOCTL_FILTERFRAME */
    743 #endif /* CONFIG_WPS */
    744 
    745 static int madwifi_receive_probe_req(struct madwifi_driver_data *drv)
    746 {
    747 	int ret = 0;
    748 #ifdef CONFIG_WPS
    749 #ifdef IEEE80211_IOCTL_FILTERFRAME
    750 	struct ieee80211req_set_filter filt;
    751 
    752 	wpa_printf(MSG_DEBUG, "%s Enter", __func__);
    753 	filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ;
    754 
    755 	ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
    756 			   sizeof(struct ieee80211req_set_filter));
    757 	if (ret)
    758 		return ret;
    759 
    760 	drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW,
    761 				       madwifi_raw_receive, drv, 1);
    762 	if (drv->sock_raw == NULL)
    763 		return -1;
    764 #endif /* IEEE80211_IOCTL_FILTERFRAME */
    765 #endif /* CONFIG_WPS */
    766 	return ret;
    767 }
    768 
    769 #ifdef CONFIG_WPS
    770 static int
    771 madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
    772 {
    773 	struct madwifi_driver_data *drv = priv;
    774 	u8 buf[256];
    775 	struct ieee80211req_getset_appiebuf *beac_ie;
    776 
    777 	wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__,
    778 		   (unsigned long) len);
    779 
    780 	beac_ie = (struct ieee80211req_getset_appiebuf *) buf;
    781 	beac_ie->app_frmtype = frametype;
    782 	beac_ie->app_buflen = len;
    783 	memcpy(&(beac_ie->app_buf[0]), ie, len);
    784 
    785 	return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie,
    786 			    sizeof(struct ieee80211req_getset_appiebuf) + len);
    787 }
    788 
    789 static int
    790 madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
    791 		      const struct wpabuf *proberesp,
    792 		      const struct wpabuf *assocresp)
    793 {
    794 	if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
    795 			       beacon ? wpabuf_len(beacon) : 0,
    796 			       IEEE80211_APPIE_FRAME_BEACON) < 0)
    797 		return -1;
    798 	return madwifi_set_wps_ie(priv,
    799 				  proberesp ? wpabuf_head(proberesp) : NULL,
    800 				  proberesp ? wpabuf_len(proberesp) : 0,
    801 				  IEEE80211_APPIE_FRAME_PROBE_RESP);
    802 }
    803 #else /* CONFIG_WPS */
    804 #define madwifi_set_ap_wps_ie NULL
    805 #endif /* CONFIG_WPS */
    806 
    807 static void
    808 madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
    809 {
    810 	struct hostapd_data *hapd = drv->hapd;
    811 	struct ieee80211req_wpaie ie;
    812 	int ielen = 0;
    813 	u8 *iebuf = NULL;
    814 
    815 	/*
    816 	 * Fetch negotiated WPA/RSN parameters from the system.
    817 	 */
    818 	memset(&ie, 0, sizeof(ie));
    819 	memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
    820 	if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {
    821 		wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE",
    822 			   __func__);
    823 		goto no_ie;
    824 	}
    825 	wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE",
    826 		    ie.wpa_ie, IEEE80211_MAX_OPT_IE);
    827 	iebuf = ie.wpa_ie;
    828 	/* madwifi seems to return some random data if WPA/RSN IE is not set.
    829 	 * Assume the IE was not included if the IE type is unknown. */
    830 	if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)
    831 		iebuf[1] = 0;
    832 #ifdef MADWIFI_NG
    833 	wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE",
    834 		    ie.rsn_ie, IEEE80211_MAX_OPT_IE);
    835 	if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {
    836 		/* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
    837 		 * set. This is needed for WPA2. */
    838 		iebuf = ie.rsn_ie;
    839 		if (iebuf[0] != WLAN_EID_RSN)
    840 			iebuf[1] = 0;
    841 	}
    842 #endif /* MADWIFI_NG */
    843 
    844 	ielen = iebuf[1];
    845 	if (ielen == 0)
    846 		iebuf = NULL;
    847 	else
    848 		ielen += 2;
    849 
    850 no_ie:
    851 	drv_event_assoc(hapd, addr, iebuf, ielen, 0);
    852 
    853 	if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
    854 		/* Cached accounting data is not valid anymore. */
    855 		memset(drv->acct_mac, 0, ETH_ALEN);
    856 		memset(&drv->acct_data, 0, sizeof(drv->acct_data));
    857 	}
    858 }
    859 
    860 static void
    861 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,
    862 				       char *custom)
    863 {
    864 	wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
    865 
    866 	if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
    867 		char *pos;
    868 		u8 addr[ETH_ALEN];
    869 		pos = strstr(custom, "addr=");
    870 		if (pos == NULL) {
    871 			wpa_printf(MSG_DEBUG,
    872 				   "MLME-MICHAELMICFAILURE.indication "
    873 				   "without sender address ignored");
    874 			return;
    875 		}
    876 		pos += 5;
    877 		if (hwaddr_aton(pos, addr) == 0) {
    878 			union wpa_event_data data;
    879 			os_memset(&data, 0, sizeof(data));
    880 			data.michael_mic_failure.unicast = 1;
    881 			data.michael_mic_failure.src = addr;
    882 			wpa_supplicant_event(drv->hapd,
    883 					     EVENT_MICHAEL_MIC_FAILURE, &data);
    884 		} else {
    885 			wpa_printf(MSG_DEBUG,
    886 				   "MLME-MICHAELMICFAILURE.indication "
    887 				   "with invalid MAC address");
    888 		}
    889 	} else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) {
    890 		char *key, *value;
    891 		u32 val;
    892 		key = custom;
    893 		while ((key = strchr(key, '\n')) != NULL) {
    894 			key++;
    895 			value = strchr(key, '=');
    896 			if (value == NULL)
    897 				continue;
    898 			*value++ = '\0';
    899 			val = strtoul(value, NULL, 10);
    900 			if (strcmp(key, "mac") == 0)
    901 				hwaddr_aton(value, drv->acct_mac);
    902 			else if (strcmp(key, "rx_packets") == 0)
    903 				drv->acct_data.rx_packets = val;
    904 			else if (strcmp(key, "tx_packets") == 0)
    905 				drv->acct_data.tx_packets = val;
    906 			else if (strcmp(key, "rx_bytes") == 0)
    907 				drv->acct_data.rx_bytes = val;
    908 			else if (strcmp(key, "tx_bytes") == 0)
    909 				drv->acct_data.tx_bytes = val;
    910 			key = value;
    911 		}
    912 	}
    913 }
    914 
    915 static void
    916 madwifi_wireless_event_wireless(struct madwifi_driver_data *drv,
    917 					    char *data, int len)
    918 {
    919 	struct iw_event iwe_buf, *iwe = &iwe_buf;
    920 	char *pos, *end, *custom, *buf;
    921 
    922 	pos = data;
    923 	end = data + len;
    924 
    925 	while (pos + IW_EV_LCP_LEN <= end) {
    926 		/* Event data may be unaligned, so make a local, aligned copy
    927 		 * before processing. */
    928 		memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
    929 		wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d",
    930 			   iwe->cmd, iwe->len);
    931 		if (iwe->len <= IW_EV_LCP_LEN)
    932 			return;
    933 
    934 		custom = pos + IW_EV_POINT_LEN;
    935 		if (drv->we_version > 18 &&
    936 		    (iwe->cmd == IWEVMICHAELMICFAILURE ||
    937 		     iwe->cmd == IWEVCUSTOM)) {
    938 			/* WE-19 removed the pointer from struct iw_point */
    939 			char *dpos = (char *) &iwe_buf.u.data.length;
    940 			int dlen = dpos - (char *) &iwe_buf;
    941 			memcpy(dpos, pos + IW_EV_LCP_LEN,
    942 			       sizeof(struct iw_event) - dlen);
    943 		} else {
    944 			memcpy(&iwe_buf, pos, sizeof(struct iw_event));
    945 			custom += IW_EV_POINT_OFF;
    946 		}
    947 
    948 		switch (iwe->cmd) {
    949 		case IWEVEXPIRED:
    950 			drv_event_disassoc(drv->hapd,
    951 					   (u8 *) iwe->u.addr.sa_data);
    952 			break;
    953 		case IWEVREGISTERED:
    954 			madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data);
    955 			break;
    956 		case IWEVCUSTOM:
    957 			if (custom + iwe->u.data.length > end)
    958 				return;
    959 			buf = malloc(iwe->u.data.length + 1);
    960 			if (buf == NULL)
    961 				return;		/* XXX */
    962 			memcpy(buf, custom, iwe->u.data.length);
    963 			buf[iwe->u.data.length] = '\0';
    964 			madwifi_wireless_event_wireless_custom(drv, buf);
    965 			free(buf);
    966 			break;
    967 		}
    968 
    969 		pos += iwe->len;
    970 	}
    971 }
    972 
    973 
    974 static void
    975 madwifi_wireless_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
    976 				   u8 *buf, size_t len)
    977 {
    978 	struct madwifi_driver_data *drv = ctx;
    979 	int attrlen, rta_len;
    980 	struct rtattr *attr;
    981 
    982 	if (ifi->ifi_index != drv->ifindex)
    983 		return;
    984 
    985 	attrlen = len;
    986 	attr = (struct rtattr *) buf;
    987 
    988 	rta_len = RTA_ALIGN(sizeof(struct rtattr));
    989 	while (RTA_OK(attr, attrlen)) {
    990 		if (attr->rta_type == IFLA_WIRELESS) {
    991 			madwifi_wireless_event_wireless(
    992 				drv, ((char *) attr) + rta_len,
    993 				attr->rta_len - rta_len);
    994 		}
    995 		attr = RTA_NEXT(attr, attrlen);
    996 	}
    997 }
    998 
    999 
   1000 static int
   1001 madwifi_get_we_version(struct madwifi_driver_data *drv)
   1002 {
   1003 	struct iw_range *range;
   1004 	struct iwreq iwr;
   1005 	int minlen;
   1006 	size_t buflen;
   1007 
   1008 	drv->we_version = 0;
   1009 
   1010 	/*
   1011 	 * Use larger buffer than struct iw_range in order to allow the
   1012 	 * structure to grow in the future.
   1013 	 */
   1014 	buflen = sizeof(struct iw_range) + 500;
   1015 	range = os_zalloc(buflen);
   1016 	if (range == NULL)
   1017 		return -1;
   1018 
   1019 	memset(&iwr, 0, sizeof(iwr));
   1020 	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
   1021 	iwr.u.data.pointer = (caddr_t) range;
   1022 	iwr.u.data.length = buflen;
   1023 
   1024 	minlen = ((char *) &range->enc_capa) - (char *) range +
   1025 		sizeof(range->enc_capa);
   1026 
   1027 	if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
   1028 		perror("ioctl[SIOCGIWRANGE]");
   1029 		free(range);
   1030 		return -1;
   1031 	} else if (iwr.u.data.length >= minlen &&
   1032 		   range->we_version_compiled >= 18) {
   1033 		wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
   1034 			   "WE(source)=%d enc_capa=0x%x",
   1035 			   range->we_version_compiled,
   1036 			   range->we_version_source,
   1037 			   range->enc_capa);
   1038 		drv->we_version = range->we_version_compiled;
   1039 	}
   1040 
   1041 	free(range);
   1042 	return 0;
   1043 }
   1044 
   1045 
   1046 static int
   1047 madwifi_wireless_event_init(struct madwifi_driver_data *drv)
   1048 {
   1049 	struct netlink_config *cfg;
   1050 
   1051 	madwifi_get_we_version(drv);
   1052 
   1053 	cfg = os_zalloc(sizeof(*cfg));
   1054 	if (cfg == NULL)
   1055 		return -1;
   1056 	cfg->ctx = drv;
   1057 	cfg->newlink_cb = madwifi_wireless_event_rtm_newlink;
   1058 	drv->netlink = netlink_init(cfg);
   1059 	if (drv->netlink == NULL) {
   1060 		os_free(cfg);
   1061 		return -1;
   1062 	}
   1063 
   1064 	return 0;
   1065 }
   1066 
   1067 
   1068 static int
   1069 madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
   1070 		   int encrypt, const u8 *own_addr, u32 flags)
   1071 {
   1072 	struct madwifi_driver_data *drv = priv;
   1073 	unsigned char buf[3000];
   1074 	unsigned char *bp = buf;
   1075 	struct l2_ethhdr *eth;
   1076 	size_t len;
   1077 	int status;
   1078 
   1079 	/*
   1080 	 * Prepend the Ethernet header.  If the caller left us
   1081 	 * space at the front we could just insert it but since
   1082 	 * we don't know we copy to a local buffer.  Given the frequency
   1083 	 * and size of frames this probably doesn't matter.
   1084 	 */
   1085 	len = data_len + sizeof(struct l2_ethhdr);
   1086 	if (len > sizeof(buf)) {
   1087 		bp = malloc(len);
   1088 		if (bp == NULL) {
   1089 			printf("EAPOL frame discarded, cannot malloc temp "
   1090 			       "buffer of size %lu!\n", (unsigned long) len);
   1091 			return -1;
   1092 		}
   1093 	}
   1094 	eth = (struct l2_ethhdr *) bp;
   1095 	memcpy(eth->h_dest, addr, ETH_ALEN);
   1096 	memcpy(eth->h_source, own_addr, ETH_ALEN);
   1097 	eth->h_proto = host_to_be16(ETH_P_EAPOL);
   1098 	memcpy(eth+1, data, data_len);
   1099 
   1100 	wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
   1101 
   1102 	status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
   1103 
   1104 	if (bp != buf)
   1105 		free(bp);
   1106 	return status;
   1107 }
   1108 
   1109 static void
   1110 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
   1111 {
   1112 	struct madwifi_driver_data *drv = ctx;
   1113 	drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr),
   1114 			   len - sizeof(struct l2_ethhdr));
   1115 }
   1116 
   1117 static void *
   1118 madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params)
   1119 {
   1120 	struct madwifi_driver_data *drv;
   1121 	struct ifreq ifr;
   1122 	struct iwreq iwr;
   1123 	char brname[IFNAMSIZ];
   1124 
   1125 	drv = os_zalloc(sizeof(struct madwifi_driver_data));
   1126 	if (drv == NULL) {
   1127 		printf("Could not allocate memory for madwifi driver data\n");
   1128 		return NULL;
   1129 	}
   1130 
   1131 	drv->hapd = hapd;
   1132 	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
   1133 	if (drv->ioctl_sock < 0) {
   1134 		perror("socket[PF_INET,SOCK_DGRAM]");
   1135 		goto bad;
   1136 	}
   1137 	memcpy(drv->iface, params->ifname, sizeof(drv->iface));
   1138 
   1139 	memset(&ifr, 0, sizeof(ifr));
   1140 	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
   1141 	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
   1142 		perror("ioctl(SIOCGIFINDEX)");
   1143 		goto bad;
   1144 	}
   1145 	drv->ifindex = ifr.ifr_ifindex;
   1146 
   1147 	drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
   1148 					handle_read, drv, 1);
   1149 	if (drv->sock_xmit == NULL)
   1150 		goto bad;
   1151 	if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
   1152 		goto bad;
   1153 	if (params->bridge[0]) {
   1154 		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
   1155 			   params->bridge[0]);
   1156 		drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
   1157 						ETH_P_EAPOL, handle_read, drv,
   1158 						1);
   1159 		if (drv->sock_recv == NULL)
   1160 			goto bad;
   1161 	} else if (linux_br_get(brname, drv->iface) == 0) {
   1162 		wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
   1163 			   "EAPOL receive", brname);
   1164 		drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
   1165 						handle_read, drv, 1);
   1166 		if (drv->sock_recv == NULL)
   1167 			goto bad;
   1168 	} else
   1169 		drv->sock_recv = drv->sock_xmit;
   1170 
   1171 	memset(&iwr, 0, sizeof(iwr));
   1172 	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
   1173 
   1174 	iwr.u.mode = IW_MODE_MASTER;
   1175 
   1176 	if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
   1177 		perror("ioctl[SIOCSIWMODE]");
   1178 		printf("Could not set interface to master mode!\n");
   1179 		goto bad;
   1180 	}
   1181 
   1182 	/* mark down during setup */
   1183 	linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
   1184 	madwifi_set_privacy(drv, 0); /* default to no privacy */
   1185 
   1186 	madwifi_receive_probe_req(drv);
   1187 
   1188 	if (madwifi_wireless_event_init(drv))
   1189 		goto bad;
   1190 
   1191 	return drv;
   1192 bad:
   1193 	if (drv->sock_xmit != NULL)
   1194 		l2_packet_deinit(drv->sock_xmit);
   1195 	if (drv->ioctl_sock >= 0)
   1196 		close(drv->ioctl_sock);
   1197 	if (drv != NULL)
   1198 		free(drv);
   1199 	return NULL;
   1200 }
   1201 
   1202 
   1203 static void
   1204 madwifi_deinit(void *priv)
   1205 {
   1206 	struct madwifi_driver_data *drv = priv;
   1207 
   1208 	netlink_deinit(drv->netlink);
   1209 	(void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
   1210 	if (drv->ioctl_sock >= 0)
   1211 		close(drv->ioctl_sock);
   1212 	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
   1213 		l2_packet_deinit(drv->sock_recv);
   1214 	if (drv->sock_xmit != NULL)
   1215 		l2_packet_deinit(drv->sock_xmit);
   1216 	if (drv->sock_raw)
   1217 		l2_packet_deinit(drv->sock_raw);
   1218 	free(drv);
   1219 }
   1220 
   1221 static int
   1222 madwifi_set_ssid(void *priv, const u8 *buf, int len)
   1223 {
   1224 	struct madwifi_driver_data *drv = priv;
   1225 	struct iwreq iwr;
   1226 
   1227 	memset(&iwr, 0, sizeof(iwr));
   1228 	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
   1229 	iwr.u.essid.flags = 1; /* SSID active */
   1230 	iwr.u.essid.pointer = (caddr_t) buf;
   1231 	iwr.u.essid.length = len + 1;
   1232 
   1233 	if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
   1234 		perror("ioctl[SIOCSIWESSID]");
   1235 		printf("len=%d\n", len);
   1236 		return -1;
   1237 	}
   1238 	return 0;
   1239 }
   1240 
   1241 static int
   1242 madwifi_get_ssid(void *priv, u8 *buf, int len)
   1243 {
   1244 	struct madwifi_driver_data *drv = priv;
   1245 	struct iwreq iwr;
   1246 	int ret = 0;
   1247 
   1248 	memset(&iwr, 0, sizeof(iwr));
   1249 	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
   1250 	iwr.u.essid.pointer = (caddr_t) buf;
   1251 	iwr.u.essid.length = len;
   1252 
   1253 	if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
   1254 		perror("ioctl[SIOCGIWESSID]");
   1255 		ret = -1;
   1256 	} else
   1257 		ret = iwr.u.essid.length;
   1258 
   1259 	return ret;
   1260 }
   1261 
   1262 static int
   1263 madwifi_set_countermeasures(void *priv, int enabled)
   1264 {
   1265 	struct madwifi_driver_data *drv = priv;
   1266 	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
   1267 	return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled);
   1268 }
   1269 
   1270 static int
   1271 madwifi_commit(void *priv)
   1272 {
   1273 	struct madwifi_driver_data *drv = priv;
   1274 	return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
   1275 }
   1276 
   1277 #else /* HOSTAPD */
   1278 
   1279 struct wpa_driver_madwifi_data {
   1280 	void *wext; /* private data for driver_wext */
   1281 	void *ctx;
   1282 	char ifname[IFNAMSIZ + 1];
   1283 	int sock;
   1284 };
   1285 
   1286 static int wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg);
   1287 static int wpa_driver_madwifi_set_probe_req_ie(void *priv, const u8 *ies,
   1288 					       size_t ies_len);
   1289 
   1290 
   1291 static int
   1292 set80211priv(struct wpa_driver_madwifi_data *drv, int op, void *data, int len,
   1293 	     int show_err)
   1294 {
   1295 	struct iwreq iwr;
   1296 
   1297 	os_memset(&iwr, 0, sizeof(iwr));
   1298 	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
   1299 	if (len < IFNAMSIZ &&
   1300 	    op != IEEE80211_IOCTL_SET_APPIEBUF) {
   1301 		/*
   1302 		 * Argument data fits inline; put it there.
   1303 		 */
   1304 		os_memcpy(iwr.u.name, data, len);
   1305 	} else {
   1306 		/*
   1307 		 * Argument data too big for inline transfer; setup a
   1308 		 * parameter block instead; the kernel will transfer
   1309 		 * the data for the driver.
   1310 		 */
   1311 		iwr.u.data.pointer = data;
   1312 		iwr.u.data.length = len;
   1313 	}
   1314 
   1315 	if (ioctl(drv->sock, op, &iwr) < 0) {
   1316 		if (show_err) {
   1317 #ifdef MADWIFI_NG
   1318 			int first = IEEE80211_IOCTL_SETPARAM;
   1319 			int last = IEEE80211_IOCTL_KICKMAC;
   1320 			static const char *opnames[] = {
   1321 				"ioctl[IEEE80211_IOCTL_SETPARAM]",
   1322 				"ioctl[IEEE80211_IOCTL_GETPARAM]",
   1323 				"ioctl[IEEE80211_IOCTL_SETMODE]",
   1324 				"ioctl[IEEE80211_IOCTL_GETMODE]",
   1325 				"ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
   1326 				"ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
   1327 				"ioctl[IEEE80211_IOCTL_SETCHANLIST]",
   1328 				"ioctl[IEEE80211_IOCTL_GETCHANLIST]",
   1329 				"ioctl[IEEE80211_IOCTL_CHANSWITCH]",
   1330 				NULL,
   1331 				"ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
   1332 				"ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
   1333 				NULL,
   1334 				"ioctl[IEEE80211_IOCTL_GETCHANINFO]",
   1335 				"ioctl[IEEE80211_IOCTL_SETOPTIE]",
   1336 				"ioctl[IEEE80211_IOCTL_GETOPTIE]",
   1337 				"ioctl[IEEE80211_IOCTL_SETMLME]",
   1338 				NULL,
   1339 				"ioctl[IEEE80211_IOCTL_SETKEY]",
   1340 				NULL,
   1341 				"ioctl[IEEE80211_IOCTL_DELKEY]",
   1342 				NULL,
   1343 				"ioctl[IEEE80211_IOCTL_ADDMAC]",
   1344 				NULL,
   1345 				"ioctl[IEEE80211_IOCTL_DELMAC]",
   1346 				NULL,
   1347 				"ioctl[IEEE80211_IOCTL_WDSMAC]",
   1348 				NULL,
   1349 				"ioctl[IEEE80211_IOCTL_WDSDELMAC]",
   1350 				NULL,
   1351 				"ioctl[IEEE80211_IOCTL_KICKMAC]",
   1352 			};
   1353 #else /* MADWIFI_NG */
   1354 			int first = IEEE80211_IOCTL_SETPARAM;
   1355 			int last = IEEE80211_IOCTL_CHANLIST;
   1356 			static const char *opnames[] = {
   1357 				"ioctl[IEEE80211_IOCTL_SETPARAM]",
   1358 				"ioctl[IEEE80211_IOCTL_GETPARAM]",
   1359 				"ioctl[IEEE80211_IOCTL_SETKEY]",
   1360 				"ioctl[IEEE80211_IOCTL_GETKEY]",
   1361 				"ioctl[IEEE80211_IOCTL_DELKEY]",
   1362 				NULL,
   1363 				"ioctl[IEEE80211_IOCTL_SETMLME]",
   1364 				NULL,
   1365 				"ioctl[IEEE80211_IOCTL_SETOPTIE]",
   1366 				"ioctl[IEEE80211_IOCTL_GETOPTIE]",
   1367 				"ioctl[IEEE80211_IOCTL_ADDMAC]",
   1368 				NULL,
   1369 				"ioctl[IEEE80211_IOCTL_DELMAC]",
   1370 				NULL,
   1371 				"ioctl[IEEE80211_IOCTL_CHANLIST]",
   1372 			};
   1373 #endif /* MADWIFI_NG */
   1374 			int idx = op - first;
   1375 			if (first <= op && op <= last &&
   1376 			    idx < (int) (sizeof(opnames) / sizeof(opnames[0]))
   1377 			    && opnames[idx])
   1378 				perror(opnames[idx]);
   1379 			else
   1380 				perror("ioctl[unknown???]");
   1381 		}
   1382 		return -1;
   1383 	}
   1384 	return 0;
   1385 }
   1386 
   1387 static int
   1388 set80211param(struct wpa_driver_madwifi_data *drv, int op, int arg,
   1389 	      int show_err)
   1390 {
   1391 	struct iwreq iwr;
   1392 
   1393 	os_memset(&iwr, 0, sizeof(iwr));
   1394 	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
   1395 	iwr.u.mode = op;
   1396 	os_memcpy(iwr.u.name+sizeof(u32), &arg, sizeof(arg));
   1397 
   1398 	if (ioctl(drv->sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
   1399 		if (show_err)
   1400 			perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
   1401 		return -1;
   1402 	}
   1403 	return 0;
   1404 }
   1405 
   1406 static int
   1407 wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data *drv,
   1408 			      const u8 *wpa_ie, size_t wpa_ie_len)
   1409 {
   1410 	struct iwreq iwr;
   1411 
   1412 	os_memset(&iwr, 0, sizeof(iwr));
   1413 	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
   1414 	/* NB: SETOPTIE is not fixed-size so must not be inlined */
   1415 	iwr.u.data.pointer = (void *) wpa_ie;
   1416 	iwr.u.data.length = wpa_ie_len;
   1417 
   1418 	if (ioctl(drv->sock, IEEE80211_IOCTL_SETOPTIE, &iwr) < 0) {
   1419 		perror("ioctl[IEEE80211_IOCTL_SETOPTIE]");
   1420 		return -1;
   1421 	}
   1422 	return 0;
   1423 }
   1424 
   1425 static int
   1426 wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data *drv, int key_idx,
   1427 			   const u8 *addr)
   1428 {
   1429 	struct ieee80211req_del_key wk;
   1430 
   1431 	wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __FUNCTION__, key_idx);
   1432 	os_memset(&wk, 0, sizeof(wk));
   1433 	wk.idk_keyix = key_idx;
   1434 	if (addr != NULL)
   1435 		os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
   1436 
   1437 	return set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk), 1);
   1438 }
   1439 
   1440 static int
   1441 wpa_driver_madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg,
   1442 			   const u8 *addr, int key_idx, int set_tx,
   1443 			   const u8 *seq, size_t seq_len,
   1444 			   const u8 *key, size_t key_len)
   1445 {
   1446 	struct wpa_driver_madwifi_data *drv = priv;
   1447 	struct ieee80211req_key wk;
   1448 	char *alg_name;
   1449 	u_int8_t cipher;
   1450 
   1451 	if (alg == WPA_ALG_NONE)
   1452 		return wpa_driver_madwifi_del_key(drv, key_idx, addr);
   1453 
   1454 	switch (alg) {
   1455 	case WPA_ALG_WEP:
   1456 		if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
   1457 					      ETH_ALEN) == 0) {
   1458 			/*
   1459 			 * madwifi did not seem to like static WEP key
   1460 			 * configuration with IEEE80211_IOCTL_SETKEY, so use
   1461 			 * Linux wireless extensions ioctl for this.
   1462 			 */
   1463 			return wpa_driver_wext_set_key(ifname, drv->wext, alg,
   1464 						       addr, key_idx, set_tx,
   1465 						       seq, seq_len,
   1466 						       key, key_len);
   1467 		}
   1468 		alg_name = "WEP";
   1469 		cipher = IEEE80211_CIPHER_WEP;
   1470 		break;
   1471 	case WPA_ALG_TKIP:
   1472 		alg_name = "TKIP";
   1473 		cipher = IEEE80211_CIPHER_TKIP;
   1474 		break;
   1475 	case WPA_ALG_CCMP:
   1476 		alg_name = "CCMP";
   1477 		cipher = IEEE80211_CIPHER_AES_CCM;
   1478 		break;
   1479 	default:
   1480 		wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
   1481 			__FUNCTION__, alg);
   1482 		return -1;
   1483 	}
   1484 
   1485 	wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
   1486 		   "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
   1487 		   (unsigned long) seq_len, (unsigned long) key_len);
   1488 
   1489 	if (seq_len > sizeof(u_int64_t)) {
   1490 		wpa_printf(MSG_DEBUG, "%s: seq_len %lu too big",
   1491 			   __FUNCTION__, (unsigned long) seq_len);
   1492 		return -2;
   1493 	}
   1494 	if (key_len > sizeof(wk.ik_keydata)) {
   1495 		wpa_printf(MSG_DEBUG, "%s: key length %lu too big",
   1496 			   __FUNCTION__, (unsigned long) key_len);
   1497 		return -3;
   1498 	}
   1499 
   1500 	os_memset(&wk, 0, sizeof(wk));
   1501 	wk.ik_type = cipher;
   1502 	wk.ik_flags = IEEE80211_KEY_RECV;
   1503 	if (addr == NULL ||
   1504 	    os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
   1505 		wk.ik_flags |= IEEE80211_KEY_GROUP;
   1506 	if (set_tx) {
   1507 		wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT;
   1508 		os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
   1509 	} else
   1510 		os_memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN);
   1511 	wk.ik_keyix = key_idx;
   1512 	wk.ik_keylen = key_len;
   1513 #ifdef WORDS_BIGENDIAN
   1514 	if (seq) {
   1515 		size_t i;
   1516 		u8 tmp[WPA_KEY_RSC_LEN];
   1517 		os_memset(tmp, 0, sizeof(tmp));
   1518 		for (i = 0; i < seq_len; i++)
   1519 			tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i];
   1520 		os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN);
   1521 	}
   1522 #else /* WORDS_BIGENDIAN */
   1523 	if (seq)
   1524 		os_memcpy(&wk.ik_keyrsc, seq, seq_len);
   1525 #endif /* WORDS_BIGENDIAN */
   1526 	os_memcpy(wk.ik_keydata, key, key_len);
   1527 
   1528 	return set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk), 1);
   1529 }
   1530 
   1531 static int
   1532 wpa_driver_madwifi_set_countermeasures(void *priv, int enabled)
   1533 {
   1534 	struct wpa_driver_madwifi_data *drv = priv;
   1535 	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
   1536 	return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled, 1);
   1537 }
   1538 
   1539 static int
   1540 wpa_driver_madwifi_deauthenticate(void *priv, const u8 *addr, int reason_code)
   1541 {
   1542 	struct wpa_driver_madwifi_data *drv = priv;
   1543 	struct ieee80211req_mlme mlme;
   1544 
   1545 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
   1546 	mlme.im_op = IEEE80211_MLME_DEAUTH;
   1547 	mlme.im_reason = reason_code;
   1548 	os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
   1549 	return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1);
   1550 }
   1551 
   1552 static int
   1553 wpa_driver_madwifi_disassociate(void *priv, const u8 *addr, int reason_code)
   1554 {
   1555 	struct wpa_driver_madwifi_data *drv = priv;
   1556 	struct ieee80211req_mlme mlme;
   1557 
   1558 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
   1559 	mlme.im_op = IEEE80211_MLME_DISASSOC;
   1560 	mlme.im_reason = reason_code;
   1561 	os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
   1562 	return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1);
   1563 }
   1564 
   1565 static int
   1566 wpa_driver_madwifi_associate(void *priv,
   1567 			     struct wpa_driver_associate_params *params)
   1568 {
   1569 	struct wpa_driver_madwifi_data *drv = priv;
   1570 	struct ieee80211req_mlme mlme;
   1571 	int ret = 0, privacy = 1;
   1572 
   1573 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
   1574 
   1575 	if (set80211param(drv, IEEE80211_PARAM_DROPUNENCRYPTED,
   1576 			  params->drop_unencrypted, 1) < 0)
   1577 		ret = -1;
   1578 	if (wpa_driver_madwifi_set_auth_alg(drv, params->auth_alg) < 0)
   1579 		ret = -1;
   1580 
   1581 	/*
   1582 	 * NB: Don't need to set the freq or cipher-related state as
   1583 	 *     this is implied by the bssid which is used to locate
   1584 	 *     the scanned node state which holds it.  The ssid is
   1585 	 *     needed to disambiguate an AP that broadcasts multiple
   1586 	 *     ssid's but uses the same bssid.
   1587 	 */
   1588 	/* XXX error handling is wrong but unclear what to do... */
   1589 	if (wpa_driver_madwifi_set_wpa_ie(drv, params->wpa_ie,
   1590 					  params->wpa_ie_len) < 0)
   1591 		ret = -1;
   1592 
   1593 	if (params->pairwise_suite == CIPHER_NONE &&
   1594 	    params->group_suite == CIPHER_NONE &&
   1595 	    params->key_mgmt_suite == KEY_MGMT_NONE &&
   1596 	    params->wpa_ie_len == 0)
   1597 		privacy = 0;
   1598 
   1599 	if (set80211param(drv, IEEE80211_PARAM_PRIVACY, privacy, 1) < 0)
   1600 		ret = -1;
   1601 
   1602 	if (params->wpa_ie_len &&
   1603 	    set80211param(drv, IEEE80211_PARAM_WPA,
   1604 			  params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1, 1) < 0)
   1605 		ret = -1;
   1606 
   1607 	if (params->bssid == NULL) {
   1608 		/* ap_scan=2 mode - driver takes care of AP selection and
   1609 		 * roaming */
   1610 		/* FIX: this does not seem to work; would probably need to
   1611 		 * change something in the driver */
   1612 		if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0)
   1613 			ret = -1;
   1614 
   1615 		if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
   1616 					     params->ssid_len) < 0)
   1617 			ret = -1;
   1618 	} else {
   1619 		if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0)
   1620 			ret = -1;
   1621 		if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
   1622 					     params->ssid_len) < 0)
   1623 			ret = -1;
   1624 		os_memset(&mlme, 0, sizeof(mlme));
   1625 		mlme.im_op = IEEE80211_MLME_ASSOC;
   1626 		os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
   1627 		if (set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
   1628 				 sizeof(mlme), 1) < 0) {
   1629 			wpa_printf(MSG_DEBUG, "%s: SETMLME[ASSOC] failed",
   1630 				   __func__);
   1631 			ret = -1;
   1632 		}
   1633 	}
   1634 
   1635 	return ret;
   1636 }
   1637 
   1638 static int
   1639 wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg)
   1640 {
   1641 	struct wpa_driver_madwifi_data *drv = priv;
   1642 	int authmode;
   1643 
   1644 	if ((auth_alg & WPA_AUTH_ALG_OPEN) &&
   1645 	    (auth_alg & WPA_AUTH_ALG_SHARED))
   1646 		authmode = IEEE80211_AUTH_AUTO;
   1647 	else if (auth_alg & WPA_AUTH_ALG_SHARED)
   1648 		authmode = IEEE80211_AUTH_SHARED;
   1649 	else
   1650 		authmode = IEEE80211_AUTH_OPEN;
   1651 
   1652 	return set80211param(drv, IEEE80211_PARAM_AUTHMODE, authmode, 1);
   1653 }
   1654 
   1655 static int
   1656 wpa_driver_madwifi_scan(void *priv, struct wpa_driver_scan_params *params)
   1657 {
   1658 	struct wpa_driver_madwifi_data *drv = priv;
   1659 	struct iwreq iwr;
   1660 	int ret = 0;
   1661 	const u8 *ssid = params->ssids[0].ssid;
   1662 	size_t ssid_len = params->ssids[0].ssid_len;
   1663 
   1664 	wpa_driver_madwifi_set_probe_req_ie(drv, params->extra_ies,
   1665 					    params->extra_ies_len);
   1666 
   1667 	os_memset(&iwr, 0, sizeof(iwr));
   1668 	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
   1669 
   1670 	/* set desired ssid before scan */
   1671 	/* FIX: scan should not break the current association, so using
   1672 	 * set_ssid may not be the best way of doing this.. */
   1673 	if (wpa_driver_wext_set_ssid(drv->wext, ssid, ssid_len) < 0)
   1674 		ret = -1;
   1675 
   1676 	if (ioctl(drv->sock, SIOCSIWSCAN, &iwr) < 0) {
   1677 		perror("ioctl[SIOCSIWSCAN]");
   1678 		ret = -1;
   1679 	}
   1680 
   1681 	/*
   1682 	 * madwifi delivers a scan complete event so no need to poll, but
   1683 	 * register a backup timeout anyway to make sure that we recover even
   1684 	 * if the driver does not send this event for any reason. This timeout
   1685 	 * will only be used if the event is not delivered (event handler will
   1686 	 * cancel the timeout).
   1687 	 */
   1688 	eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext,
   1689 			     drv->ctx);
   1690 	eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout, drv->wext,
   1691 			       drv->ctx);
   1692 
   1693 	return ret;
   1694 }
   1695 
   1696 static int wpa_driver_madwifi_get_bssid(void *priv, u8 *bssid)
   1697 {
   1698 	struct wpa_driver_madwifi_data *drv = priv;
   1699 	return wpa_driver_wext_get_bssid(drv->wext, bssid);
   1700 }
   1701 
   1702 
   1703 static int wpa_driver_madwifi_get_ssid(void *priv, u8 *ssid)
   1704 {
   1705 	struct wpa_driver_madwifi_data *drv = priv;
   1706 	return wpa_driver_wext_get_ssid(drv->wext, ssid);
   1707 }
   1708 
   1709 
   1710 static struct wpa_scan_results *
   1711 wpa_driver_madwifi_get_scan_results(void *priv)
   1712 {
   1713 	struct wpa_driver_madwifi_data *drv = priv;
   1714 	return wpa_driver_wext_get_scan_results(drv->wext);
   1715 }
   1716 
   1717 
   1718 static int wpa_driver_madwifi_set_operstate(void *priv, int state)
   1719 {
   1720 	struct wpa_driver_madwifi_data *drv = priv;
   1721 	return wpa_driver_wext_set_operstate(drv->wext, state);
   1722 }
   1723 
   1724 
   1725 static int wpa_driver_madwifi_set_probe_req_ie(void *priv, const u8 *ies,
   1726 					       size_t ies_len)
   1727 {
   1728 	struct ieee80211req_getset_appiebuf *probe_req_ie;
   1729 	int ret;
   1730 
   1731 	probe_req_ie = os_malloc(sizeof(*probe_req_ie) + ies_len);
   1732 	if (probe_req_ie == NULL)
   1733 		return -1;
   1734 
   1735 	probe_req_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_REQ;
   1736 	probe_req_ie->app_buflen = ies_len;
   1737 	os_memcpy(probe_req_ie->app_buf, ies, ies_len);
   1738 
   1739 	ret = set80211priv(priv, IEEE80211_IOCTL_SET_APPIEBUF, probe_req_ie,
   1740 			   sizeof(struct ieee80211req_getset_appiebuf) +
   1741 			   ies_len, 1);
   1742 
   1743 	os_free(probe_req_ie);
   1744 
   1745 	return ret;
   1746 }
   1747 
   1748 
   1749 static void * wpa_driver_madwifi_init(void *ctx, const char *ifname)
   1750 {
   1751 	struct wpa_driver_madwifi_data *drv;
   1752 
   1753 	drv = os_zalloc(sizeof(*drv));
   1754 	if (drv == NULL)
   1755 		return NULL;
   1756 	drv->wext = wpa_driver_wext_init(ctx, ifname);
   1757 	if (drv->wext == NULL)
   1758 		goto fail;
   1759 
   1760 	drv->ctx = ctx;
   1761 	os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
   1762 	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
   1763 	if (drv->sock < 0)
   1764 		goto fail2;
   1765 
   1766 	if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) {
   1767 		wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "
   1768 			   "roaming", __FUNCTION__);
   1769 		goto fail3;
   1770 	}
   1771 
   1772 	if (set80211param(drv, IEEE80211_PARAM_WPA, 3, 1) < 0) {
   1773 		wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support",
   1774 			   __FUNCTION__);
   1775 		goto fail3;
   1776 	}
   1777 
   1778 	return drv;
   1779 
   1780 fail3:
   1781 	close(drv->sock);
   1782 fail2:
   1783 	wpa_driver_wext_deinit(drv->wext);
   1784 fail:
   1785 	os_free(drv);
   1786 	return NULL;
   1787 }
   1788 
   1789 
   1790 static void wpa_driver_madwifi_deinit(void *priv)
   1791 {
   1792 	struct wpa_driver_madwifi_data *drv = priv;
   1793 
   1794 	if (wpa_driver_madwifi_set_wpa_ie(drv, NULL, 0) < 0) {
   1795 		wpa_printf(MSG_DEBUG, "%s: failed to clear WPA IE",
   1796 			   __FUNCTION__);
   1797 	}
   1798 	if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) {
   1799 		wpa_printf(MSG_DEBUG, "%s: failed to enable driver-based "
   1800 			   "roaming", __FUNCTION__);
   1801 	}
   1802 	if (set80211param(drv, IEEE80211_PARAM_PRIVACY, 0, 1) < 0) {
   1803 		wpa_printf(MSG_DEBUG, "%s: failed to disable forced Privacy "
   1804 			   "flag", __FUNCTION__);
   1805 	}
   1806 	if (set80211param(drv, IEEE80211_PARAM_WPA, 0, 1) < 0) {
   1807 		wpa_printf(MSG_DEBUG, "%s: failed to disable WPA",
   1808 			   __FUNCTION__);
   1809 	}
   1810 
   1811 	wpa_driver_wext_deinit(drv->wext);
   1812 
   1813 	close(drv->sock);
   1814 	os_free(drv);
   1815 }
   1816 
   1817 #endif /* HOSTAPD */
   1818 
   1819 
   1820 const struct wpa_driver_ops wpa_driver_madwifi_ops = {
   1821 	.name			= "madwifi",
   1822 	.desc			= "MADWIFI 802.11 support (Atheros, etc.)",
   1823 	.set_key		= wpa_driver_madwifi_set_key,
   1824 #ifdef HOSTAPD
   1825 	.hapd_init		= madwifi_init,
   1826 	.hapd_deinit		= madwifi_deinit,
   1827 	.set_ieee8021x		= madwifi_set_ieee8021x,
   1828 	.set_privacy		= madwifi_set_privacy,
   1829 	.get_seqnum		= madwifi_get_seqnum,
   1830 	.flush			= madwifi_flush,
   1831 	.set_generic_elem	= madwifi_set_opt_ie,
   1832 	.sta_set_flags		= madwifi_sta_set_flags,
   1833 	.read_sta_data		= madwifi_read_sta_driver_data,
   1834 	.hapd_send_eapol	= madwifi_send_eapol,
   1835 	.sta_disassoc		= madwifi_sta_disassoc,
   1836 	.sta_deauth		= madwifi_sta_deauth,
   1837 	.hapd_set_ssid		= madwifi_set_ssid,
   1838 	.hapd_get_ssid		= madwifi_get_ssid,
   1839 	.hapd_set_countermeasures	= madwifi_set_countermeasures,
   1840 	.sta_clear_stats        = madwifi_sta_clear_stats,
   1841 	.commit			= madwifi_commit,
   1842 	.set_ap_wps_ie		= madwifi_set_ap_wps_ie,
   1843 #else /* HOSTAPD */
   1844 	.get_bssid		= wpa_driver_madwifi_get_bssid,
   1845 	.get_ssid		= wpa_driver_madwifi_get_ssid,
   1846 	.init			= wpa_driver_madwifi_init,
   1847 	.deinit			= wpa_driver_madwifi_deinit,
   1848 	.set_countermeasures	= wpa_driver_madwifi_set_countermeasures,
   1849 	.scan2			= wpa_driver_madwifi_scan,
   1850 	.get_scan_results2	= wpa_driver_madwifi_get_scan_results,
   1851 	.deauthenticate		= wpa_driver_madwifi_deauthenticate,
   1852 	.disassociate		= wpa_driver_madwifi_disassociate,
   1853 	.associate		= wpa_driver_madwifi_associate,
   1854 	.set_operstate		= wpa_driver_madwifi_set_operstate,
   1855 #endif /* HOSTAPD */
   1856 };
   1857