[pkg-wpa-devel] r1340 - in /hostapd/branches/upstream/current: hostapd/ src/common/ src/crypto/ src/drivers/ src/eap_common/ src/eap_peer/ src/eap_server/ src/eapol_supp/ src/l2_packet/ src/rsn_supp/ src/tls/ src/wps/

kelmo-guest at users.alioth.debian.org kelmo-guest at users.alioth.debian.org
Mon Mar 23 15:39:23 UTC 2009


Author: kelmo-guest
Date: Mon Mar 23 15:39:23 2009
New Revision: 1340

URL: http://svn.debian.org/wsvn/?sc=1&rev=1340
Log:
[svn-upgrade] Integrating new upstream version, hostapd (0.6.9)

Added:
    hostapd/branches/upstream/current/hostapd/driver_atheros.c
Modified:
    hostapd/branches/upstream/current/hostapd/ChangeLog
    hostapd/branches/upstream/current/hostapd/Makefile
    hostapd/branches/upstream/current/hostapd/ctrl_iface.c
    hostapd/branches/upstream/current/hostapd/driver_bsd.c
    hostapd/branches/upstream/current/hostapd/driver_madwifi.c
    hostapd/branches/upstream/current/hostapd/driver_nl80211.c
    hostapd/branches/upstream/current/hostapd/driver_prism54.c
    hostapd/branches/upstream/current/hostapd/drivers.c
    hostapd/branches/upstream/current/hostapd/hostapd.8
    hostapd/branches/upstream/current/hostapd/hostapd.conf
    hostapd/branches/upstream/current/hostapd/hostapd_cli.1
    hostapd/branches/upstream/current/hostapd/ieee802_11.c
    hostapd/branches/upstream/current/hostapd/wme.c
    hostapd/branches/upstream/current/hostapd/wme.h
    hostapd/branches/upstream/current/hostapd/wps_hostapd.c
    hostapd/branches/upstream/current/src/common/ieee802_11_defs.h
    hostapd/branches/upstream/current/src/common/nl80211_copy.h
    hostapd/branches/upstream/current/src/common/version.h
    hostapd/branches/upstream/current/src/common/wpa_common.c
    hostapd/branches/upstream/current/src/crypto/crypto_gnutls.c
    hostapd/branches/upstream/current/src/crypto/crypto_internal.c
    hostapd/branches/upstream/current/src/crypto/sha256.c
    hostapd/branches/upstream/current/src/crypto/tls_gnutls.c
    hostapd/branches/upstream/current/src/drivers/driver_bsd.c
    hostapd/branches/upstream/current/src/drivers/driver_ndis.c
    hostapd/branches/upstream/current/src/eap_common/eap_defs.h
    hostapd/branches/upstream/current/src/eap_common/eap_fast_common.h
    hostapd/branches/upstream/current/src/eap_common/eap_tlv_common.h
    hostapd/branches/upstream/current/src/eap_peer/eap_fast.c
    hostapd/branches/upstream/current/src/eap_peer/eap_gpsk.c
    hostapd/branches/upstream/current/src/eap_peer/eap_tnc.c
    hostapd/branches/upstream/current/src/eap_server/eap.c
    hostapd/branches/upstream/current/src/eap_server/eap_gpsk.c
    hostapd/branches/upstream/current/src/eap_server/eap_i.h
    hostapd/branches/upstream/current/src/eap_server/eap_tnc.c
    hostapd/branches/upstream/current/src/eap_server/eap_ttls.c
    hostapd/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c
    hostapd/branches/upstream/current/src/l2_packet/l2_packet_linux.c
    hostapd/branches/upstream/current/src/rsn_supp/wpa.c
    hostapd/branches/upstream/current/src/tls/tlsv1_client.c
    hostapd/branches/upstream/current/src/wps/wps.h
    hostapd/branches/upstream/current/src/wps/wps_enrollee.c
    hostapd/branches/upstream/current/src/wps/wps_registrar.c
    hostapd/branches/upstream/current/src/wps/wps_upnp.c
    hostapd/branches/upstream/current/src/wps/wps_upnp_ssdp.c

Modified: hostapd/branches/upstream/current/hostapd/ChangeLog
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/ChangeLog?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/ChangeLog (original)
+++ hostapd/branches/upstream/current/hostapd/ChangeLog Mon Mar 23 15:39:23 2009
@@ -1,4 +1,14 @@
 ChangeLog for hostapd
+
+2009-03-23 - v0.6.9
+	* driver_nl80211: fixed STA accounting data collection (TX/RX bytes
+	  reported correctly; TX/RX packets not yet available from kernel)
+	* fixed EAPOL/EAP reauthentication when using an external RADIUS
+	  authentication server
+	* driver_prism54: fixed segmentation fault on initialization
+	* fixed TNC with EAP-TTLS
+	* fixed IEEE 802.11r key derivation function to match with the standard
+	  (note: this breaks interoperability with previous version) [Bug 303]
 
 2009-02-15 - v0.6.8
 	* increased hostapd_cli ping interval to 5 seconds and made this

Modified: hostapd/branches/upstream/current/hostapd/Makefile
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/Makefile?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/Makefile (original)
+++ hostapd/branches/upstream/current/hostapd/Makefile Mon Mar 23 15:39:23 2009
@@ -113,6 +113,12 @@
 ifdef CONFIG_DRIVER_MADWIFI
 CFLAGS += -DCONFIG_DRIVER_MADWIFI
 OBJS += driver_madwifi.o
+CONFIG_L2_PACKET=y
+endif
+
+ifdef CONFIG_DRIVER_ATHEROS
+CFLAGS += -DCONFIG_DRIVER_ATHEROS
+OBJS += driver_atheros.o
 CONFIG_L2_PACKET=y
 endif
 
@@ -307,7 +313,9 @@
 OBJS += ../src/eap_server/eap_tnc.o
 OBJS += ../src/eap_server/tncs.o
 NEED_BASE64=y
+ifndef CONFIG_DRIVER_BSD
 LIBS += -ldl
+endif
 endif
 
 # Basic EAP functionality is needed for EAPOL

Modified: hostapd/branches/upstream/current/hostapd/ctrl_iface.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/ctrl_iface.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/ctrl_iface.c (original)
+++ hostapd/branches/upstream/current/hostapd/ctrl_iface.c Mon Mar 23 15:39:23 2009
@@ -18,6 +18,7 @@
 
 #include <sys/un.h>
 #include <sys/stat.h>
+#include <stddef.h>
 
 #include "hostapd.h"
 #include "eloop.h"
@@ -60,7 +61,8 @@
 	dst->next = hapd->ctrl_dst;
 	hapd->ctrl_dst = dst;
 	wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached",
-		    (u8 *) from->sun_path, fromlen);
+		    (u8 *) from->sun_path,
+		    fromlen - offsetof(struct sockaddr_un, sun_path));
 	return 0;
 }
 
@@ -74,15 +76,18 @@
 	dst = hapd->ctrl_dst;
 	while (dst) {
 		if (fromlen == dst->addrlen &&
-		    os_memcmp(from->sun_path, dst->addr.sun_path, fromlen) ==
-		    0) {
+		    os_memcmp(from->sun_path, dst->addr.sun_path,
+			      fromlen - offsetof(struct sockaddr_un, sun_path))
+		    == 0) {
 			if (prev == NULL)
 				hapd->ctrl_dst = dst->next;
 			else
 				prev->next = dst->next;
 			os_free(dst);
 			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached",
-				    (u8 *) from->sun_path, fromlen);
+				    (u8 *) from->sun_path,
+				    fromlen -
+				    offsetof(struct sockaddr_un, sun_path));
 			return 0;
 		}
 		prev = dst;
@@ -104,10 +109,12 @@
 	dst = hapd->ctrl_dst;
 	while (dst) {
 		if (fromlen == dst->addrlen &&
-		    os_memcmp(from->sun_path, dst->addr.sun_path, fromlen) ==
-		    0) {
+		    os_memcmp(from->sun_path, dst->addr.sun_path,
+			      fromlen - offsetof(struct sockaddr_un, sun_path))
+		    == 0) {
 			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor "
-				    "level", (u8 *) from->sun_path, fromlen);
+				    "level", (u8 *) from->sun_path, fromlen -
+				    offsetof(struct sockaddr_un, sun_path));
 			dst->debug_level = atoi(level);
 			return 0;
 		}
@@ -434,6 +441,9 @@
 	}
 
 	os_memset(&addr, 0, sizeof(addr));
+#ifdef __FreeBSD__
+	addr.sun_len = sizeof(addr);
+#endif /* __FreeBSD__ */
 	addr.sun_family = AF_UNIX;
 	fname = hostapd_ctrl_iface_path(hapd);
 	if (fname == NULL)
@@ -536,15 +546,17 @@
 		next = dst->next;
 		if (level >= dst->debug_level) {
 			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send",
-				    (u8 *) dst->addr.sun_path, dst->addrlen);
+				    (u8 *) dst->addr.sun_path, dst->addrlen -
+				    offsetof(struct sockaddr_un, sun_path));
 			msg.msg_name = &dst->addr;
 			msg.msg_namelen = dst->addrlen;
 			if (sendmsg(hapd->ctrl_sock, &msg, 0) < 0) {
-				fprintf(stderr, "CTRL_IFACE monitor[%d]: ",
-					idx);
-				perror("sendmsg");
+				int _errno = errno;
+				wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
+					   "%d - %s",
+					   idx, errno, strerror(errno));
 				dst->errors++;
