diff options
| author | nico <nico@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-11-22 03:10:56 +0000 | 
|---|---|---|
| committer | nico <nico@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-11-22 03:10:56 +0000 | 
| commit | c6df1caef5c56750808f4dd8f228f8ac2eafabf6 (patch) | |
| tree | 875ed0b3009163db4402e4c09906611fc6ccc88c /package/hostapd/patches | |
| parent | 6b9d65f68b0eeea27dfbebef48a4beeb0eb66766 (diff) | |
update hostapd to new upstream stable release (v0.4.7)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2542 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/hostapd/patches')
| -rw-r--r-- | package/hostapd/patches/002-madwifi.patch | 1278 | 
1 files changed, 0 insertions, 1278 deletions
| diff --git a/package/hostapd/patches/002-madwifi.patch b/package/hostapd/patches/002-madwifi.patch deleted file mode 100644 index f53ad7d89..000000000 --- a/package/hostapd/patches/002-madwifi.patch +++ /dev/null @@ -1,1278 +0,0 @@ -diff -ruN hostapd-0.4.5-old/driver_madwifi.c hostapd-0.4.5-new/driver_madwifi.c ---- hostapd-0.4.5-old/driver_madwifi.c	2005-10-23 14:52:39.000000000 +0200 -+++ hostapd-0.4.5-new/driver_madwifi.c	2005-10-23 15:09:45.000000000 +0200 -@@ -20,19 +20,20 @@ - #include <errno.h> - #include <sys/types.h> - #include <sys/socket.h> -+#include <linux/if.h> -+#include <stdint.h> -  - #include <include/compat.h> - #include <net80211/ieee80211.h> - #ifdef WME_NUM_AC - /* Assume this is built against BSD branch of madwifi driver. */ --#define MADWIFI_BSD - #include <net80211/_ieee80211.h> - #endif /* WME_NUM_AC */ - #include <net80211/ieee80211_crypto.h> - #include <net80211/ieee80211_ioctl.h> -  - #include <net/if_arp.h> --#include "wireless_copy.h" -+#include <wireless.h> -  - #include <netinet/in.h> - #include <netpacket/packet.h> -diff -ruN hostapd-0.4.5-old/driver_madwifi.~c hostapd-0.4.5-new/driver_madwifi.~c ---- hostapd-0.4.5-old/driver_madwifi.~c	1970-01-01 01:00:00.000000000 +0100 -+++ hostapd-0.4.5-new/driver_madwifi.~c	2005-10-23 15:06:20.000000000 +0200 -@@ -0,0 +1,1248 @@ -+/* -+ * Host AP - driver interaction with MADWIFI 802.11 driver -+ * Copyright (c) 2004, Sam Leffler <sam@errno.com> -+ * Copyright (c) 2004, Video54 Technologies -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Alternatively, this software may be distributed under the terms of BSD -+ * license. -+ * -+ * See README and COPYING for more details. -+ */ -+#include <stdlib.h> -+#include <stdio.h> -+#include <unistd.h> -+#include <string.h> -+#include <sys/ioctl.h> -+#include <errno.h> -+#include <sys/types.h> -+#include <sys/socket.h> -+ -+#include <include/compat.h> -+#include <net80211/ieee80211.h> -+#ifdef WME_NUM_AC -+/* Assume this is built against BSD branch of madwifi driver. */ -+#include <net80211/_ieee80211.h> -+#endif /* WME_NUM_AC */ -+#include <net80211/ieee80211_crypto.h> -+#include <net80211/ieee80211_ioctl.h> -+ -+#include <net/if_arp.h> -+#include <wireless.h> -+ -+#include <netinet/in.h> -+#include <netpacket/packet.h> -+ -+#include "hostapd.h" -+#include "driver.h" -+#include "ieee802_1x.h" -+#include "eloop.h" -+#include "priv_netlink.h" -+#include "sta_info.h" -+#include "l2_packet.h" -+#include "hostap_common.h" -+ -+#include "eapol_sm.h" -+#include "wpa.h" -+#include "radius.h" -+#include "ieee802_11.h" -+#include "accounting.h" -+#include "common.h" -+ -+ -+struct madwifi_driver_data { -+	struct driver_ops ops;			/* base class */ -+	struct hostapd_data *hapd;		/* back pointer */ -+ -+	char	iface[IFNAMSIZ + 1]; -+	int     ifindex; -+	struct l2_packet_data *sock_xmit;	/* raw packet xmit socket */ -+	struct l2_packet_data *sock_recv;	/* raw packet recv socket */ -+	int	ioctl_sock;			/* socket for ioctl() use */ -+	int	wext_sock;			/* socket for wireless events */ -+	int	we_version; -+	u8	acct_mac[ETH_ALEN]; -+	struct hostap_sta_driver_data acct_data; -+}; -+ -+static const struct driver_ops madwifi_driver_ops; -+ -+static int madwifi_sta_deauth(void *priv, u8 *addr, int reason_code); -+ -+static int -+set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) -+{ -+#define	N(a)	(sizeof(a)/sizeof(a[0])) -+	struct iwreq iwr; -+ -+	memset(&iwr, 0, sizeof(iwr)); -+	strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+	if (len < IFNAMSIZ) { -+		/* -+		 * Argument data fits inline; put it there. -+		 */ -+		memcpy(iwr.u.name, data, len); -+	} else { -+		/* -+		 * Argument data too big for inline transfer; setup a -+		 * parameter block instead; the kernel will transfer -+		 * the data for the driver. -+		 */ -+		iwr.u.data.pointer = data; -+		iwr.u.data.length = len; -+	} -+ -+	if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { -+		static const char *opnames[] = { -+			"ioctl[IEEE80211_IOCTL_SETPARAM]", -+			"ioctl[IEEE80211_IOCTL_GETPARAM]", -+			"ioctl[IEEE80211_IOCTL_SETKEY]", -+			"ioctl[SIOCIWFIRSTPRIV+3]", -+			"ioctl[IEEE80211_IOCTL_DELKEY]", -+			"ioctl[SIOCIWFIRSTPRIV+5]", -+			"ioctl[IEEE80211_IOCTL_SETMLME]", -+			"ioctl[SIOCIWFIRSTPRIV+7]", -+			"ioctl[IEEE80211_IOCTL_SETOPTIE]", -+			"ioctl[IEEE80211_IOCTL_GETOPTIE]", -+			"ioctl[IEEE80211_IOCTL_ADDMAC]", -+			"ioctl[SIOCIWFIRSTPRIV+11]", -+			"ioctl[IEEE80211_IOCTL_DELMAC]", -+			"ioctl[SIOCIWFIRSTPRIV+13]", -+			"ioctl[IEEE80211_IOCTL_CHANLIST]", -+			"ioctl[SIOCIWFIRSTPRIV+15]", -+			"ioctl[IEEE80211_IOCTL_GETRSN]", -+			"ioctl[SIOCIWFIRSTPRIV+17]", -+			"ioctl[IEEE80211_IOCTL_GETKEY]", -+		}; -+		op -= SIOCIWFIRSTPRIV; -+		if (0 <= op && op < N(opnames)) -+			perror(opnames[op]); -+		else -+			perror("ioctl[unknown???]"); -+		return -1; -+	} -+	return 0; -+#undef N -+} -+ -+static int -+set80211param(struct madwifi_driver_data *drv, int op, int arg) -+{ -+	struct iwreq iwr; -+ -+	memset(&iwr, 0, sizeof(iwr)); -+	strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+	iwr.u.mode = op; -+	memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); -+ -+	if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { -+		perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); -+		return -1; -+	} -+	return 0; -+} -+ -+static const char * -+ether_sprintf(const u8 *addr) -+{ -+	static char buf[sizeof(MACSTR)]; -+ -+	if (addr != NULL) -+		snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); -+	else -+		snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); -+	return buf; -+} -+ -+/* -+ * Configure WPA parameters. -+ */ -+static int -+madwifi_configure_wpa(struct madwifi_driver_data *drv) -+{ -+	hostapd *hapd = drv->hapd; -+	struct hostapd_config *conf = hapd->conf; -+	int v; -+ -+	switch (conf->wpa_group) { -+	case WPA_CIPHER_CCMP: -+		v = IEEE80211_CIPHER_AES_CCM; -+		break; -+	case WPA_CIPHER_TKIP: -+		v = IEEE80211_CIPHER_TKIP; -+		break; -+	case WPA_CIPHER_WEP104: -+		v = IEEE80211_CIPHER_WEP; -+		break; -+	case WPA_CIPHER_WEP40: -+		v = IEEE80211_CIPHER_WEP; -+		break; -+	case WPA_CIPHER_NONE: -+		v = IEEE80211_CIPHER_NONE; -+		break; -+	default: -+		printf("Unknown group key cipher %u\n", -+			conf->wpa_group); -+		return -1; -+	} -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: group key cipher=%d\n", __func__, v); -+	if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { -+		printf("Unable to set group key cipher to %u\n", v); -+		return -1; -+	} -+	if (v == IEEE80211_CIPHER_WEP) { -+		/* key length is done only for specific ciphers */ -+		v = (conf->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); -+		if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { -+			printf("Unable to set group key length to %u\n", v); -+			return -1; -+		} -+	} -+ -+	v = 0; -+	if (conf->wpa_pairwise & WPA_CIPHER_CCMP) -+		v |= 1<<IEEE80211_CIPHER_AES_CCM; -+	if (conf->wpa_pairwise & WPA_CIPHER_TKIP) -+		v |= 1<<IEEE80211_CIPHER_TKIP; -+	if (conf->wpa_pairwise & WPA_CIPHER_NONE) -+		v |= 1<<IEEE80211_CIPHER_NONE; -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: pairwise key ciphers=0x%x\n", __func__, v); -+	if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) { -+		printf("Unable to set pairwise key ciphers to 0x%x\n", v); -+		return -1; -+	} -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: key management algorithms=0x%x\n", -+		__func__, conf->wpa_key_mgmt); -+	if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, conf->wpa_key_mgmt)) { -+		printf("Unable to set key management algorithms to 0x%x\n", -+			conf->wpa_key_mgmt); -+		return -1; -+	} -+ -+	v = 0; -+	if (conf->rsn_preauth) -+		v |= BIT(0); -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: rsn capabilities=0x%x\n", __func__, conf->rsn_preauth); -+	if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { -+		printf("Unable to set RSN capabilities to 0x%x\n", v); -+		return -1; -+	} -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: enable WPA= 0x%x\n", __func__, conf->wpa); -+	if (set80211param(drv, IEEE80211_PARAM_WPA, conf->wpa)) { -+		printf("Unable to set WPA to %u\n", conf->wpa); -+		return -1; -+	} -+	return 0; -+} -+ -+ -+static int -+madwifi_set_iface_flags(void *priv, int dev_up) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct ifreq ifr; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, -+		"%s: dev_up=%d\n", __func__, dev_up); -+ -+	if (drv->ioctl_sock < 0) -+		return -1; -+ -+	memset(&ifr, 0, sizeof(ifr)); -+	snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); -+ -+	if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) { -+		perror("ioctl[SIOCGIFFLAGS]"); -+		return -1; -+	} -+ -+	if (dev_up) -+		ifr.ifr_flags |= IFF_UP; -+	else -+		ifr.ifr_flags &= ~IFF_UP; -+ -+	if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) { -+		perror("ioctl[SIOCSIFFLAGS]"); -+		return -1; -+	} -+ -+	if (dev_up) { -+		memset(&ifr, 0, sizeof(ifr)); -+		snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface); -+		ifr.ifr_mtu = HOSTAPD_MTU; -+		if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) { -+			perror("ioctl[SIOCSIFMTU]"); -+			printf("Setting MTU failed - trying to survive with " -+			       "current value\n"); -+		} -+	} -+ -+	return 0; -+} -+ -+static int -+madwifi_set_ieee8021x(void *priv, int enabled) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct hostapd_config *conf = hapd->conf; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, -+		"%s: enabled=%d\n", __func__, enabled); -+ -+	if (!enabled) { -+		/* XXX restore state */ -+		return set80211param(priv, IEEE80211_PARAM_AUTHMODE, -+			IEEE80211_AUTH_AUTO); -+	} -+	if (!conf->wpa && !conf->ieee802_1x) { -+		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, -+			HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); -+		return -1; -+	} -+	if (conf->wpa && madwifi_configure_wpa(drv) != 0) { -+		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, -+			HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); -+		return -1; -+	} -+	if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, -+		(conf->wpa ?  IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { -+		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, -+			HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); -+		return -1; -+	} -+	return madwifi_set_iface_flags(priv, 1); -+} -+ -+static int -+madwifi_set_privacy(void *priv, int enabled) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: enabled=%d\n", __func__, enabled); -+ -+	return set80211param(priv, IEEE80211_PARAM_PRIVACY, enabled); -+} -+ -+static int -+madwifi_set_sta_authorized(void *priv, u8 *addr, int authorized) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct ieee80211req_mlme mlme; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, -+		"%s: addr=%s authorized=%d\n", -+		__func__, ether_sprintf(addr), authorized); -+ -+	if (authorized) -+		mlme.im_op = IEEE80211_MLME_AUTHORIZE; -+	else -+		mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; -+	mlme.im_reason = 0; -+	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+	return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, -+			    sizeof(mlme)); -+} -+ -+static int -+madwifi_del_key(void *priv, unsigned char *addr, int key_idx) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct ieee80211req_del_key wk; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: addr=%s key_idx=%d\n", -+		__func__, ether_sprintf(addr), key_idx); -+ -+	memset(&wk, 0, sizeof(wk)); -+	if (addr != NULL) { -+		memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); -+		wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; -+	} else { -+		wk.idk_keyix = key_idx; -+	} -+ -+	return set80211priv(priv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); -+} -+ -+static int -+madwifi_set_key(void *priv, const char *alg, -+	     unsigned char *addr, int key_idx, -+	     u8 *key, size_t key_len) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct ieee80211req_key wk; -+	u_int8_t cipher; -+ -+	if (strcmp(alg, "none") == 0) -+		return madwifi_del_key(priv, addr, key_idx); -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: alg=%s addr=%s key_idx=%d\n", -+		__func__, alg, ether_sprintf(addr), key_idx); -+ -+	if (strcmp(alg, "WEP") == 0) -+		cipher = IEEE80211_CIPHER_WEP; -+	else if (strcmp(alg, "TKIP") == 0) -+		cipher = IEEE80211_CIPHER_TKIP; -+	else if (strcmp(alg, "CCMP") == 0) -+		cipher = IEEE80211_CIPHER_AES_CCM; -+	else { -+		printf("%s: unknown/unsupported algorithm %s\n", -+			__func__, alg); -+		return -1; -+	} -+ -+	if (key_len > sizeof(wk.ik_keydata)) { -+		printf("%s: key length %lu too big\n", __func__, -+		       (unsigned long) key_len); -+		return -3; -+	} -+ -+	memset(&wk, 0, sizeof(wk)); -+	wk.ik_type = cipher; -+	wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; -+	if (addr == NULL) { -+		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); -+		wk.ik_keyix = key_idx; -+		wk.ik_flags |= IEEE80211_KEY_DEFAULT; -+	} else { -+		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); -+		wk.ik_keyix = IEEE80211_KEYIX_NONE; -+	} -+	wk.ik_keylen = key_len; -+	memcpy(wk.ik_keydata, key, key_len); -+ -+	return set80211priv(priv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); -+} -+ -+ -+static int -+madwifi_get_seqnum(void *priv, u8 *addr, int idx, u8 *seq) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct ieee80211req_key wk; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: addr=%s idx=%d\n", __func__, ether_sprintf(addr), idx); -+ -+	memset(&wk, 0, sizeof(wk)); -+	if (addr == NULL) -+		memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); -+	else -+		memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); -+	wk.ik_keyix = idx; -+ -+	if (set80211priv(priv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { -+		printf("Failed to get encryption.\n"); -+		return -1; -+	} -+ -+#ifdef WORDS_BIGENDIAN -+	{ -+		/* -+		 * wk.ik_keytsc is in host byte order (big endian), need to -+		 * swap it to match with the byte order used in WPA. -+		 */ -+		int i; -+		u8 tmp[WPA_KEY_RSC_LEN]; -+		memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); -+		for (i = 0; i < WPA_KEY_RSC_LEN; i++) { -+			seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; -+		} -+	} -+#else /* WORDS_BIGENDIAN */ -+	memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); -+#endif /* WORDS_BIGENDIAN */ -+	return 0; -+} -+ -+ -+static int  -+madwifi_flush(void *priv) -+{ -+#ifdef MADWIFI_BSD -+	u8 allsta[IEEE80211_ADDR_LEN]; -+	memset(allsta, 0xff, IEEE80211_ADDR_LEN); -+	return madwifi_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE); -+#else /* MADWIFI_BSD */ -+	return 0;		/* XXX */ -+#endif /* MADWIFI_BSD */ -+} -+ -+ -+static int -+madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, -+					u8 *addr) -+{ -+	struct madwifi_driver_data *drv = priv; -+ -+#ifdef MADWIFI_BSD -+	struct ieee80211req_sta_stats stats; -+ -+	memset(data, 0, sizeof(*data)); -+ -+	/* -+	 * Fetch statistics for station from the system. -+	 */ -+	memset(&stats, 0, sizeof(stats)); -+	memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); -+	if (set80211priv(drv, IEEE80211_IOCTL_GETSTASTATS, &stats, -+			 sizeof(stats))) { -+		if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { -+			memcpy(data, &drv->acct_data, sizeof(*data)); -+			return 0; -+		} -+ -+		printf("Failed to get station stats information element.\n"); -+		return -1; -+	} -+ -+	data->rx_packets = stats.is_stats.ns_rx_data; -+	data->rx_bytes = stats.is_stats.ns_rx_bytes; -+	data->tx_packets = stats.is_stats.ns_tx_data; -+	data->tx_bytes = stats.is_stats.ns_tx_bytes; -+	return 0; -+ -+#else /* MADWIFI_BSD */ -+ -+	char buf[1024], line[128], *pos; -+	FILE *f; -+	unsigned long val; -+ -+	memset(data, 0, sizeof(*data)); -+	snprintf(buf, sizeof(buf), "/proc/net/madwifi/%s/" MACSTR, -+		 drv->iface, MAC2STR(addr)); -+ -+	f = fopen(buf, "r"); -+	if (!f) { -+		if (memcmp(addr, drv->acct_mac, ETH_ALEN) != 0) -+			return -1; -+		memcpy(data, &drv->acct_data, sizeof(*data)); -+		return 0; -+	} -+	/* Need to read proc file with in one piece, so use large enough -+	 * buffer. */ -+	setbuffer(f, buf, sizeof(buf)); -+ -+	while (fgets(line, sizeof(line), f)) { -+		pos = strchr(line, '='); -+		if (!pos) -+			continue; -+		*pos++ = '\0'; -+		val = strtoul(pos, NULL, 10); -+		if (strcmp(line, "rx_packets") == 0) -+			data->rx_packets = val; -+		else if (strcmp(line, "tx_packets") == 0) -+			data->tx_packets = val; -+		else if (strcmp(line, "rx_bytes") == 0) -+			data->rx_bytes = val; -+		else if (strcmp(line, "tx_bytes") == 0) -+			data->tx_bytes = val; -+	} -+ -+	fclose(f); -+ -+	return 0; -+#endif /* MADWIFI_BSD */ -+} -+ -+ -+static int -+madwifi_sta_clear_stats(void *priv, u8 *addr) -+{ -+#ifdef MADWIFI_BSD -+	struct madwifi_driver_data *drv = priv; -+	struct hostapd_data *hapd = drv->hapd; -+	struct ieee80211req_mlme mlme; -+	 -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: addr=%s\n", -+		      __func__, ether_sprintf(addr)); -+ -+	mlme.im_op = IEEE80211_MLME_CLEAR_STATS; -+	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+	return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, -+			    sizeof(mlme)); -+#else /* MADWIFI_BSD */ -+	return 0; /* FIX */ -+#endif /* MADWIFI_BSD */ -+} -+ -+ -+static int -+madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) -+{ -+	/* -+	 * Do nothing; we setup parameters at startup that define the -+	 * contents of the beacon information element. -+	 */ -+	return 0; -+} -+ -+static int -+madwifi_sta_deauth(void *priv, u8 *addr, int reason_code) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct ieee80211req_mlme mlme; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: addr=%s reason_code=%d\n", -+		__func__, ether_sprintf(addr), reason_code); -+ -+	mlme.im_op = IEEE80211_MLME_DEAUTH; -+	mlme.im_reason = reason_code; -+	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+	return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); -+} -+ -+static int -+madwifi_sta_disassoc(void *priv, u8 *addr, int reason_code) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	struct ieee80211req_mlme mlme; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+		"%s: addr=%s reason_code=%d\n", -+		__func__, ether_sprintf(addr), reason_code); -+ -+	mlme.im_reason = reason_code; -+	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); -+	return set80211priv(priv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); -+} -+ -+static int -+madwifi_del_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) -+{ -+	struct hostapd_data *hapd = drv->hapd; -+	struct sta_info *sta; -+ -+	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, -+		HOSTAPD_LEVEL_INFO, "deassociated"); -+ -+	sta = ap_get_sta(hapd, addr); -+	if (sta != NULL) { -+		sta->flags &= ~WLAN_STA_ASSOC; -+		wpa_sm_event(hapd, sta, WPA_DISASSOC); -+		sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; -+		ieee802_1x_set_port_enabled(hapd, sta, 0); -+		ap_free_sta(hapd, sta); -+	} -+	return 0; -+} -+ -+static int -+madwifi_process_wpa_ie(struct madwifi_driver_data *drv, struct sta_info *sta) -+{ -+	struct hostapd_data *hapd = drv->hapd; -+	struct ieee80211req_wpaie ie; -+	int ielen, res; -+ -+	/* -+	 * Fetch negotiated WPA/RSN parameters from the system. -+	 */ -+	memset(&ie, 0, sizeof(ie)); -+	memcpy(ie.wpa_macaddr, sta->addr, IEEE80211_ADDR_LEN); -+	if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { -+		printf("Failed to get WPA/RSN information element.\n"); -+		return -1;		/* XXX not right */ -+	} -+	ielen = ie.wpa_ie[1]; -+	if (ielen == 0) { -+		printf("No WPA/RSN information element for station!?\n"); -+		return -1;		/* XXX not right */ -+	} -+	ielen += 2; -+	res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen, -+			ie.wpa_ie[0] == WLAN_EID_RSN ? -+			    HOSTAPD_WPA_VERSION_WPA2 : HOSTAPD_WPA_VERSION_WPA); -+	if (res != WPA_IE_OK) { -+		printf("WPA/RSN information element rejected? (res %u)\n", res); -+		return -1; -+	} -+	free(sta->wpa_ie); -+	sta->wpa_ie = malloc(ielen); -+	if (sta->wpa_ie == NULL) { -+		printf("No memory to save WPA/RSN information element!\n"); -+		return -1; -+	} -+	memcpy(sta->wpa_ie, ie.wpa_ie, ielen); -+	sta->wpa_ie_len = ielen; -+	return 0; -+} -+ -+static int -+madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) -+{ -+	struct hostapd_data *hapd = drv->hapd; -+	struct sta_info *sta; -+	int new_assoc; -+ -+	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, -+		HOSTAPD_LEVEL_INFO, "associated"); -+ -+	sta = ap_get_sta(hapd, addr); -+	if (sta) { -+		accounting_sta_stop(hapd, sta); -+	} else { -+		sta = ap_sta_add(hapd, addr); -+		if (sta == NULL) -+			return -1; -+	} -+ -+	if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { -+		/* Cached accounting data is not valid anymore. */ -+		memset(drv->acct_mac, 0, ETH_ALEN); -+		memset(&drv->acct_data, 0, sizeof(drv->acct_data)); -+	} -+	accounting_sta_get_id(hapd, sta); -+ -+	if (hapd->conf->wpa) { -+		if (madwifi_process_wpa_ie(drv, sta)) -+			return -1; -+	} else { -+		free(sta->wpa_ie); -+		sta->wpa_ie = NULL; -+		sta->wpa_ie_len = 0; -+	} -+ -+	/* -+	 * Now that the internal station state is setup -+	 * kick the authenticator into action. -+	 */ -+	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; -+	sta->flags |= WLAN_STA_ASSOC; -+	wpa_sm_event(hapd, sta, WPA_ASSOC); -+	hostapd_new_assoc_sta(hapd, sta, !new_assoc); -+	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); -+	return 0; -+} -+ -+static void -+madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, -+				       char *custom) -+{ -+	struct hostapd_data *hapd = drv->hapd; -+ -+	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Custom wireless event: '%s'\n", -+		      custom); -+ -+	if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { -+		char *pos; -+		u8 addr[ETH_ALEN]; -+		pos = strstr(custom, "addr="); -+		if (pos == NULL) { -+			HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+				      "MLME-MICHAELMICFAILURE.indication " -+				      "without sender address ignored\n"); -+			return; -+		} -+		pos += 5; -+		if (hwaddr_aton(pos, addr) == 0) { -+			ieee80211_michael_mic_failure(drv->hapd, addr, 1); -+		} else { -+			HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+				      "MLME-MICHAELMICFAILURE.indication " -+				      "with invalid MAC address"); -+		} -+	} else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { -+		char *key, *value; -+		u32 val; -+		key = custom; -+		while ((key = strchr(key, '\n')) != NULL) { -+			key++; -+			value = strchr(key, '='); -+			if (value == NULL) -+				continue; -+			*value++ = '\0'; -+			val = strtoul(value, NULL, 10); -+			if (strcmp(key, "mac") == 0) -+				hwaddr_aton(value, drv->acct_mac); -+			else if (strcmp(key, "rx_packets") == 0) -+				drv->acct_data.rx_packets = val; -+			else if (strcmp(key, "tx_packets") == 0) -+				drv->acct_data.tx_packets = val; -+			else if (strcmp(key, "rx_bytes") == 0) -+				drv->acct_data.rx_bytes = val; -+			else if (strcmp(key, "tx_bytes") == 0) -+				drv->acct_data.tx_bytes = val; -+			key = value; -+		} -+	} -+} -+ -+static void -+madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, -+					    char *data, int len) -+{ -+	struct hostapd_data *hapd = drv->hapd; -+	struct iw_event iwe_buf, *iwe = &iwe_buf; -+	char *pos, *end, *custom, *buf; -+ -+	pos = data; -+	end = data + len; -+ -+	while (pos + IW_EV_LCP_LEN <= end) { -+		/* Event data may be unaligned, so make a local, aligned copy -+		 * before processing. */ -+		memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); -+		HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE, "Wireless event: " -+			      "cmd=0x%x len=%d\n", iwe->cmd, iwe->len); -+		if (iwe->len <= IW_EV_LCP_LEN) -+			return; -+ -+		custom = pos + IW_EV_POINT_LEN; -+		if (drv->we_version > 18 && -+		    (iwe->cmd == IWEVMICHAELMICFAILURE || -+		     iwe->cmd == IWEVCUSTOM)) { -+			/* WE-19 removed the pointer from struct iw_point */ -+			char *dpos = (char *) &iwe_buf.u.data.length; -+			int dlen = dpos - (char *) &iwe_buf; -+			memcpy(dpos, pos + IW_EV_LCP_LEN, -+			       sizeof(struct iw_event) - dlen); -+		} else { -+			memcpy(&iwe_buf, pos, sizeof(struct iw_event)); -+			custom += IW_EV_POINT_OFF; -+		} -+ -+		switch (iwe->cmd) { -+		case IWEVEXPIRED: -+			madwifi_del_sta(drv, iwe->u.addr.sa_data); -+			break; -+		case IWEVREGISTERED: -+			madwifi_new_sta(drv, iwe->u.addr.sa_data); -+			break; -+		case IWEVCUSTOM: -+			if (custom + iwe->u.data.length > end) -+				return; -+			buf = malloc(iwe->u.data.length + 1); -+			if (buf == NULL) -+				return;		/* XXX */ -+			memcpy(buf, custom, iwe->u.data.length); -+			buf[iwe->u.data.length] = '\0'; -+			madwifi_wireless_event_wireless_custom(drv, buf); -+			free(buf); -+			break; -+		} -+ -+		pos += iwe->len; -+	} -+} -+ -+ -+static void -+madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data *drv, -+					       struct nlmsghdr *h, int len) -+{ -+	struct ifinfomsg *ifi; -+	int attrlen, nlmsg_len, rta_len; -+	struct rtattr * attr; -+ -+	if (len < sizeof(*ifi)) -+		return; -+ -+	ifi = NLMSG_DATA(h); -+ -+	if (ifi->ifi_index != drv->ifindex) -+		return; -+ -+	nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); -+ -+	attrlen = h->nlmsg_len - nlmsg_len; -+	if (attrlen < 0) -+		return; -+ -+	attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); -+ -+	rta_len = RTA_ALIGN(sizeof(struct rtattr)); -+	while (RTA_OK(attr, attrlen)) { -+		if (attr->rta_type == IFLA_WIRELESS) { -+			madwifi_wireless_event_wireless( -+				drv, ((char *) attr) + rta_len, -+				attr->rta_len - rta_len); -+		} -+		attr = RTA_NEXT(attr, attrlen); -+	} -+} -+ -+ -+static void -+madwifi_wireless_event_receive(int sock, void *eloop_ctx, void *sock_ctx) -+{ -+	char buf[256]; -+	int left; -+	struct sockaddr_nl from; -+	socklen_t fromlen; -+	struct nlmsghdr *h; -+	struct madwifi_driver_data *drv = eloop_ctx; -+ -+	fromlen = sizeof(from); -+	left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, -+			(struct sockaddr *) &from, &fromlen); -+	if (left < 0) { -+		if (errno != EINTR && errno != EAGAIN) -+			perror("recvfrom(netlink)"); -+		return; -+	} -+ -+	h = (struct nlmsghdr *) buf; -+	while (left >= sizeof(*h)) { -+		int len, plen; -+ -+		len = h->nlmsg_len; -+		plen = len - sizeof(*h); -+		if (len > left || plen < 0) { -+			printf("Malformed netlink message: " -+			       "len=%d left=%d plen=%d\n", -+			       len, left, plen); -+			break; -+		} -+ -+		switch (h->nlmsg_type) { -+		case RTM_NEWLINK: -+			madwifi_wireless_event_rtm_newlink(drv, h, plen); -+			break; -+		} -+ -+		len = NLMSG_ALIGN(len); -+		left -= len; -+		h = (struct nlmsghdr *) ((char *) h + len); -+	} -+ -+	if (left > 0) { -+		printf("%d extra bytes in the end of netlink message\n", left); -+	} -+} -+ -+ -+static int -+madwifi_get_we_version(struct madwifi_driver_data *drv) -+{ -+	struct iw_range *range; -+	struct iwreq iwr; -+	int minlen; -+	size_t buflen; -+ -+	drv->we_version = 0; -+ -+	/* -+	 * Use larger buffer than struct iw_range in order to allow the -+	 * structure to grow in the future. -+	 */ -+	buflen = sizeof(struct iw_range) + 500; -+	range = malloc(buflen); -+	if (range == NULL) -+		return -1; -+	memset(range, 0, buflen); -+ -+	memset(&iwr, 0, sizeof(iwr)); -+	strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+	iwr.u.data.pointer = (caddr_t) range; -+	iwr.u.data.length = buflen; -+ -+	minlen = ((char *) &range->enc_capa) - (char *) range + -+		sizeof(range->enc_capa); -+ -+	if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { -+		perror("ioctl[SIOCGIWRANGE]"); -+		free(range); -+		return -1; -+	} else if (iwr.u.data.length >= minlen && -+		   range->we_version_compiled >= 18) { -+		wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " -+			   "WE(source)=%d enc_capa=0x%x", -+			   range->we_version_compiled, -+			   range->we_version_source, -+			   range->enc_capa); -+		drv->we_version = range->we_version_compiled; -+	} -+ -+	free(range); -+	return 0; -+} -+ -+ -+static int -+madwifi_wireless_event_init(void *priv) -+{ -+	struct madwifi_driver_data *drv = priv; -+	int s; -+	struct sockaddr_nl local; -+ -+	madwifi_get_we_version(drv); -+ -+	drv->wext_sock = -1; -+ -+	s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); -+	if (s < 0) { -+		perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); -+		return -1; -+	} -+ -+	memset(&local, 0, sizeof(local)); -+	local.nl_family = AF_NETLINK; -+	local.nl_groups = RTMGRP_LINK; -+	if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) { -+		perror("bind(netlink)"); -+		close(s); -+		return -1; -+	} -+ -+	eloop_register_read_sock(s, madwifi_wireless_event_receive, drv, NULL); -+	drv->wext_sock = s; -+ -+	return 0; -+} -+ -+ -+static void -+madwifi_wireless_event_deinit(void *priv) -+{ -+	struct madwifi_driver_data *drv = priv; -+ -+	if (drv != NULL) { -+		if (drv->wext_sock < 0) -+			return; -+		eloop_unregister_read_sock(drv->wext_sock); -+		close(drv->wext_sock); -+	} -+} -+ -+ -+static int -+madwifi_send_eapol(void *priv, u8 *addr, u8 *data, size_t data_len, int encrypt) -+{ -+	struct madwifi_driver_data *drv = priv; -+	hostapd *hapd = drv->hapd; -+	unsigned char buf[3000]; -+	unsigned char *bp = buf; -+	struct l2_ethhdr *eth; -+	size_t len; -+	int status; -+ -+	/* -+	 * Prepend the Etherent header.  If the caller left us -+	 * space at the front we could just insert it but since -+	 * we don't know we copy to a local buffer.  Given the frequency -+	 * and size of frames this probably doesn't matter. -+	 */ -+	len = data_len + sizeof(struct l2_ethhdr); -+	if (len > sizeof(buf)) { -+		bp = malloc(len); -+		if (bp == NULL) { -+			printf("EAPOL frame discarded, cannot malloc temp " -+			       "buffer of size %lu!\n", (unsigned long) len); -+			return -1; -+		} -+	} -+	eth = (struct l2_ethhdr *) bp; -+	memcpy(eth->h_dest, addr, ETH_ALEN); -+	memcpy(eth->h_source, drv->hapd->own_addr, ETH_ALEN); -+	eth->h_proto = htons(ETH_P_EAPOL); -+	memcpy(eth+1, data, data_len); -+ -+	if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS)) -+		hostapd_hexdump("TX EAPOL", bp, len); -+ -+	status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); -+ -+	if (bp != buf) -+		free(bp); -+	return status; -+} -+ -+static void -+handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) -+{ -+	struct madwifi_driver_data *drv = ctx; -+	hostapd *hapd = drv->hapd; -+	struct sta_info *sta; -+ -+	sta = ap_get_sta(hapd, src_addr); -+	if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { -+		printf("Data frame from not associated STA %s\n", -+		       ether_sprintf(src_addr)); -+		/* XXX cannot happen */ -+		return; -+	} -+	ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr), -+			   len - sizeof(struct l2_ethhdr)); -+} -+ -+static int -+madwifi_init(struct hostapd_data *hapd) -+{ -+	struct madwifi_driver_data *drv; -+	struct ifreq ifr; -+	struct iwreq iwr; -+ -+	drv = malloc(sizeof(struct madwifi_driver_data)); -+	if (drv == NULL) { -+		printf("Could not allocate memory for madwifi driver data\n"); -+		goto bad; -+	} -+ -+	memset(drv, 0, sizeof(*drv)); -+	drv->ops = madwifi_driver_ops; -+	drv->hapd = hapd; -+	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); -+	if (drv->ioctl_sock < 0) { -+		perror("socket[PF_INET,SOCK_DGRAM]"); -+		goto bad; -+	} -+	memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface)); -+ -+	memset(&ifr, 0, sizeof(ifr)); -+	snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->iface); -+	if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { -+		perror("ioctl(SIOCGIFINDEX)"); -+		goto bad; -+	} -+	drv->ifindex = ifr.ifr_ifindex; -+ -+	drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, -+					handle_read, drv, 1); -+	if (drv->sock_xmit == NULL) -+		goto bad; -+	if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) -+		goto bad; -+	if (hapd->conf->bridge[0] != '\0') { -+		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, -+			"Configure bridge %s for EAPOL traffic.\n", -+			hapd->conf->bridge); -+		drv->sock_recv = l2_packet_init(hapd->conf->bridge, NULL, -+						ETH_P_EAPOL, handle_read, drv, -+						0); -+		if (drv->sock_recv == NULL) -+			goto bad; -+	} else -+		drv->sock_recv = drv->sock_xmit; -+ -+	memset(&iwr, 0, sizeof(iwr)); -+	strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+ -+	iwr.u.mode = IW_MODE_MASTER; -+ -+	if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { -+		perror("ioctl[SIOCSIWMODE]"); -+		printf("Could not set interface to master mode!\n"); -+		goto bad; -+	} -+ -+	madwifi_set_iface_flags(drv, 0);	/* mark down during setup */ -+ -+	hapd->driver = &drv->ops; -+	return 0; -+bad: -+	if (drv->sock_xmit != NULL) -+		l2_packet_deinit(drv->sock_xmit); -+	if (drv->ioctl_sock >= 0) -+		close(drv->ioctl_sock); -+	if (drv != NULL) -+		free(drv); -+	return -1; -+} -+ -+ -+static void -+madwifi_deinit(void *priv) -+{ -+	struct madwifi_driver_data *drv = priv; -+ -+	drv->hapd->driver = NULL; -+ -+	(void) madwifi_set_iface_flags(drv, 0); -+	if (drv->ioctl_sock >= 0) -+		close(drv->ioctl_sock); -+	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) -+		l2_packet_deinit(drv->sock_recv); -+	if (drv->sock_xmit != NULL) -+		l2_packet_deinit(drv->sock_xmit); -+	free(drv); -+} -+ -+static int -+madwifi_set_ssid(void *priv, u8 *buf, int len) -+{ -+	struct madwifi_driver_data *drv = priv; -+	struct iwreq iwr; -+ -+	memset(&iwr, 0, sizeof(iwr)); -+	strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+	iwr.u.essid.flags = 1; /* SSID active */ -+	iwr.u.essid.pointer = (caddr_t) buf; -+	iwr.u.essid.length = len + 1; -+ -+	if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { -+		perror("ioctl[SIOCSIWESSID]"); -+		printf("len=%d\n", len); -+		return -1; -+	} -+	return 0; -+} -+ -+static int -+madwifi_get_ssid(void *priv, u8 *buf, int len) -+{ -+	struct madwifi_driver_data *drv = priv; -+	struct iwreq iwr; -+	int ret = 0; -+ -+	memset(&iwr, 0, sizeof(iwr)); -+	strncpy(iwr.ifr_name, drv->iface, IFNAMSIZ); -+	iwr.u.essid.pointer = (caddr_t) buf; -+	iwr.u.essid.length = len; -+ -+	if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { -+		perror("ioctl[SIOCGIWESSID]"); -+		ret = -1; -+	} else -+		ret = iwr.u.essid.length; -+ -+	return ret; -+} -+ -+static const struct driver_ops madwifi_driver_ops = { -+	.name			= "madwifi", -+	.init			= madwifi_init, -+	.deinit			= madwifi_deinit, -+	.set_ieee8021x		= madwifi_set_ieee8021x, -+	.set_privacy		= madwifi_set_privacy, -+	.set_encryption		= madwifi_set_key, -+	.get_seqnum		= madwifi_get_seqnum, -+	.flush			= madwifi_flush, -+	.set_generic_elem	= madwifi_set_opt_ie, -+	.wireless_event_init	= madwifi_wireless_event_init, -+	.wireless_event_deinit	= madwifi_wireless_event_deinit, -+	.set_sta_authorized	= madwifi_set_sta_authorized, -+	.read_sta_data		= madwifi_read_sta_driver_data, -+	.send_eapol		= madwifi_send_eapol, -+	.sta_disassoc		= madwifi_sta_disassoc, -+	.sta_deauth		= madwifi_sta_deauth, -+	.set_ssid		= madwifi_set_ssid, -+	.get_ssid		= madwifi_get_ssid, -+	.sta_clear_stats        = madwifi_sta_clear_stats, -+}; -+ -+void madwifi_driver_register(void) -+{ -+	driver_register(madwifi_driver_ops.name, &madwifi_driver_ops); -+} | 