-				if (dst->errors > 10) {
+				if (dst->errors > 10 || _errno == ENOENT) {
 					hostapd_ctrl_iface_detach(
 						hapd, &dst->addr,
 						dst->addrlen);

Added: hostapd/branches/upstream/current/hostapd/driver_atheros.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/driver_atheros.c?rev=1340&op=file
==============================================================================
--- hostapd/branches/upstream/current/hostapd/driver_atheros.c (added)
+++ hostapd/branches/upstream/current/hostapd/driver_atheros.c Mon Mar 23 15:39:23 2009
@@ -1,0 +1,1457 @@
+/*
+ * hostapd / Driver interaction with Atheros driver
+ * Copyright (c) 2004, Sam Leffler <sam at errno.com>
+ * Copyright (c) 2004, Video54 Technologies
+ * Copyright (c) 2005-2007, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2009, Atheros Communications
+ *
+ * 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 "includes.h"
+#include <net/if.h>
+#include <sys/ioctl.h>
+
+#include "common.h"
+#ifndef _BYTE_ORDER
+#ifdef WORDS_BIGENDIAN
+#define _BYTE_ORDER _BIG_ENDIAN
+#else
+#define _BYTE_ORDER _LITTLE_ENDIAN
+#endif
+#endif /* _BYTE_ORDER */
+
+#include <net80211/ieee80211.h>
+#include <net80211/_ieee80211.h>
+#include <net80211/ieee80211_crypto.h>
+
+/*
+ * Note, the ATH_WPS_IE setting must match with the driver build.. If the
+ * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail.
+ */
+#define ATH_WPS_IE
+#include <net80211/ieee80211_ioctl.h>
+
+#ifdef CONFIG_WPS
+#ifdef IEEE80211_IOCTL_FILTERFRAME
+#include <netpacket/packet.h>
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW 0x0019
+#endif
+#endif /* IEEE80211_IOCTL_FILTERFRAME */
+#endif /* CONFIG_WPS */
+
+/*
+ * Avoid conflicts with hostapd definitions by undefining couple of defines
+ * from madwifi header files.
+ */
+#undef WPA_OUI_TYPE
+#undef WME_OUI_TYPE
+
+#include "wireless_copy.h"
+
+#include "hostapd.h"
+#include "driver.h"
+#include "eloop.h"
+#include "priv_netlink.h"
+#include "l2_packet/l2_packet.h"
+
+#include "wps_hostapd.h"
+#include "ieee802_11_defs.h"
+
+
+struct madwifi_driver_data {
+	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;
+
+	struct l2_packet_data *sock_raw; /* raw 802.11 management frames */
+};
+
+static int madwifi_sta_deauth(void *priv, const u8 *addr, int reason_code);
+
+/* hostapd 0.7.x compatibility - START */
+#include "ieee802_1x.h"
+#include "sta_info.h"
+#include "wpa.h"
+#include "radius/radius.h"
+#include "ieee802_11.h"
+#include "accounting.h"
+
+static int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
+			       const u8 *ie, size_t ielen)
+{
+	struct sta_info *sta;
+	int new_assoc, res;
+
+	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;
+	}
+	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
+
+	if (hapd->conf->wpa) {
+		if (ie == NULL || ielen == 0) {
+			if (hapd->conf->wps_state) {
+				wpa_printf(MSG_DEBUG, "STA did not include "
+					   "WPA/RSN IE in (Re)Association "
+					   "Request - possible WPS use");
+				sta->flags |= WLAN_STA_MAYBE_WPS;
+				goto skip_wpa_check;
+			}
+
+			wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
+			return -1;
+		}
+		if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
+		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
+			sta->flags |= WLAN_STA_WPS;
+			goto skip_wpa_check;
+		}
+
+		if (sta->wpa_sm == NULL)
+			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
+							sta->addr);
+		if (sta->wpa_sm == NULL) {
+			wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
+				   "machine");
+			return -1;
+		}
+		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
+					  ie, ielen, NULL, 0);
+		if (res != WPA_IE_OK) {
+			wpa_printf(MSG_DEBUG, "WPA/RSN information element "
+				   "rejected? (res %u)", res);
+			wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
+			return -1;
+		}
+	} else if (hapd->conf->wps_state) {
+		if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 &&
+		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
+			sta->flags |= WLAN_STA_WPS;
+		} else
+			sta->flags |= WLAN_STA_MAYBE_WPS;
+	}
+skip_wpa_check:
+
+	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
+	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
+	wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
+
+	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
+
+	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
+
+	return 0;
+}
+
+
+static void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
+{
+	struct sta_info *sta;
+
+	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
+		       HOSTAPD_LEVEL_INFO, "disassociated");
+
+	sta = ap_get_sta(hapd, addr);
+	if (sta == NULL) {
+		wpa_printf(MSG_DEBUG, "Disassociation notification for "
+			   "unknown STA " MACSTR, MAC2STR(addr));
+		return;
+	}
+
+	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
+	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
+	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
+	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
+	ap_free_sta(hapd, sta);
+}
+
+
+static void hostapd_eapol_receive(struct hostapd_data *hapd, const u8 *sa,
+				  const u8 *buf, size_t len)
+{
+	ieee802_1x_receive(hapd, sa, buf, len);
+}
+
+
+static void hostapd_michael_mic_failure(struct hostapd_data *hapd,
+					const u8 *addr)
+{
+	ieee80211_michael_mic_failure(hapd, addr, 1);
+}
+/* hostapd 0.7.x compatibility - END */
+
+static int
+set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len)
+{
+	struct iwreq iwr;
+	int do_inline = len < IFNAMSIZ;
+
+	/* Certain ioctls must use the non-inlined method */
+	if (op == IEEE80211_IOCTL_SET_APPIEBUF ||
+	    op == IEEE80211_IOCTL_FILTERFRAME)
+		do_inline = 0;
+
+	memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
+	if (do_inline) {
+		/*
+		 * 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) {
+		int first = IEEE80211_IOCTL_SETPARAM;
+		static const char *opnames[] = {
+			"ioctl[IEEE80211_IOCTL_SETPARAM]",
+			"ioctl[IEEE80211_IOCTL_GETPARAM]",
+			"ioctl[IEEE80211_IOCTL_SETKEY]",
+			"ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
+			"ioctl[IEEE80211_IOCTL_DELKEY]",
+			"ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
+			"ioctl[IEEE80211_IOCTL_SETMLME]",
+			"ioctl[IEEE80211_IOCTL_GETCHANINFO]",
+			"ioctl[IEEE80211_IOCTL_SETOPTIE]",
+			"ioctl[IEEE80211_IOCTL_GETOPTIE]",
+			"ioctl[IEEE80211_IOCTL_ADDMAC]",
+			"ioctl[IEEE80211_IOCTL_DELMAC]",
+			"ioctl[IEEE80211_IOCTL_GETCHANLIST]",
+			"ioctl[IEEE80211_IOCTL_SETCHANLIST]",
+			"ioctl[IEEE80211_IOCTL_KICKMAC]",
+			"ioctl[IEEE80211_IOCTL_CHANSWITCH]",
+			"ioctl[IEEE80211_IOCTL_GETMODE]",
+			"ioctl[IEEE80211_IOCTL_SETMODE]",
+			"ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
+			"ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
+			NULL,
+			"ioctl[IEEE80211_IOCTL_FILTERFRAME]",
+		};
+		int idx = op - first;
+		if (first <= op &&
+		    idx < (int) (sizeof(opnames) / sizeof(opnames[0])) &&
+		    opnames[idx])
+			perror(opnames[idx]);
+		else {
+			perror("ioctl[unknown???]");
+			wpa_printf(MSG_DEBUG, "Failed ioctl: 0x%x", op);
+		}
+		return -1;
+	}
+	return 0;
+}
+
+static int
+set80211param(struct madwifi_driver_data *drv, int op, int arg)
+{
+	struct iwreq iwr;
+
+	memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(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]");
+		wpa_printf(MSG_DEBUG, "%s: Failed to set parameter (op %d "
+			   "arg %d)", __func__, op, arg);
+		return -1;
+	}
+	return 0;
+}
+
+#ifndef CONFIG_NO_STDOUT_DEBUG
+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;
+}
+#endif /* CONFIG_NO_STDOUT_DEBUG */
+
+/*
+ * Configure WPA parameters.
+ */
+static int
+madwifi_configure_wpa(struct madwifi_driver_data *drv)
+{
+	struct hostapd_data *hapd = drv->hapd;
+	struct hostapd_bss_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:
+		wpa_printf(MSG_ERROR, "Unknown group key cipher %u",
+			   conf->wpa_group);
+		return -1;
+	}
+	wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __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;
+	wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
+	if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) {
+		printf("Unable to set pairwise key ciphers to 0x%x\n", v);
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
+		   __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);
+	wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
+		   __func__, conf->rsn_preauth);
+	if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) {
+		printf("Unable to set RSN capabilities to 0x%x\n", v);
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __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;
+	struct ifreq ifr;
+
+	wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up);
+
+	if (drv->ioctl_sock < 0)
+		return -1;
+
+	memset(&ifr, 0, sizeof(ifr));
+	os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);
+
+	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));
+		os_strlcpy(ifr.ifr_name, drv->iface, IFNAMSIZ);
+		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(const char *ifname, void *priv, int enabled)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct hostapd_data *hapd = drv->hapd;
+	struct hostapd_bss_config *conf = hapd->conf;
+
+	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __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 0;
+}
+
+static int
+madwifi_set_privacy(const char *ifname, void *priv, int enabled)
+{
+	struct madwifi_driver_data *drv = priv;
+
+	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
+
+	return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled);
+}
+
+static int
+madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct ieee80211req_mlme mlme;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
+		   __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);
+	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR,
+			   __func__, authorized ? "" : "un", MAC2STR(addr));
+	}
+
+	return ret;
+}
+
+static int
+madwifi_sta_set_flags(void *priv, const u8 *addr, int total_flags,
+		      int flags_or, int flags_and)
+{
+	/* For now, only support setting Authorized flag */
+	if (flags_or & WLAN_STA_AUTHORIZED)
+		return madwifi_set_sta_authorized(priv, addr, 1);
+	if (!(flags_and & WLAN_STA_AUTHORIZED))
+		return madwifi_set_sta_authorized(priv, addr, 0);
+	return 0;
+}
+
+static int
+madwifi_del_key(void *priv, const u8 *addr, int key_idx)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct ieee80211req_del_key wk;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
+		   __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;
+	}
+
+	ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk));
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s"
+			   " key_idx %d)", __func__, ether_sprintf(addr),
+			   key_idx);
+	}
+
+	return ret;
+}
+
+static int
+madwifi_set_key(const char *ifname, void *priv, const char *alg,
+		const u8 *addr, int key_idx,
+		const u8 *key, size_t key_len, int txkey)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct ieee80211req_key wk;
+	u_int8_t cipher;
+	int ret;
+
+	if (strcmp(alg, "none") == 0)
+		return madwifi_del_key(drv, addr, key_idx);
+
+	wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d",
+		   __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);
+
+	ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s"
+			   " key_idx %d alg '%s' key_len %lu txkey %d)",
+			   __func__, ether_sprintf(wk.ik_macaddr), key_idx,
+			   alg, (unsigned long) key_len, txkey);
+	}
+
+	return ret;
+}
+
+
+static int
+madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
+		   u8 *seq)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct ieee80211req_key wk;
+
+	wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
+		   __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(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data "
+			   "(addr " MACSTR " key_idx %d)",
+			   __func__, MAC2STR(wk.ik_macaddr), idx);
+		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)
+{
+	u8 allsta[IEEE80211_ADDR_LEN];
+	memset(allsta, 0xff, IEEE80211_ADDR_LEN);
+	return madwifi_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE);
+}
+
+
+static int
+madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
+			     const u8 *addr)
+{
+	struct madwifi_driver_data *drv = priv;
+	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_STA_STATS,
+			 &stats, sizeof(stats))) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr "
+			   MACSTR ")", __func__, MAC2STR(addr));
+		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;
+}
+
+
+static int
+madwifi_sta_clear_stats(void *priv, const u8 *addr)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct ieee80211req_mlme mlme;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr));
+
+	mlme.im_op = IEEE80211_MLME_CLEAR_STATS;
+	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
+	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
+			   sizeof(mlme));
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr "
+			   MACSTR ")", __func__, MAC2STR(addr));
+	}
+
+	return ret;
+}
+
+
+static int
+madwifi_set_opt_ie(const char *ifname, 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, const u8 *addr, int reason_code)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct ieee80211req_mlme mlme;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
+		   __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);
+	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR
+			   " reason %d)",
+			   __func__, MAC2STR(addr), reason_code);
+	}
+
+	return ret;
+}
+
+static int
+madwifi_sta_disassoc(void *priv, const u8 *addr, int reason_code)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct ieee80211req_mlme mlme;
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
+		   __func__, ether_sprintf(addr), reason_code);
+
+	mlme.im_op = IEEE80211_MLME_DISASSOC;
+	mlme.im_reason = reason_code;
+	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
+	ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr "
+			   MACSTR " reason %d)",
+			   __func__, MAC2STR(addr), reason_code);
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_WPS
+static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
+				size_t len)
+{
+	struct madwifi_driver_data *drv = ctx;
+	const struct ieee80211_mgmt *mgmt;
+	const u8 *end, *ie;
+	u16 fc;
+	size_t ie_len;
+
+	/* Send Probe Request information to WPS processing */
+
+	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
+		return;
+	mgmt = (const struct ieee80211_mgmt *) buf;
+
+	fc = le_to_host16(mgmt->frame_control);
+	if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
+	    WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ)
+		return;
+
+	end = buf + len;
+	ie = mgmt->u.probe_req.variable;
+	ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
+
+	hostapd_wps_probe_req_rx(drv->hapd, mgmt->sa, ie, ie_len);
+}
+#endif /* CONFIG_WPS */
+
+static int madwifi_receive_probe_req(struct madwifi_driver_data *drv)
+{
+	int ret = 0;
+#ifdef CONFIG_WPS
+	struct ieee80211req_set_filter filt;
+
+	wpa_printf(MSG_DEBUG, "%s Enter", __func__);
+	filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ;
+
+	ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
+			   sizeof(struct ieee80211req_set_filter));
+	if (ret)
+		return ret;
+
+	drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW,
+				       madwifi_raw_receive, drv, 1);
+	if (drv->sock_raw == NULL)
+		return -1;
+#endif /* CONFIG_WPS */
+	return ret;
+}
+
+#ifdef CONFIG_WPS
+static int
+madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
+{
+	struct madwifi_driver_data *drv = priv;
+	u8 buf[256];
+	struct ieee80211req_getset_appiebuf *beac_ie;
+
+	wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__,
+		   (unsigned long) len);
+
+	beac_ie = (struct ieee80211req_getset_appiebuf *) buf;
+	beac_ie->app_frmtype = frametype;
+	beac_ie->app_buflen = len;
+	memcpy(&(beac_ie->app_buf[0]), ie, len);
+
+	return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie,
+			    sizeof(struct ieee80211req_getset_appiebuf) + len);
+}
+
+static int
+madwifi_set_wps_beacon_ie(const char *ifname, void *priv, const u8 *ie,
+			  size_t len)
+{
+	return madwifi_set_wps_ie(priv, ie, len, IEEE80211_APPIE_FRAME_BEACON);
+}
+
+static int
+madwifi_set_wps_probe_resp_ie(const char *ifname, void *priv, const u8 *ie,
+			      size_t len)
+{
+	return madwifi_set_wps_ie(priv, ie, len,
+				  IEEE80211_APPIE_FRAME_PROBE_RESP);
+}
+#else /* CONFIG_WPS */
+#define madwifi_set_wps_beacon_ie NULL
+#define madwifi_set_wps_probe_resp_ie NULL
+#endif /* CONFIG_WPS */
+
+static int
+madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
+{
+	struct hostapd_data *hapd = drv->hapd;
+	struct ieee80211req_wpaie ie;
+	int ielen = 0, res;
+	u8 *iebuf = NULL;
+
+	/*
+	 * Fetch negotiated WPA/RSN parameters from the system.
+	 */
+	memset(&ie, 0, sizeof(ie));
+	memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
+	if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {
+		/*
+		 * See ATH_WPS_IE comment in the beginning of the file for a
+		 * possible cause for the failure..
+		 */
+		wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s",
+			   __func__, strerror(errno));
+		goto no_ie;
+	}
+	wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE",
+		    ie.wpa_ie, IEEE80211_MAX_OPT_IE);
+	wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE",
+		    ie.rsn_ie, IEEE80211_MAX_OPT_IE);
+	iebuf = ie.wpa_ie;
+	/* madwifi seems to return some random data if WPA/RSN IE is not set.
+	 * Assume the IE was not included if the IE type is unknown. */
+	if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)
+		iebuf[1] = 0;
+	if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {
+		/* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
+		 * set. This is needed for WPA2. */
+		iebuf = ie.rsn_ie;
+		if (iebuf[0] != WLAN_EID_RSN)
+			iebuf[1] = 0;
+	}
+
+	ielen = iebuf[1];
+	if (ielen == 0)
+		iebuf = NULL;
+	else
+		ielen += 2;
+
+no_ie:
+	res = hostapd_notif_assoc(hapd, addr, iebuf, ielen);
+
+	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));
+	}
+
+	return res;
+}
+
+static void
+madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,
+				       char *custom, char *end)
+{
+	wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
+
+	if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
+		char *pos;
+		u8 addr[ETH_ALEN];
+		pos = strstr(custom, "addr=");
+		if (pos == NULL) {
+			wpa_printf(MSG_DEBUG,
+				   "MLME-MICHAELMICFAILURE.indication "
+				   "without sender address ignored");
+			return;
+		}
+		pos += 5;
+		if (hwaddr_aton(pos, addr) == 0) {
+			hostapd_michael_mic_failure(drv->hapd, addr);
+		} else {
+			wpa_printf(MSG_DEBUG,
+				   "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;
+		}
+#ifdef CONFIG_WPS
+	} else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) {
+		/* Some atheros kernels send push button as a wireless event */
+		/* PROBLEM! this event is received for ALL BSSs ...
+		 * so all are enabled for WPS... ugh.
+		 */
+		hostapd_wps_button_pushed(drv->hapd);
+	} else if (strncmp(custom, "Manage.prob_req ", 16) == 0) {
+		/*
+		 * Atheros driver uses a hack to pass Probe Request frames as a
+		 * binary data in the custom wireless event. The old way (using
+		 * packet sniffing) didn't work when bridging.
+		 * Format: "Manage.prob_req <frame len>" | zero padding | frame
+		 */
+#define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */
+		int len = atoi(custom + 16);
+		if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) {
+			wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event "
+				   "length %d", len);
+			return;
+		}
+		madwifi_raw_receive(drv, NULL,
+				    (u8 *) custom + WPS_FRAM_TAG_SIZE, len);
+#endif /* CONFIG_WPS */
+	}
+}
+
+static void
+madwifi_wireless_event_wireless(struct madwifi_driver_data *drv,
+				char *data, int len)
+{
+	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);
+		wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d",
+			   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 == IWEVASSOCREQIE ||
+		     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:
+			hostapd_notif_disassoc(drv->hapd,
+					       (u8 *) iwe->u.addr.sa_data);
+			break;
+		case IWEVREGISTERED:
+			madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data);
+			break;
+		case IWEVASSOCREQIE:
+			/* Driver hack.. Use IWEVASSOCREQIE to bypass
+			 * IWEVCUSTOM size limitations. Need to handle this
+			 * just like IWEVCUSTOM.
+			 */
+		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, buf + iwe->u.data.length);
+			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 < (int) 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 >= (int) 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 = os_zalloc(buflen);
+	if (range == NULL)
+		return -1;
+
+	memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(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, const u8 *addr, const u8 *data, size_t data_len,
+		   int encrypt, const u8 *own_addr)
+{
+	struct madwifi_driver_data *drv = priv;
+	unsigned char buf[3000];
+	unsigned char *bp = buf;
+	struct l2_ethhdr *eth;
+	size_t len;
+	int status;
+
+	/*
+	 * Prepend the Ethernet 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, own_addr, ETH_ALEN);
+	eth->h_proto = host_to_be16(ETH_P_EAPOL);
+	memcpy(eth+1, data, data_len);
+
+	wpa_hexdump(MSG_MSGDUMP, "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_eapol_receive(drv->hapd, src_addr,
+			      buf + sizeof(struct l2_ethhdr),
+			      len - sizeof(struct l2_ethhdr));
+}
+
+static void *
+madwifi_init(struct hostapd_data *hapd)
+{
+	struct madwifi_driver_data *drv;
+	struct ifreq ifr;
+	struct iwreq iwr;
+
+	drv = os_zalloc(sizeof(struct madwifi_driver_data));
+	if (drv == NULL) {
+		printf("Could not allocate memory for madwifi driver data\n");
+		return NULL;
+	}
+
+	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));
+	os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
+	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') {
+		wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
+			   hapd->conf->bridge);
+		drv->sock_recv = l2_packet_init(hapd->conf->bridge, NULL,
+						ETH_P_EAPOL, handle_read, drv,
+						1);
+		if (drv->sock_recv == NULL)
+			goto bad;
+	} else
+		drv->sock_recv = drv->sock_xmit;
+
+	memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(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 */
+	madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */
+
+	madwifi_receive_probe_req(drv);
+
+	return drv;
+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 NULL;
+}
+
+
+static void
+madwifi_deinit(void *priv)
+{
+	struct madwifi_driver_data *drv = priv;
+
+	(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);
+	if (drv->sock_raw)
+		l2_packet_deinit(drv->sock_raw);
+	free(drv);
+}
+
+static int
+madwifi_set_ssid(const char *ifname, void *priv, const u8 *buf, int len)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct iwreq iwr;
+
+	memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(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(const char *ifname, void *priv, u8 *buf, int len)
+{
+	struct madwifi_driver_data *drv = priv;
+	struct iwreq iwr;
+	int ret = 0;
+
+	memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(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 int
+madwifi_set_countermeasures(void *priv, int enabled)
+{
+	struct madwifi_driver_data *drv = priv;
+	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
+	return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled);
+}
+
+static int
+madwifi_commit(void *priv)
+{
+	return madwifi_set_iface_flags(priv, 1);
+}
+
+const struct wpa_driver_ops wpa_driver_atheros_ops = {
+	.name			= "atheros",
+	.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,
+	.sta_set_flags		= madwifi_sta_set_flags,
+	.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,
+	.set_countermeasures	= madwifi_set_countermeasures,
+	.sta_clear_stats	= madwifi_sta_clear_stats,
+	.commit			= madwifi_commit,
+	.set_wps_beacon_ie	= madwifi_set_wps_beacon_ie,
+	.set_wps_probe_resp_ie	= madwifi_set_wps_probe_resp_ie,
+};

Modified: hostapd/branches/upstream/current/hostapd/driver_bsd.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/driver_bsd.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/driver_bsd.c (original)
+++ hostapd/branches/upstream/current/hostapd/driver_bsd.c Mon Mar 23 15:39:23 2009
@@ -29,6 +29,7 @@
 #undef RSN_VERSION
 #undef WPA_VERSION
 #undef WPA_OUI_TYPE
+#undef WME_OUI_TYPE
 
 #include "hostapd.h"
 #include "driver.h"

Modified: hostapd/branches/upstream/current/hostapd/driver_madwifi.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/driver_madwifi.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/driver_madwifi.c (original)
+++ hostapd/branches/upstream/current/hostapd/driver_madwifi.c Mon Mar 23 15:39:23 2009
@@ -877,14 +877,14 @@
 	}
 	wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE",
 		    ie.wpa_ie, IEEE80211_MAX_OPT_IE);
-	wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE",
-		    ie.rsn_ie, IEEE80211_MAX_OPT_IE);
 	iebuf = ie.wpa_ie;
 	/* madwifi seems to return some random data if WPA/RSN IE is not set.
 	 * Assume the IE was not included if the IE type is unknown. */
 	if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)
 		iebuf[1] = 0;
 #ifdef MADWIFI_NG
+	wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE",
+		    ie.rsn_ie, IEEE80211_MAX_OPT_IE);
 	if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {
 		/* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
 		 * set. This is needed for WPA2. */

Modified: hostapd/branches/upstream/current/hostapd/driver_nl80211.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/driver_nl80211.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/driver_nl80211.c (original)
+++ hostapd/branches/upstream/current/hostapd/driver_nl80211.c Mon Mar 23 15:39:23 2009
@@ -682,6 +682,8 @@
 		[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
 	};
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
@@ -710,7 +712,13 @@
 	if (stats[NL80211_STA_INFO_RX_BYTES])
 		data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
 	if (stats[NL80211_STA_INFO_TX_BYTES])
-		data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
+		data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
+	if (stats[NL80211_STA_INFO_RX_PACKETS])
+		data->rx_packets =
+			nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
+	if (stats[NL80211_STA_INFO_TX_PACKETS])
+		data->tx_packets =
+			nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
 
 	return NL_SKIP;
 }
@@ -721,6 +729,7 @@
 	struct i802_driver_data *drv = priv;
 	struct nl_msg *msg;
 
+	os_memset(data, 0, sizeof(*data));
 	msg = nlmsg_alloc();
 	if (!msg)
 		return -ENOMEM;
@@ -837,6 +846,9 @@
 #endif /* CONFIG_IEEE80211N */
 
 	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+	if (ret)
+		wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_NEW_STATION "
+			   "result: %d (%s)", ret, strerror(-ret));
 	if (ret == -EEXIST)
 		ret = 0;
  nla_put_failure:

Modified: hostapd/branches/upstream/current/hostapd/driver_prism54.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/driver_prism54.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/driver_prism54.c (original)
+++ hostapd/branches/upstream/current/hostapd/driver_prism54.c Mon Mar 23 15:39:23 2009
@@ -1052,7 +1052,7 @@
 	}
 	prism54_init_1x(drv);
 	/* must clean previous elems */
-	hostapd_set_generic_elem(hapd, NULL, 0);
+	prism54_set_generic_elem(drv->iface, drv, NULL, 0);
 
 	return drv;
 }

Modified: hostapd/branches/upstream/current/hostapd/drivers.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/drivers.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/drivers.c (original)
+++ hostapd/branches/upstream/current/hostapd/drivers.c Mon Mar 23 15:39:23 2009
@@ -27,6 +27,9 @@
 #ifdef CONFIG_DRIVER_MADWIFI
 extern struct wpa_driver_ops wpa_driver_madwifi_ops; /* driver_madwifi.c */
 #endif /* CONFIG_DRIVER_MADWIFI */
+#ifdef CONFIG_DRIVER_ATHEROS
+extern struct wpa_driver_ops wpa_driver_atheros_ops; /* driver_atheros.c */
+#endif /* CONFIG_DRIVER_ATHEROS */
 #ifdef CONFIG_DRIVER_BSD
 extern struct wpa_driver_ops wpa_driver_bsd_ops; /* driver_bsd.c */
 #endif /* CONFIG_DRIVER_BSD */
@@ -55,6 +58,9 @@
 #ifdef CONFIG_DRIVER_MADWIFI
 	&wpa_driver_madwifi_ops,
 #endif /* CONFIG_DRIVER_MADWIFI */
+#ifdef CONFIG_DRIVER_ATHEROS
+	&wpa_driver_atheros_ops,
+#endif /* CONFIG_DRIVER_ATHEROS */
 #ifdef CONFIG_DRIVER_BSD
 	&wpa_driver_bsd_ops,
 #endif /* CONFIG_DRIVER_BSD */

Modified: hostapd/branches/upstream/current/hostapd/hostapd.8
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/hostapd.8?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/hostapd.8 (original)
+++ hostapd/branches/upstream/current/hostapd/hostapd.8 Mon Mar 23 15:39:23 2009
@@ -3,7 +3,7 @@
 hostapd \- IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
 .SH SYNOPSIS
 .B hostapd
-[-hdBKtv] [-P <PID file>] <configuration file(s)>
+[\-hdBKtv] [\-P <PID file>] <configuration file(s)>
 .SH DESCRIPTION
 This manual page documents briefly the
 .B hostapd

Modified: hostapd/branches/upstream/current/hostapd/hostapd.conf
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/hostapd.conf?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/hostapd.conf (original)
+++ hostapd/branches/upstream/current/hostapd/hostapd.conf Mon Mar 23 15:39:23 2009
@@ -245,14 +245,14 @@
 #tx_queue_beacon_cwmax=7
 #tx_queue_beacon_burst=1.5
 
-# 802.1D Tag to AC mappings
+# 802.1D Tag (= UP) to AC mappings
 # WMM specifies following mapping of data frames to different ACs. This mapping
 # can be configured using Linux QoS/tc and sch_pktpri.o module.
 # 802.1D Tag	802.1D Designation	Access Category	WMM Designation
 # 1		BK			AC_BK		Background
 # 2		-			AC_BK		Background
 # 0		BE			AC_BE		Best Effort
-# 3		EE			AC_VI		Video
+# 3		EE			AC_BE		Best Effort
 # 4		CL			AC_VI		Video
 # 5		VI			AC_VI		Video
 # 6		VO			AC_VO		Voice

Modified: hostapd/branches/upstream/current/hostapd/hostapd_cli.1
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/hostapd_cli.1?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/hostapd_cli.1 (original)
+++ hostapd/branches/upstream/current/hostapd/hostapd_cli.1 Mon Mar 23 15:39:23 2009
@@ -3,7 +3,7 @@
 hostapd_cli \- hostapd command-line interface
 .SH SYNOPSIS
 .B hostapd_cli
-[-p<path>] [-i<ifname>] [-hv] [command..]
+[\-p<path>] [\-i<ifname>] [\-hv] [command..]
 .SH DESCRIPTION
 This manual page documents briefly the
 .B hostapd_cli

Modified: hostapd/branches/upstream/current/hostapd/ieee802_11.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/ieee802_11.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/ieee802_11.c (original)
+++ hostapd/branches/upstream/current/hostapd/ieee802_11.c Mon Mar 23 15:39:23 2009
@@ -1527,6 +1527,34 @@
 }
 
 
+#ifdef CONFIG_IEEE80211N
+static void
+hostapd_get_ht_capab(struct hostapd_data *hapd,
+		     struct ht_cap_ie *ht_cap_ie,
+		     struct ht_cap_ie *neg_ht_cap_ie)
+{
+
+	os_memcpy(neg_ht_cap_ie, ht_cap_ie, sizeof(struct ht_cap_ie));
+	neg_ht_cap_ie->data.capabilities_info =
+		ht_cap_ie->data.capabilities_info & hapd->iconf->ht_capab;
+
+	neg_ht_cap_ie->data.capabilities_info &= ~HT_CAP_INFO_SMPS_DISABLED;
+	if ((ht_cap_ie->data.capabilities_info & HT_CAP_INFO_SMPS_DISABLED) ==
+	    (hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED))
+		neg_ht_cap_ie->data.capabilities_info |=
+			hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED;
+	else
+		neg_ht_cap_ie->data.capabilities_info |=
+			HT_CAP_INFO_SMPS_DISABLED;
+
+	/* FIXME: Rx STBC needs to be handled specially */
+	neg_ht_cap_ie->data.capabilities_info &= ~HT_CAP_INFO_RX_STBC_MASK;
+	neg_ht_cap_ie->data.capabilities_info |=
+		hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK;
+}
+#endif /* CONFIG_IEEE80211N */
+
+
 static void handle_assoc_cb(struct hostapd_data *hapd,
 			    struct ieee80211_mgmt *mgmt,
 			    size_t len, int reassoc, int ok)
@@ -1534,7 +1562,10 @@
 	u16 status;
 	struct sta_info *sta;
 	int new_assoc = 1;
-	struct ht_cap_ie *ht_cap = NULL;
+#ifdef CONFIG_IEEE80211N
+	struct ht_cap_ie ht_cap;
+#endif /* CONFIG_IEEE80211N */
+	struct ht_cap_ie *ht_cap_ptr = NULL;
 
 	if (!ok) {
 		hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
@@ -1584,8 +1615,10 @@
 		mlme_associate_indication(hapd, sta);
 
 #ifdef CONFIG_IEEE80211N
-	if (sta->flags & WLAN_STA_HT)
-		ht_cap = &sta->ht_capabilities;
+	if (sta->flags & WLAN_STA_HT) {
+		ht_cap_ptr = &ht_cap;
+		hostapd_get_ht_capab(hapd, &sta->ht_capabilities, ht_cap_ptr);
+	}
 #endif /* CONFIG_IEEE80211N */
 
 #ifdef CONFIG_IEEE80211W
@@ -1595,7 +1628,7 @@
 	if (hostapd_sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid,
 			    sta->capability, sta->supported_rates,
 			    sta->supported_rates_len, 0, sta->listen_interval,
-			    ht_cap))
+			    ht_cap_ptr))
 	{
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_NOTICE,

Modified: hostapd/branches/upstream/current/hostapd/wme.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/wme.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/wme.c (original)
+++ hostapd/branches/upstream/current/hostapd/wme.c Mon Mar 23 15:39:23 2009
@@ -153,40 +153,102 @@
 }
 
 
-/* given frame data payload size in bytes, and data_rate in bits per second
- * returns time to complete frame exchange */
-/* FIX: should not use floating point types */
-static double wme_frame_exchange_time(int bytes, int data_rate, int encryption,
-				      int cts_protection)
-{
-	/* TODO: account for MAC/PHY headers correctly */
-	/* TODO: account for encryption headers */
-	/* TODO: account for WDS headers */
-	/* TODO: account for CTS protection */
-	/* TODO: account for SIFS + ACK at minimum PHY rate */
-	return (bytes + 400) * 8.0 / data_rate;
-}
-
-
 static void wme_setup_request(struct hostapd_data *hapd,
 			      struct ieee80211_mgmt *mgmt,
 			      struct wme_tspec_info_element *tspec, size_t len)
 {
-	/* FIX: should not use floating point types */
-	double medium_time, pps;
-
-	/* TODO: account for airtime and answer no to tspec setup requests
-	 * when none left!! */
-
-	pps = (tspec->mean_data_rate / 8.0) / tspec->nominal_msdu_size;
-	medium_time = (tspec->surplus_bandwidth_allowance / 8) * pps *
-		wme_frame_exchange_time(tspec->nominal_msdu_size,
-					tspec->minimum_phy_rate, 0, 0);
-	tspec->medium_time = medium_time * 1000000.0 / 32.0;
+	u8 *end = ((u8 *) mgmt) + len;
+	int medium_time, pps, duration;
+	int up, psb, dir, tid;
+	u16 val, surplus;
+
+	if ((u8 *) (tspec + 1) > end) {
+		wpa_printf(MSG_DEBUG, "WMM: TSPEC overflow in ADDTS Request");
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "WMM: ADDTS Request (Dialog Token %d) for TSPEC "
+		   "from " MACSTR,
+		   mgmt->u.action.u.wme_action.dialog_token,
+		   MAC2STR(mgmt->sa));
+
+	up = (tspec->ts_info[1] >> 3) & 0x07;
+	psb = (tspec->ts_info[1] >> 2) & 0x01;
+	dir = (tspec->ts_info[0] >> 5) & 0x03;
+	tid = (tspec->ts_info[0] >> 1) & 0x0f;
+	wpa_printf(MSG_DEBUG, "WMM: TS Info: UP=%d PSB=%d Direction=%d TID=%d",
+		   up, psb, dir, tid);
+	val = le_to_host16(tspec->nominal_msdu_size);
+	wpa_printf(MSG_DEBUG, "WMM: Nominal MSDU Size: %d%s",
+		   val & 0x7fff, val & 0x8000 ? " (fixed)" : "");
+	wpa_printf(MSG_DEBUG, "WMM: Mean Data Rate: %u bps",
+		   le_to_host32(tspec->mean_data_rate));
+	wpa_printf(MSG_DEBUG, "WMM: Minimum PHY Rate: %u bps",
+		   le_to_host32(tspec->minimum_phy_rate));
+	val = le_to_host16(tspec->surplus_bandwidth_allowance);
+	wpa_printf(MSG_DEBUG, "WMM: Surplus Bandwidth Allowance: %u.%04u",
+		   val >> 13, 10000 * (val & 0x1fff) / 0x2000);
+
+	val = le_to_host16(tspec->nominal_msdu_size);
+	if (val == 0) {
+		wpa_printf(MSG_DEBUG, "WMM: Invalid Nominal MSDU Size (0)");
+		goto invalid;
+	}
+	/* pps = Ceiling((Mean Data Rate / 8) / Nominal MSDU Size) */
+	pps = ((le_to_host32(tspec->mean_data_rate) / 8) + val - 1) / val;
+	wpa_printf(MSG_DEBUG, "WMM: Packets-per-second estimate for TSPEC: %d",
+		   pps);
+
+	if (le_to_host32(tspec->minimum_phy_rate) < 1000000) {
+		wpa_printf(MSG_DEBUG, "WMM: Too small Minimum PHY Rate");
+		goto invalid;
+	}
+
+	duration = (le_to_host16(tspec->nominal_msdu_size) & 0x7fff) * 8 /
+		(le_to_host32(tspec->minimum_phy_rate) / 1000000) +
+		50 /* FIX: proper SIFS + ACK duration */;
+
+	/* unsigned binary number with an implicit binary point after the
+	 * leftmost 3 bits, i.e., 0x2000 = 1.0 */
+	surplus = le_to_host16(tspec->surplus_bandwidth_allowance);
+	if (surplus <= 0x2000) {
+		wpa_printf(MSG_DEBUG, "WMM: Surplus Bandwidth Allowance not "
+			   "greater than unity");
+		goto invalid;
+	}
+
+	medium_time = surplus * pps * duration / 0x2000;
+	wpa_printf(MSG_DEBUG, "WMM: Estimated medium time: %u", medium_time);
+
+	/*
+	 * TODO: store list of granted (and still active) TSPECs and check
+	 * whether there is available medium time for this request. For now,
+	 * just refuse requests that would by themselves take very large
+	 * portion of the available bandwidth.
+	 */
+	if (medium_time > 750000) {
+		wpa_printf(MSG_DEBUG, "WMM: Refuse TSPEC request for over "
+			   "75%% of available bandwidth");
+		wme_send_action(hapd, mgmt->sa, tspec,
+				WME_ACTION_CODE_SETUP_RESPONSE,
+				mgmt->u.action.u.wme_action.dialog_token,
+				WME_SETUP_RESPONSE_STATUS_REFUSED);
+		return;
+	}
+
+	/* Convert to 32 microseconds per second unit */
+	tspec->medium_time = host_to_le16(medium_time / 32);
 
 	wme_send_action(hapd, mgmt->sa, tspec, WME_ACTION_CODE_SETUP_RESPONSE,
 			mgmt->u.action.u.wme_action.dialog_token,
 			WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED);
+	return;
+
+invalid:
+	wme_send_action(hapd, mgmt->sa, tspec,
+			WME_ACTION_CODE_SETUP_RESPONSE,
+			mgmt->u.action.u.wme_action.dialog_token,
+			WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS);
 }
 
 

Modified: hostapd/branches/upstream/current/hostapd/wme.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/wme.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/wme.h (original)
+++ hostapd/branches/upstream/current/hostapd/wme.h Mon Mar 23 15:39:23 2009
@@ -86,27 +86,29 @@
 } __attribute__ ((packed));
 
 struct wme_tspec_info_element {
-	u8 eid;
-	u8 length;
-	u8 oui[3];
-	u8 oui_type;
-	u8 oui_subtype;
-	u8 version;
-	u16 ts_info;
-	u16 nominal_msdu_size;
-	u16 maximum_msdu_size;
-	u32 minimum_service_interval;
-	u32 maximum_service_interval;
-	u32 inactivity_interval;
-	u32 start_time;
-	u32 minimum_data_rate;
-	u32 mean_data_rate;
-	u32 maximum_burst_size;
-	u32 minimum_phy_rate;
-	u32 peak_data_rate;
-	u32 delay_bound;
-	u16 surplus_bandwidth_allowance;
-	u16 medium_time;
+	u8 eid; /* 221 = 0xdd */
+	u8 length; /* 6 + 55 = 61 */
+	u8 oui[3]; /* 00:50:f2 */
+	u8 oui_type; /* 2 */
+	u8 oui_subtype; /* 2 */
+	u8 version; /* 1 */
+	/* WMM TSPEC body (55 octets): */
+	u8 ts_info[3];
+	le16 nominal_msdu_size;
+	le16 maximum_msdu_size;
+	le32 minimum_service_interval;
+	le32 maximum_service_interval;
+	le32 inactivity_interval;
+	le32 suspension_interval;
+	le32 service_start_time;
+	le32 minimum_data_rate;
+	le32 mean_data_rate;
+	le32 peak_data_rate;
+	le32 maximum_burst_size;
+	le32 delay_bound;
+	le32 minimum_phy_rate;
+	le16 surplus_bandwidth_allowance;
+	le16 medium_time;
 } __attribute__ ((packed));
 
 

Modified: hostapd/branches/upstream/current/hostapd/wps_hostapd.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/hostapd/wps_hostapd.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/hostapd/wps_hostapd.c (original)
+++ hostapd/branches/upstream/current/hostapd/wps_hostapd.c Mon Mar 23 15:39:23 2009
@@ -326,15 +326,21 @@
 		else
 			fprintf(nconf, "auth_algs=1\n");
 
-		if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx < 4) {
-			fprintf(nconf, "wep_default_key=%d\n", cred->key_idx);
-			fprintf(nconf, "wep_key%d=", cred->key_idx);
-			if (cred->key_len != 10 && cred->key_len != 26)
-				fputc('"', nconf);
-			for (i = 0; i < cred->key_len; i++)
-				fputc(cred->key[i], nconf);
-			if (cred->key_len != 10 && cred->key_len != 26)
-				fputc('"', nconf);
+		if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx <= 4) {
+			int key_idx = cred->key_idx;
+			if (key_idx)
+				key_idx--;
+			fprintf(nconf, "wep_default_key=%d\n", key_idx);
+			fprintf(nconf, "wep_key%d=", key_idx);
+			if (cred->key_len == 10 || cred->key_len == 26) {
+				/* WEP key as a hex string */
+				for (i = 0; i < cred->key_len; i++)
+					fputc(cred->key[i], nconf);
+			} else {
+				/* Raw WEP key; convert to hex */
+				for (i = 0; i < cred->key_len; i++)
+					fprintf(nconf, "%02x", cred->key[i]);
+			}
 			fprintf(nconf, "\n");
 		}
 	}
@@ -620,6 +626,8 @@
 	cfg.extra_cred_len = conf->extra_cred_len;
 	cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) &&
 		conf->skip_cred_build;
+	if (conf->ssid.security_policy == SECURITY_STATIC_WEP)
+		cfg.static_wep_only = 1;
 
 	wps->registrar = wps_registrar_init(wps, &cfg);
 	if (wps->registrar == NULL) {

Modified: hostapd/branches/upstream/current/src/common/ieee802_11_defs.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/common/ieee802_11_defs.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/common/ieee802_11_defs.h (original)
+++ hostapd/branches/upstream/current/src/common/ieee802_11_defs.h Mon Mar 23 15:39:23 2009
@@ -134,10 +134,9 @@
 #define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51
 /* IEEE 802.11r */
 #define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52
-#define WLAN_STATUS_EXPECTED_RESOURCE_REQ_FT 53
-#define WLAN_STATUS_INVALID_PMKID 54
-#define WLAN_STATUS_INVALID_MDIE 55
-#define WLAN_STATUS_INVALID_FTIE 56
+#define WLAN_STATUS_INVALID_PMKID 53
+#define WLAN_STATUS_INVALID_MDIE 54
+#define WLAN_STATUS_INVALID_FTIE 55
 
 /* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) */
 #define WLAN_REASON_UNSPECIFIED 1

Modified: hostapd/branches/upstream/current/src/common/nl80211_copy.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/common/nl80211_copy.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/common/nl80211_copy.h (original)
+++ hostapd/branches/upstream/current/src/common/nl80211_copy.h Mon Mar 23 15:39:23 2009
@@ -526,6 +526,9 @@
  * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
  * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
  * 	containing info as possible, see &enum nl80211_sta_info_txrate.
+ * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station)
+ * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this
+ *	station)
  */
 enum nl80211_sta_info {
 	__NL80211_STA_INFO_INVALID,
@@ -537,6 +540,8 @@
 	NL80211_STA_INFO_PLINK_STATE,
 	NL80211_STA_INFO_SIGNAL,
 	NL80211_STA_INFO_TX_BITRATE,
+	NL80211_STA_INFO_RX_PACKETS,
+	NL80211_STA_INFO_TX_PACKETS,
 
 	/* keep last */
 	__NL80211_STA_INFO_AFTER_LAST,

Modified: hostapd/branches/upstream/current/src/common/version.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/common/version.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/common/version.h (original)
+++ hostapd/branches/upstream/current/src/common/version.h Mon Mar 23 15:39:23 2009
@@ -1,6 +1,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define VERSION_STR "0.6.8"
+#define VERSION_STR "0.6.9"
 
 #endif /* VERSION_H */

Modified: hostapd/branches/upstream/current/src/common/wpa_common.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/common/wpa_common.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/common/wpa_common.c (original)
+++ hostapd/branches/upstream/current/src/common/wpa_common.c Mon Mar 23 15:39:23 2009
@@ -56,10 +56,10 @@
 		hmac_sha1(key, 16, buf, len, hash);
 		os_memcpy(mic, hash, MD5_MAC_LEN);
 		break;
-#ifdef CONFIG_IEEE80211R
+#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
 	case WPA_KEY_INFO_TYPE_AES_128_CMAC:
 		return omac1_aes_128(key, buf, len, mic);
-#endif /* CONFIG_IEEE80211R */
+#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
 	default:
 		return -1;
 	}

Modified: hostapd/branches/upstream/current/src/crypto/crypto_gnutls.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/crypto/crypto_gnutls.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/crypto/crypto_gnutls.c (original)
+++ hostapd/branches/upstream/current/src/crypto/crypto_gnutls.c Mon Mar 23 15:39:23 2009
@@ -57,7 +57,6 @@
 }
 
 
-#ifdef EAP_TLS_FUNCS
 void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
 	gcry_md_hd_t hd;
@@ -162,7 +161,6 @@
 	gcry_cipher_hd_t hd = ctx;
 	gcry_cipher_close(hd);
 }
-#endif /* EAP_TLS_FUNCS */
 
 
 int crypto_mod_exp(const u8 *base, size_t base_len,

Modified: hostapd/branches/upstream/current/src/crypto/crypto_internal.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/crypto/crypto_internal.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/crypto/crypto_internal.c (original)
+++ hostapd/branches/upstream/current/src/crypto/crypto_internal.c Mon Mar 23 15:39:23 2009
@@ -25,7 +25,7 @@
 #include "tls/asn1.h"
 
 
-#ifdef EAP_TLS_FUNCS
+#ifdef CONFIG_CRYPTO_INTERNAL
 
 #ifdef CONFIG_TLS_INTERNAL
 
@@ -788,6 +788,7 @@
 void crypto_global_deinit(void)
 {
 }
+#endif /* CONFIG_TLS_INTERNAL */
 
 
 #if defined(EAP_FAST) || defined(CONFIG_WPS)
@@ -830,6 +831,4 @@
 #endif /* EAP_FAST || CONFIG_WPS */
 
 
-#endif /* CONFIG_TLS_INTERNAL */
-
-#endif /* EAP_TLS_FUNCS */
+#endif /* CONFIG_CRYPTO_INTERNAL */

Modified: hostapd/branches/upstream/current/src/crypto/sha256.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/crypto/sha256.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/crypto/sha256.c (original)
+++ hostapd/branches/upstream/current/src/crypto/sha256.c Mon Mar 23 15:39:23 2009
@@ -122,7 +122,7 @@
 void sha256_prf(const u8 *key, size_t key_len, const char *label,
 		const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
 {
-	u16 counter = 0;
+	u16 counter = 1;
 	size_t pos, plen;
 	u8 hash[SHA256_MAC_LEN];
 	const u8 *addr[4];

Modified: hostapd/branches/upstream/current/src/crypto/tls_gnutls.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/crypto/tls_gnutls.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/crypto/tls_gnutls.c (original)
+++ hostapd/branches/upstream/current/src/crypto/tls_gnutls.c Mon Mar 23 15:39:23 2009
@@ -989,11 +989,13 @@
 			return NULL;
 		}
 
+#ifdef CONFIG_GNUTLS_EXTRA
 		if (conn->tls_ia && !gnutls_ia_handshake_p(conn->session)) {
 			wpa_printf(MSG_INFO, "TLS: No TLS/IA negotiation");
 			conn->failed++;
 			return NULL;
 		}
+#endif /* CONFIG_GNUTLS_EXTRA */
 
 		if (conn->tls_ia)
 			wpa_printf(MSG_DEBUG, "TLS: Start TLS/IA handshake");

Modified: hostapd/branches/upstream/current/src/drivers/driver_bsd.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/drivers/driver_bsd.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/drivers/driver_bsd.c (original)
+++ hostapd/branches/upstream/current/src/drivers/driver_bsd.c Mon Mar 23 15:39:23 2009
@@ -177,7 +177,7 @@
 }
 
 static int
-wpa_driver_bsd_set_ssid(void *priv, const char *ssid,
+wpa_driver_bsd_set_ssid(void *priv, const u8 *ssid,
 			     size_t ssid_len)
 {
 	struct wpa_driver_bsd_data *drv = priv;
@@ -187,7 +187,7 @@
 
 static int
 wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv,
-	const char *wpa_ie, size_t wpa_ie_len)
+	const u8 *wpa_ie, size_t wpa_ie_len)
 {
 	return set80211var(drv, IEEE80211_IOC_OPTIE, wpa_ie, wpa_ie_len);
 }

Modified: hostapd/branches/upstream/current/src/drivers/driver_ndis.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/drivers/driver_ndis.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/drivers/driver_ndis.c (original)
+++ hostapd/branches/upstream/current/src/drivers/driver_ndis.c Mon Mar 23 15:39:23 2009
@@ -54,6 +54,10 @@
 static int wpa_driver_ndis_adapter_init(struct wpa_driver_ndis_data *drv);
 static int wpa_driver_ndis_adapter_open(struct wpa_driver_ndis_data *drv);
 static void wpa_driver_ndis_adapter_close(struct wpa_driver_ndis_data *drv);
+
+
+static const u8 pae_group_addr[ETH_ALEN] =
+{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 };
 
 
 /* FIX: to be removed once this can be compiled with the complete NDIS
@@ -610,12 +614,7 @@
 		 * Report PAE group address as the "BSSID" for wired
 		 * connection.
 		 */
-		bssid[0] = 0x01;
-		bssid[1] = 0x80;
-		bssid[2] = 0xc2;
-		bssid[3] = 0x00;
-		bssid[4] = 0x00;
-		bssid[5] = 0x03;
+		os_memcpy(bssid, pae_group_addr, ETH_ALEN);
 		return 0;
 	}
 
@@ -2704,6 +2703,19 @@
 }
 
 
+static int ndis_add_multicast(struct wpa_driver_ndis_data *drv)
+{
+	if (ndis_set_oid(drv, OID_802_3_MULTICAST_LIST,
+			 (const char *) pae_group_addr, ETH_ALEN) < 0) {
+		wpa_printf(MSG_DEBUG, "NDIS: Failed to add PAE group address "
+			   "to the multicast list");
+		return -1;
+	}
+
+	return 0;
+}
+
+
 static void * wpa_driver_ndis_init(void *ctx, const char *ifname)
 {
 	struct wpa_driver_ndis_data *drv;
@@ -2799,6 +2811,7 @@
 				   "any wireless capabilities - assume it is "
 				   "a wired interface");
 			drv->wired = 1;
+			ndis_add_multicast(drv);
 		}
 	}
 

Modified: hostapd/branches/upstream/current/src/eap_common/eap_defs.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_common/eap_defs.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_common/eap_defs.h (original)
+++ hostapd/branches/upstream/current/src/eap_common/eap_defs.h Mon Mar 23 15:39:23 2009
@@ -67,7 +67,7 @@
 	EAP_TYPE_SAKE = 48 /* RFC 4763 */,
 	EAP_TYPE_IKEV2 = 49 /* RFC 5106 */,
 	EAP_TYPE_AKA_PRIME = 50 /* draft-arkko-eap-aka-kdf-10.txt */,
-	EAP_TYPE_GPSK = 51 /* draft-ietf-emu-eap-gpsk-17.txt */,
+	EAP_TYPE_GPSK = 51 /* RFC 5433 */,
 	EAP_TYPE_EXPANDED = 254 /* RFC 3748 */
 } EapType;
 

Modified: hostapd/branches/upstream/current/src/eap_common/eap_fast_common.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_common/eap_fast_common.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_common/eap_fast_common.h (original)
+++ hostapd/branches/upstream/current/src/eap_common/eap_fast_common.h Mon Mar 23 15:39:23 2009
@@ -24,8 +24,7 @@
 #define TLS_EXT_PAC_OPAQUE 35
 
 /*
- * draft-cam-winget-eap-fast-provisioning-04.txt:
- * Section 4.2.1 - Formats for PAC TLV Attributes / Type Field
+ * RFC 5422: Section 4.2.1 - Formats for PAC TLV Attributes / Type Field
  * Note: bit 0x8000 (Mandatory) and bit 0x4000 (Reserved) are also defined
  * in the general PAC TLV format (Section 4.2).
  */
@@ -59,10 +58,7 @@
 
 #define EAP_FAST_PAC_KEY_LEN 32
 
-/* draft-cam-winget-eap-fast-provisioning-04.txt: 4.2.6 PAC-Type TLV
- * Note: Machine Authentication PAC and User Authorization PAC were removed in
- * draft-cam-winget-eap-fast-provisioning-03.txt
- */
+/* RFC 5422: 4.2.6 PAC-Type TLV */
 #define PAC_TYPE_TUNNEL_PAC 1
 /* Application Specific Short Lived PACs (only in volatile storage) */
 /* User Authorization PAC */
@@ -73,8 +69,8 @@
 
 
 /*
- * draft-cam-winget-eap-fast-provisioning-04.txt:
- * Section 3.4 - Key Derivations Used in the EAP-FAST Provisioning Exchange
+ * RFC 5422:
+ * Section 3.3 - Key Derivations Used in the EAP-FAST Provisioning Exchange
  */
 struct eap_fast_key_block_provisioning {
 	/* Extra key material after TLS key_block */

Modified: hostapd/branches/upstream/current/src/eap_common/eap_tlv_common.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_common/eap_tlv_common.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_common/eap_tlv_common.h (original)
+++ hostapd/branches/upstream/current/src/eap_common/eap_tlv_common.h Mon Mar 23 15:39:23 2009
@@ -24,8 +24,7 @@
 #define EAP_TLV_URI_TLV 8
 #define EAP_TLV_EAP_PAYLOAD_TLV 9
 #define EAP_TLV_INTERMEDIATE_RESULT_TLV 10
-#define EAP_TLV_PAC_TLV 11 /* draft-cam-winget-eap-fast-provisioning-04.txt,
-			    * Section 4.2 */
+#define EAP_TLV_PAC_TLV 11 /* RFC 5422, Section 4.2 */
 #define EAP_TLV_CRYPTO_BINDING_TLV 12
 #define EAP_TLV_CALLING_STATION_ID_TLV 13
 #define EAP_TLV_CALLED_STATION_ID_TLV 14
@@ -99,7 +98,7 @@
 	be16 action;
 } STRUCT_PACKED;
 
-/* draft-cam-winget-eap-fast-provisiong-04.txt, Section 4.2.6 - PAC-Type TLV */
+/* RFC 5422, Section 4.2.6 - PAC-Type TLV */
 struct eap_tlv_pac_type_tlv {
 	be16 tlv_type; /* PAC_TYPE_PAC_TYPE */
 	be16 length;

Modified: hostapd/branches/upstream/current/src/eap_peer/eap_fast.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_peer/eap_fast.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_peer/eap_fast.c (original)
+++ hostapd/branches/upstream/current/src/eap_peer/eap_fast.c Mon Mar 23 15:39:23 2009
@@ -918,10 +918,7 @@
 		entry->a_id_info_len = len;
 		break;
 	case PAC_TYPE_PAC_TYPE:
-		/*
-		 * draft-cam-winget-eap-fast-provisioning-04.txt,
-		 * Section 4.2.6 - PAC-Type TLV
-		 */
+		/* RFC 5422, Section 4.2.6 - PAC-Type TLV */
 		if (len != 2) {
 			wpa_printf(MSG_INFO, "EAP-FAST: Invalid PAC-Type "
 				   "length %lu (expected 2)",
@@ -961,7 +958,7 @@
 	size_t left, len;
 	int type;
 
-	/* draft-cam-winget-eap-fast-provisioning-04.txt, Section 4.2.4 */
+	/* RFC 5422, Section 4.2.4 */
 
 	/* PAC-Type defaults to Tunnel PAC (Type 1) */
 	entry->pac_type = PAC_TYPE_TUNNEL_PAC;

Modified: hostapd/branches/upstream/current/src/eap_peer/eap_gpsk.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_peer/eap_gpsk.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_peer/eap_gpsk.c (original)
+++ hostapd/branches/upstream/current/src/eap_peer/eap_gpsk.c Mon Mar 23 15:39:23 2009
@@ -1,5 +1,5 @@
 /*
- * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt)
+ * EAP peer method: EAP-GPSK (RFC 5433)
  * Copyright (c) 2006-2008, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify

Modified: hostapd/branches/upstream/current/src/eap_peer/eap_tnc.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_peer/eap_tnc.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_peer/eap_tnc.c (original)
+++ hostapd/branches/upstream/current/src/eap_peer/eap_tnc.c Mon Mar 23 15:39:23 2009
@@ -295,7 +295,7 @@
 			wpa_printf(MSG_DEBUG, "EAP-TNC: Server did not use "
 				   "start flag in the first message");
 			ret->ignore = TRUE;
-			return NULL;
+			goto fail;
 		}
 
 		tncc_init_connection(data->tncc);
@@ -308,7 +308,7 @@
 			wpa_printf(MSG_DEBUG, "EAP-TNC: Server used start "
 				   "flag again");
 			ret->ignore = TRUE;
-			return NULL;
+			goto fail;
 		}
 
 		res = tncc_process_if_tnccs(data->tncc,
@@ -317,7 +317,7 @@
 		switch (res) {
 		case TNCCS_PROCESS_ERROR:
 			ret->ignore = TRUE;
-			return NULL;
+			goto fail;
 		case TNCCS_PROCESS_OK_NO_RECOMMENDATION:
 		case TNCCS_RECOMMENDATION_ERROR:
 			wpa_printf(MSG_DEBUG, "EAP-TNC: No "
@@ -404,6 +404,11 @@
 	data->out_buf = resp;
 	data->state = PROC_MSG;
 	return eap_tnc_build_msg(data, ret, id);
+
+fail:
+	if (data->in_buf == &tmpbuf)
+		data->in_buf = NULL;
+	return NULL;
 }
 
 

Modified: hostapd/branches/upstream/current/src/eap_server/eap.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_server/eap.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_server/eap.c (original)
+++ hostapd/branches/upstream/current/src/eap_server/eap.c Mon Mar 23 15:39:23 2009
@@ -573,6 +573,13 @@
 	}
 
 	sm->eap_if.eapSuccess = TRUE;
+
+	/*
+	 * Start reauthentication with identity request even though we know the
+	 * previously used identity. This is needed to get reauthentication
+	 * started properly.
+	 */
+	sm->start_reauth = TRUE;
 }
 
 
@@ -1070,7 +1077,7 @@
 
 static int eap_sm_Policy_getDecision(struct eap_sm *sm)
 {
-	if (!sm->eap_server && sm->identity) {
+	if (!sm->eap_server && sm->identity && !sm->start_reauth) {
 		wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH");
 		return DECISION_PASSTHROUGH;
 	}
@@ -1091,7 +1098,8 @@
 		return DECISION_FAILURE;
 	}
 
-	if ((sm->user == NULL || sm->update_user) && sm->identity) {
+	if ((sm->user == NULL || sm->update_user) && sm->identity &&
+	    !sm->start_reauth) {
 		/*
 		 * Allow Identity method to be started once to allow identity
 		 * selection hint to be sent from the authentication server,
@@ -1118,6 +1126,7 @@
 		}
 		sm->update_user = FALSE;
 	}
+	sm->start_reauth = FALSE;
 
 	if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
 	    (sm->user->methods[sm->user_eap_method_index].vendor !=

Modified: hostapd/branches/upstream/current/src/eap_server/eap_gpsk.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_server/eap_gpsk.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_server/eap_gpsk.c (original)
+++ hostapd/branches/upstream/current/src/eap_server/eap_gpsk.c Mon Mar 23 15:39:23 2009
@@ -1,5 +1,5 @@
 /*
- * hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt) server
+ * hostapd / EAP-GPSK (RFC 5433) server
  * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify

Modified: hostapd/branches/upstream/current/src/eap_server/eap_i.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_server/eap_i.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_server/eap_i.h (original)
+++ hostapd/branches/upstream/current/src/eap_server/eap_i.h Mon Mar 23 15:39:23 2009
@@ -183,6 +183,8 @@
 	int tnc;
 	struct wps_context *wps;
 	struct wpabuf *assoc_wps_ie;
+
+	Boolean start_reauth;
 };
 
 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,

Modified: hostapd/branches/upstream/current/src/eap_server/eap_tnc.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_server/eap_tnc.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_server/eap_tnc.c (original)
+++ hostapd/branches/upstream/current/src/eap_server/eap_tnc.c Mon Mar 23 15:39:23 2009
@@ -500,7 +500,7 @@
 static Boolean eap_tnc_isDone(struct eap_sm *sm, void *priv)
 {
 	struct eap_tnc_data *data = priv;
-	return data->state == DONE;
+	return data->state == DONE || data->state == FAIL;
 }
 
 

Modified: hostapd/branches/upstream/current/src/eap_server/eap_ttls.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eap_server/eap_ttls.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eap_server/eap_ttls.c (original)
+++ hostapd/branches/upstream/current/src/eap_server/eap_ttls.c Mon Mar 23 15:39:23 2009
@@ -954,7 +954,7 @@
 	sm->init_phase2 = 1;
 	data->phase2_priv = data->phase2_method->init(sm);
 	sm->init_phase2 = 0;
-	return 0;
+	return data->phase2_priv == NULL ? -1 : 0;
 }
 
 
@@ -1045,6 +1045,11 @@
 		next_type = sm->user->methods[0].method;
 		sm->user_eap_method_index = 1;
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
+		if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
+			wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize "
+				   "EAP type %d", next_type);
+			eap_ttls_state(data, FAILURE);
+		}
 		break;
 	case PHASE2_METHOD:
 		if (data->ttls_version > 0) {
@@ -1065,12 +1070,6 @@
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
 			   __func__, data->state);
 		break;
-	}
-
-	if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
-		wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize EAP "
-			   "type %d", next_type);
-		eap_ttls_state(data, FAILURE);
 	}
 }
 

Modified: hostapd/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c (original)
+++ hostapd/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c Mon Mar 23 15:39:23 2009
@@ -282,7 +282,12 @@
 		 * delay authentication. Use a short timeout to send the first
 		 * EAPOL-Start if Authenticator does not start authentication.
 		 */
+#ifdef CONFIG_WPS
+		/* Reduce latency on starting WPS negotiation. */
+		sm->startWhen = 1;
+#else /* CONFIG_WPS */
 		sm->startWhen = 3;
+#endif /* CONFIG_WPS */
 	}
 	eapol_enable_timer_tick(sm);
 	sm->eapolEap = FALSE;

Modified: hostapd/branches/upstream/current/src/l2_packet/l2_packet_linux.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/l2_packet/l2_packet_linux.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/l2_packet/l2_packet_linux.c (original)
+++ hostapd/branches/upstream/current/src/l2_packet/l2_packet_linux.c Mon Mar 23 15:39:23 2009
@@ -115,6 +115,7 @@
 		os_free(l2);
 		return NULL;
 	}
+	os_memset(&ifr, 0, sizeof(ifr));
 	os_strlcpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));
 	if (ioctl(l2->fd, SIOCGIFINDEX, &ifr) < 0) {
 		perror("ioctl[SIOCGIFINDEX]");

Modified: hostapd/branches/upstream/current/src/rsn_supp/wpa.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/rsn_supp/wpa.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/rsn_supp/wpa.c (original)
+++ hostapd/branches/upstream/current/src/rsn_supp/wpa.c Mon Mar 23 15:39:23 2009
@@ -1468,9 +1468,9 @@
 	key_info = WPA_GET_BE16(key->key_info);
 	ver = key_info & WPA_KEY_INFO_TYPE_MASK;
 	if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
-#ifdef CONFIG_IEEE80211R
+#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
 	    ver != WPA_KEY_INFO_TYPE_AES_128_CMAC &&
-#endif /* CONFIG_IEEE80211R */
+#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
 	    ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
 		wpa_printf(MSG_INFO, "WPA: Unsupported EAPOL-Key descriptor "
 			   "version %d.", ver);

Modified: hostapd/branches/upstream/current/src/tls/tlsv1_client.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/tls/tlsv1_client.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/tls/tlsv1_client.c (original)
+++ hostapd/branches/upstream/current/src/tls/tlsv1_client.c Mon Mar 23 15:39:23 2009
@@ -620,6 +620,17 @@
 		suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
 		suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
 		suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
+
+		/*
+		 * Cisco AP (at least 350 and 1200 series) local authentication
+		 * server does not know how to search cipher suites from the
+		 * list and seem to require that the last entry in the list is
+		 * the one that it wants to use. However, TLS specification
+		 * requires the list to be in the client preference order. As a
+		 * workaround, ass anon-DH AES-128-SHA1 again at the end of the
+		 * list to allow the Cisco code to find it.
+		 */
+		suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
 		conn->num_cipher_suites = count;
 	}
 

Modified: hostapd/branches/upstream/current/src/wps/wps.h
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/wps/wps.h?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/wps/wps.h (original)
+++ hostapd/branches/upstream/current/src/wps/wps.h Mon Mar 23 15:39:23 2009
@@ -266,6 +266,11 @@
 	 * to be set with a suitable Credential and skip_cred_build being used.
 	 */
 	int disable_auto_conf;
+
+	/**
+	 * static_wep_only - Whether the BSS supports only static WEP
+	 */
+	int static_wep_only;
 };
 
 

Modified: hostapd/branches/upstream/current/src/wps/wps_enrollee.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/wps/wps_enrollee.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/wps/wps_enrollee.c (original)
+++ hostapd/branches/upstream/current/src/wps/wps_enrollee.c Mon Mar 23 15:39:23 2009
@@ -41,7 +41,7 @@
 		   state);
 	wpabuf_put_be16(msg, ATTR_WPS_STATE);
 	wpabuf_put_be16(msg, 1);
-	wpabuf_put_u8(msg, WPS_STATE_NOT_CONFIGURED);
+	wpabuf_put_u8(msg, state);
 	return 0;
 }
 

Modified: hostapd/branches/upstream/current/src/wps/wps_registrar.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/wps/wps_registrar.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/wps/wps_registrar.c (original)
+++ hostapd/branches/upstream/current/src/wps/wps_registrar.c Mon Mar 23 15:39:23 2009
@@ -98,6 +98,7 @@
 	int disable_auto_conf;
 	int sel_reg_dev_password_id_override;
 	int sel_reg_config_methods_override;
+	int static_wep_only;
 };
 
 
@@ -376,6 +377,7 @@
 	reg->disable_auto_conf = cfg->disable_auto_conf;
 	reg->sel_reg_dev_password_id_override = -1;
 	reg->sel_reg_config_methods_override = -1;
+	reg->static_wep_only = cfg->static_wep_only;
 
 	if (wps_set_ie(reg)) {
 		wps_registrar_deinit(reg);
@@ -775,6 +777,28 @@
 		wpabuf_free(beacon);
 		wpabuf_free(probe);
 		return -1;
+	}
+
+	if (reg->static_wep_only) {
+		/*
+		 * Windows XP and Vista clients can get confused about
+		 * EAP-Identity/Request when they probe the network with
+		 * EAPOL-Start. In such a case, they may assume the network is
+		 * using IEEE 802.1X and prompt user for a certificate while
+		 * the correct (non-WPS) behavior would be to ask for the
+		 * static WEP key. As a workaround, use Microsoft Provisioning
+		 * IE to advertise that legacy 802.1X is not supported.
+		 */
+		const u8 ms_wps[7] = {
+			WLAN_EID_VENDOR_SPECIFIC, 5,
+			/* Microsoft Provisioning IE (00:50:f2:5) */
+			0x00, 0x50, 0xf2, 5,
+			0x00 /* no legacy 802.1X or MS WPS */
+		};
+		wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
+			   "into Beacon/Probe Response frames");
+		wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
+		wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
 	}
 
 	ret = wps_cb_set_ie(reg, beacon, probe);
@@ -2401,7 +2425,6 @@
  * wps_registrar_set_selected_registrar - Notification of SetSelectedRegistrar
  * @reg: Registrar data from wps_registrar_init()
  * @msg: Received message from SetSelectedRegistrar
- * @msg_len: Length of msg in octets
  * Returns: 0 on success, -1 on failure
  *
  * This function is called when an AP receives a SetSelectedRegistrar UPnP

Modified: hostapd/branches/upstream/current/src/wps/wps_upnp.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/wps/wps_upnp.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/wps/wps_upnp.c (original)
+++ hostapd/branches/upstream/current/src/wps/wps_upnp.c Mon Mar 23 15:39:23 2009
@@ -832,6 +832,50 @@
 }
 
 
+#ifdef __FreeBSD__
+#include <sys/sysctl.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+
+static int eth_get(const char *device, u8 ea[ETH_ALEN])
+{
+	struct if_msghdr *ifm;
+	struct sockaddr_dl *sdl;
+	u_char *p, *buf;
+	size_t len;
+	int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
+
+	if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
+		return -1;
+	if ((buf = os_malloc(len)) == NULL)
+		return -1;
+	if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+		os_free(buf);
+		return -1;
+	}
+	for (p = buf; p < buf + len; p += ifm->ifm_msglen) {
+		ifm = (struct if_msghdr *)p;
+		sdl = (struct sockaddr_dl *)(ifm + 1);
+		if (ifm->ifm_type != RTM_IFINFO ||
+		    (ifm->ifm_addrs & RTA_IFP) == 0)
+			continue;
+		if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
+		    os_memcmp(sdl->sdl_data, device, sdl->sdl_nlen) != 0)
+			continue;
+		os_memcpy(ea, LLADDR(sdl), sdl->sdl_alen);
+		break;
+	}
+	os_free(buf);
+
+	if (p >= buf + len) {
+		errno = ESRCH;
+		return -1;
+	}
+	return 0;
+}
+#endif /* __FreeBSD__ */
+
+
 /**
  * get_netif_info - Get hw and IP addresses for network device
  * @net_if: Selected network interface name
@@ -870,6 +914,7 @@
 	in_addr.s_addr = *ip_addr;
 	os_snprintf(*ip_addr_text, 16, "%s", inet_ntoa(in_addr));
 
+#ifdef __linux__
 	os_strlcpy(req.ifr_name, net_if, sizeof(req.ifr_name));
 	if (ioctl(sock, SIOCGIFHWADDR, &req) < 0) {
 		wpa_printf(MSG_ERROR, "WPS UPnP: SIOCGIFHWADDR failed: "
@@ -877,6 +922,14 @@
 		goto fail;
 	}
 	os_memcpy(mac, req.ifr_addr.sa_data, 6);
+#elif defined(__FreeBSD__)
+	if (eth_get(net_if, mac) < 0) {
+		wpa_printf(MSG_ERROR, "WPS UPnP: Failed to get MAC address");
+		goto fail;
+	}
+#else
+#error MAC address fetch not implemented
+#endif
 	os_snprintf(*mac_addr_text, 18, MACSTR, MAC2STR(req.ifr_addr.sa_data));
 
 	close(sock);

Modified: hostapd/branches/upstream/current/src/wps/wps_upnp_ssdp.c
URL: http://svn.debian.org/wsvn/hostapd/branches/upstream/current/src/wps/wps_upnp_ssdp.c?rev=1340&op=diff
==============================================================================
--- hostapd/branches/upstream/current/src/wps/wps_upnp_ssdp.c (original)
+++ hostapd/branches/upstream/current/src/wps/wps_upnp_ssdp.c Mon Mar 23 15:39:23 2009
@@ -784,6 +784,7 @@
  */
 int add_ssdp_network(char *net_if)
 {
+#ifdef __linux__
 	int ret = -1;
 	int sock = -1;
 	struct rtentry rt;
@@ -826,6 +827,9 @@
 		close(sock);
 
 	return ret;
+#else /* __linux__ */
+	return 0;
+#endif /* __linux__ */
 }
 
 




More information about the Pkg-wpa-devel mailing list