[pkg-wpa-devel] r1474 - in /hostapd/trunk: debian/ debian/patches/ hostapd/ src/common/ src/crypto/ src/drivers/ src/eap_common/ src/eap_peer/ src/eap_server/ src/eapol_supp/ src/hlr_auc_gw/ src/l2_packet/ src/radius/ src/rsn_supp/ src/tls/ src/utils/ src/wps/

kelmo-guest at users.alioth.debian.org kelmo-guest at users.alioth.debian.org
Thu Feb 11 04:49:22 UTC 2010


Author: kelmo-guest
Date: Thu Feb 11 04:49:20 2010
New Revision: 1474

URL: http://svn.debian.org/wsvn/pkg-wpa/?sc=1&rev=1474
Log:
* New upstream release.
  - drop all patches applied upstream

Removed:
    hostapd/trunk/debian/patches/
    hostapd/trunk/src/common/.gitignore
    hostapd/trunk/src/crypto/.gitignore
    hostapd/trunk/src/drivers/.gitignore
    hostapd/trunk/src/eap_common/.gitignore
    hostapd/trunk/src/eap_peer/.gitignore
    hostapd/trunk/src/eap_server/.gitignore
    hostapd/trunk/src/eapol_supp/.gitignore
    hostapd/trunk/src/hlr_auc_gw/.gitignore
    hostapd/trunk/src/l2_packet/.gitignore
    hostapd/trunk/src/radius/.gitignore
    hostapd/trunk/src/rsn_supp/.gitignore
    hostapd/trunk/src/tls/.gitignore
    hostapd/trunk/src/utils/.gitignore
    hostapd/trunk/src/wps/.gitignore
Modified:
    hostapd/trunk/debian/changelog
    hostapd/trunk/debian/control
    hostapd/trunk/debian/rules
    hostapd/trunk/hostapd/ChangeLog
    hostapd/trunk/hostapd/Makefile
    hostapd/trunk/hostapd/README-WPS
    hostapd/trunk/hostapd/ap.h
    hostapd/trunk/hostapd/beacon.c
    hostapd/trunk/hostapd/config.c
    hostapd/trunk/hostapd/config.h
    hostapd/trunk/hostapd/ctrl_iface.c
    hostapd/trunk/hostapd/driver_nl80211.c
    hostapd/trunk/hostapd/hostapd.c
    hostapd/trunk/hostapd/hostapd.conf
    hostapd/trunk/hostapd/hostapd_cli.c
    hostapd/trunk/hostapd/hw_features.c
    hostapd/trunk/hostapd/ieee802_11.c
    hostapd/trunk/hostapd/ieee802_1x.c
    hostapd/trunk/hostapd/preauth.c
    hostapd/trunk/hostapd/wme.c
    hostapd/trunk/hostapd/wme.h
    hostapd/trunk/hostapd/wpa.c
    hostapd/trunk/hostapd/wpa.h
    hostapd/trunk/hostapd/wpa_auth_i.h
    hostapd/trunk/hostapd/wpa_auth_ie.c
    hostapd/trunk/hostapd/wpa_ft.c
    hostapd/trunk/hostapd/wps_hostapd.c
    hostapd/trunk/hostapd/wps_hostapd.h
    hostapd/trunk/src/common/ieee802_11_common.c
    hostapd/trunk/src/common/ieee802_11_common.h
    hostapd/trunk/src/common/ieee802_11_defs.h
    hostapd/trunk/src/common/nl80211_copy.h
    hostapd/trunk/src/common/version.h
    hostapd/trunk/src/crypto/crypto_cryptoapi.c
    hostapd/trunk/src/crypto/crypto_internal.c
    hostapd/trunk/src/crypto/dh_groups.c
    hostapd/trunk/src/crypto/ms_funcs.c
    hostapd/trunk/src/crypto/rc4.c
    hostapd/trunk/src/crypto/rc4.h
    hostapd/trunk/src/crypto/sha1.c
    hostapd/trunk/src/crypto/tls.h
    hostapd/trunk/src/crypto/tls_gnutls.c
    hostapd/trunk/src/crypto/tls_openssl.c
    hostapd/trunk/src/drivers/driver.h
    hostapd/trunk/src/drivers/driver_bsd.c
    hostapd/trunk/src/drivers/driver_madwifi.c
    hostapd/trunk/src/drivers/driver_ndiswrapper.c
    hostapd/trunk/src/drivers/driver_nl80211.c
    hostapd/trunk/src/drivers/driver_roboswitch.c
    hostapd/trunk/src/drivers/driver_wext.c
    hostapd/trunk/src/drivers/driver_wired.c
    hostapd/trunk/src/eap_peer/eap_methods.h
    hostapd/trunk/src/eap_peer/eap_sim.c
    hostapd/trunk/src/eap_peer/eap_tls_common.c
    hostapd/trunk/src/eap_peer/eap_ttls.c
    hostapd/trunk/src/eap_peer/eap_wsc.c
    hostapd/trunk/src/eap_peer/tncc.c
    hostapd/trunk/src/eap_server/eap.c
    hostapd/trunk/src/eap_server/eap_fast.c
    hostapd/trunk/src/eap_server/eap_tls_common.c
    hostapd/trunk/src/eapol_supp/eapol_supp_sm.c
    hostapd/trunk/src/hlr_auc_gw/hlr_auc_gw.c
    hostapd/trunk/src/l2_packet/l2_packet_linux.c
    hostapd/trunk/src/radius/radius_client.c
    hostapd/trunk/src/radius/radius_server.c
    hostapd/trunk/src/rsn_supp/wpa.c
    hostapd/trunk/src/rsn_supp/wpa_ft.c
    hostapd/trunk/src/rsn_supp/wpa_i.h
    hostapd/trunk/src/tls/rsa.c
    hostapd/trunk/src/tls/tlsv1_client.c
    hostapd/trunk/src/tls/tlsv1_server_read.c
    hostapd/trunk/src/utils/base64.c
    hostapd/trunk/src/utils/common.c
    hostapd/trunk/src/utils/common.h
    hostapd/trunk/src/utils/os_unix.c
    hostapd/trunk/src/utils/wpa_debug.c
    hostapd/trunk/src/utils/wpa_debug.h
    hostapd/trunk/src/utils/wpabuf.c
    hostapd/trunk/src/wps/httpread.c
    hostapd/trunk/src/wps/wps.h
    hostapd/trunk/src/wps/wps_attr_parse.c
    hostapd/trunk/src/wps/wps_common.c
    hostapd/trunk/src/wps/wps_enrollee.c
    hostapd/trunk/src/wps/wps_i.h
    hostapd/trunk/src/wps/wps_registrar.c
    hostapd/trunk/src/wps/wps_upnp.c
    hostapd/trunk/src/wps/wps_upnp_event.c
    hostapd/trunk/src/wps/wps_upnp_i.h
    hostapd/trunk/src/wps/wps_upnp_ssdp.c
    hostapd/trunk/src/wps/wps_upnp_web.c

Modified: hostapd/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/debian/changelog?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/debian/changelog (original)
+++ hostapd/trunk/debian/changelog Thu Feb 11 04:49:20 2010
@@ -1,5 +1,7 @@
-hostapd (1:0.6.9-4) unstable; urgency=low
-
+hostapd (1:0.6.10-1) unstable; urgency=low
+
+  * New upstream release.
+    - drop all patches applied upstream
   * Support the status command in init.d script. Depend on lsb-base (>=
     3.2-13) for status_of_proc. Patch thanks to Peter Eisentraut.
     (Closes: #535633)
@@ -22,7 +24,7 @@
   * Remove uupdate command from debian/watch, unused by maintainer.
   * Adjust debian/watch to scan for the 0.6.X stable releases only.
 
- -- Kel Modderman <kel at otaku42.de>  Thu, 11 Feb 2010 14:16:32 +1000
+ -- Kel Modderman <kel at otaku42.de>  Thu, 11 Feb 2010 14:47:55 +1000
 
 hostapd (1:0.6.9-3) unstable; urgency=low
 

Modified: hostapd/trunk/debian/control
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/debian/control?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/debian/control (original)
+++ hostapd/trunk/debian/control Thu Feb 11 04:49:20 2010
@@ -5,7 +5,6 @@
 Uploaders: Faidon Liambotis <paravoid at debian.org>,
  Kel Modderman <kel at otaku42.de>
 Build-Depends: debhelper (>= 7.3.7~),
- quilt (>= 0.46-7~),
  libssl-dev,
  libnl-dev (>= 1.1)
 Standards-Version: 3.8.4

Modified: hostapd/trunk/debian/rules
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/debian/rules?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/debian/rules (original)
+++ hostapd/trunk/debian/rules Thu Feb 11 04:49:20 2010
@@ -1,6 +1,7 @@
 #!/usr/bin/make -f
 
 CFLAGS = -MMD -Wall -g
+V = 1
 
 ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
 	CFLAGS += -O0
@@ -8,7 +9,7 @@
 	CFLAGS += -O2
 endif
 
-export CFLAGS
+export CFLAGS V
 
 DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
 BUILD_DOT_CONFIG := debian/config/$(DEB_HOST_ARCH_OS)
@@ -38,4 +39,4 @@
 ### end dh overrides
 
 %:
-	dh $@ --with quilt
+	dh $@

Modified: hostapd/trunk/hostapd/ChangeLog
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/ChangeLog?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/ChangeLog (original)
+++ hostapd/trunk/hostapd/ChangeLog Thu Feb 11 04:49:20 2010
@@ -1,4 +1,26 @@
 ChangeLog for hostapd
+
+2010-01-12 - v0.6.10
+	* fixed SHA-256 based key derivation function to match with the
+	  standard when using CCMP (for IEEE 802.11r and IEEE 802.11w)
+	  (note: this breaks interoperability with previous version) [Bug 307]
+	* fixed WPS selected registrar expiration for internal PIN registrar
+	* disable PMTU discovery for RADIUS packets
+	* fixed WPS UPnP SSDP on 32-bit targets
+	* fixed WPS AP reconfiguration with drivers that do not use hostapd
+	  MLME
+	* fixed RSN parameter setting for multi-BSS case
+	* added WPS workarounds for known interoperability issues with broken,
+	  deployed implementation
+	* update IEEE 802.11w implementation to match with the published
+	  standard
+	* fixed OpCode when proxying WSC_ACK or WSC_NACK from WPS ER
+	* fixed proxying of WSC_NACK to WPS ER
+	* fixed compilation with newer GnuTLS versions
+	* added support for defining timeout for WPS PINs
+	* fixed WPS Probe Request processing to handle missing required
+	  attribute
+	* fixed PKCS#12 use with OpenSSL 1.0.0
 
 2009-03-23 - v0.6.9
 	* driver_nl80211: fixed STA accounting data collection (TX/RX bytes

Modified: hostapd/trunk/hostapd/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/Makefile?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/Makefile (original)
+++ hostapd/trunk/hostapd/Makefile Thu Feb 11 04:49:20 2010
@@ -220,6 +220,7 @@
 CFLAGS += -DEAP_AKA
 OBJS += ../src/eap_server/eap_aka.o
 CONFIG_EAP_SIM_COMMON=y
+NEED_SHA256=y
 endif
 
 ifdef CONFIG_EAP_AKA_PRIME
@@ -306,6 +307,7 @@
 OBJS += ../src/eap_server/eap_ikev2.o ../src/eap_server/ikev2.o
 OBJS += ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.o
 NEED_DH_GROUPS=y
+NEED_DH_GROUPS_ALL=y
 endif
 
 ifdef CONFIG_EAP_TNC
@@ -449,6 +451,15 @@
 OBJS += ../src/crypto/crypto_internal.o ../src/tls/rsa.o ../src/tls/bignum.o
 OBJS_p += ../src/crypto/crypto_internal.o ../src/tls/rsa.o ../src/tls/bignum.o
 CFLAGS += -DCONFIG_CRYPTO_INTERNAL
+ifdef CONFIG_INTERNAL_LIBTOMMATH
+CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
+ifdef CONFIG_INTERNAL_LIBTOMMATH_FAST
+CFLAGS += -DLTM_FAST
+endif
+else
+LIBS += -ltommath
+LIBS_p += -ltommath
+endif
 CONFIG_INTERNAL_AES=y
 CONFIG_INTERNAL_DES=y
 CONFIG_INTERNAL_SHA1=y
@@ -489,6 +500,9 @@
 
 ifdef NEED_DH_GROUPS
 OBJS += ../src/crypto/dh_groups.o
+ifdef NEED_DH_GROUPS_ALL
+CFLAGS += -DALL_DH_GROUPS
+endif
 endif
 
 ifndef NEED_FIPS186_2_PRF
@@ -541,6 +555,17 @@
 ALL=hostapd hostapd_cli
 
 all: verify_config $(ALL)
+
+Q=@
+E=echo
+ifeq ($(V), 1)
+Q=
+E=true
+endif
+
+%.o: %.c
+	$(Q)$(CC) -c -o $@ $(CFLAGS) $<
+	@$(E) "  CC " $<
 
 verify_config:
 	@if [ ! -r .config ]; then \

Modified: hostapd/trunk/hostapd/README-WPS
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/README-WPS?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/README-WPS (original)
+++ hostapd/trunk/hostapd/README-WPS Thu Feb 11 04:49:20 2010
@@ -165,9 +165,16 @@
 hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c 12345670
 
 If the UUID-E is not available (e.g., Enrollee waits for the Registrar
-to be selected before connecting), wildcard UUID may be used to allow the PIN to be used once with any UUID:
+to be selected before connecting), wildcard UUID may be used to allow
+the PIN to be used once with any UUID:
 
 hostapd_cli wps_pin any 12345670
+
+To reduce likelihood of PIN being used with other devices or of
+forgetting an active PIN available for potential attackers, expiration
+time can be set for the new PIN:
+
+hostapd_cli wps_pin any 12345670 300
 
 
 After this, the Enrollee can connect to the AP again and complete WPS

Modified: hostapd/trunk/hostapd/ap.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/ap.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/ap.h (original)
+++ hostapd/trunk/hostapd/ap.h Thu Feb 11 04:49:20 2010
@@ -30,7 +30,7 @@
 #define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
 #define WLAN_STA_SHORT_PREAMBLE BIT(7)
 #define WLAN_STA_PREAUTH BIT(8)
-#define WLAN_STA_WME BIT(9)
+#define WLAN_STA_WMM BIT(9)
 #define WLAN_STA_MFP BIT(10)
 #define WLAN_STA_HT BIT(11)
 #define WLAN_STA_WPS BIT(12)

Modified: hostapd/trunk/hostapd/beacon.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/beacon.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/beacon.c (original)
+++ hostapd/trunk/hostapd/beacon.c Thu Feb 11 04:49:20 2010
@@ -298,8 +298,8 @@
 
 	pos = hostapd_eid_wpa(hapd, pos, epos - pos, sta);
 
-	/* Wi-Fi Wireless Multimedia Extensions */
-	pos = hostapd_eid_wme(hapd, pos);
+	/* Wi-Fi Alliance WMM */
+	pos = hostapd_eid_wmm(hapd, pos);
 
 	pos = hostapd_eid_ht_capabilities_info(hapd, pos);
 	pos = hostapd_eid_ht_operation(hapd, pos);
@@ -395,8 +395,8 @@
 	tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
 				  tailpos, NULL);
 
-	/* Wi-Fi Wireless Multimedia Extensions */
-	tailpos = hostapd_eid_wme(hapd, tailpos);
+	/* Wi-Fi Alliance WMM */
+	tailpos = hostapd_eid_wmm(hapd, tailpos);
 
 #ifdef CONFIG_IEEE80211N
 	if (hapd->iconf->ieee80211n) {

Modified: hostapd/trunk/hostapd/config.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/config.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/config.c (original)
+++ hostapd/trunk/hostapd/config.c Thu Feb 11 04:49:20 2010
@@ -201,15 +201,15 @@
 	struct hostapd_config *conf;
 	struct hostapd_bss_config *bss;
 	int i;
-	const int aCWmin = 15, aCWmax = 1024;
-	const struct hostapd_wme_ac_params ac_bk =
+	const int aCWmin = 4, aCWmax = 10;
+	const struct hostapd_wmm_ac_params ac_bk =
 		{ aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
-	const struct hostapd_wme_ac_params ac_be =
+	const struct hostapd_wmm_ac_params ac_be =
 		{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
-	const struct hostapd_wme_ac_params ac_vi = /* video traffic */
-		{ aCWmin >> 1, aCWmin, 2, 3000 / 32, 1 };
-	const struct hostapd_wme_ac_params ac_vo = /* voice traffic */
-		{ aCWmin >> 2, aCWmin >> 1, 2, 1500 / 32, 1 };
+	const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
+		{ aCWmin - 1, aCWmin, 2, 3000 / 32, 1 };
+	const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
+		{ aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 1 };
 
 	conf = os_zalloc(sizeof(*conf));
 	bss = os_zalloc(sizeof(*bss));
@@ -251,10 +251,10 @@
 	for (i = 0; i < NUM_TX_QUEUES; i++)
 		conf->tx_queue[i].aifs = -1; /* use hw default */
 
-	conf->wme_ac_params[0] = ac_be;
-	conf->wme_ac_params[1] = ac_bk;
-	conf->wme_ac_params[2] = ac_vi;
-	conf->wme_ac_params[3] = ac_vo;
+	conf->wmm_ac_params[0] = ac_be;
+	conf->wmm_ac_params[1] = ac_bk;
+	conf->wmm_ac_params[2] = ac_vi;
+	conf->wmm_ac_params[3] = ac_vo;
 
 #ifdef CONFIG_IEEE80211N
 	conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;
@@ -1166,14 +1166,14 @@
 }
 
 
-static int hostapd_config_wme_ac(struct hostapd_config *conf, char *name,
-				   char *val)
+static int hostapd_config_wmm_ac(struct hostapd_config *conf, char *name,
+				 char *val)
 {
 	int num, v;
 	char *pos;
-	struct hostapd_wme_ac_params *ac;
-
-	/* skip 'wme_ac_' prefix */
+	struct hostapd_wmm_ac_params *ac;
+
+	/* skip 'wme_ac_' or 'wmm_ac_' prefix */
 	pos = name + 7;
 	if (os_strncmp(pos, "be_", 3) == 0) {
 		num = 0;
@@ -1188,11 +1188,11 @@
 		num = 3;
 		pos += 3;
 	} else {
-		wpa_printf(MSG_ERROR, "Unknown wme name '%s'", pos);
-		return -1;
-	}
-
-	ac = &conf->wme_ac_params[num];
+		wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
+		return -1;
+	}
+
+	ac = &conf->wmm_ac_params[num];
 
 	if (os_strcmp(pos, "aifs") == 0) {
 		v = atoi(val);
@@ -1221,7 +1221,7 @@
 			wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
 			return -1;
 		}
-		ac->txopLimit = v;
+		ac->txop_limit = v;
 	} else if (os_strcmp(pos, "acm") == 0) {
 		v = atoi(val);
 		if (v < 0 || v > 1) {
@@ -1230,7 +1230,7 @@
 		}
 		ac->admission_control_mandatory = v;
 	} else {
-		wpa_printf(MSG_ERROR, "Unknown wme_ac_ field '%s'", pos);
+		wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
 		return -1;
 	}
 
@@ -1452,13 +1452,13 @@
 		} else if (os_strcmp(buf, "bridge") == 0) {
 			os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
 		} else if (os_strcmp(buf, "driver") == 0) {
-			int i;
+			int j;
 			/* clear to get error below if setting is invalid */
 			conf->driver = NULL;
-			for (i = 0; hostapd_drivers[i]; i++) {
-				if (os_strcmp(pos, hostapd_drivers[i]->name) ==
+			for (j = 0; hostapd_drivers[j]; j++) {
+				if (os_strcmp(pos, hostapd_drivers[j]->name) ==
 				    0) {
-					conf->driver = hostapd_drivers[i];
+					conf->driver = hostapd_drivers[j];
 					break;
 				}
 			}
@@ -2070,11 +2070,13 @@
 					   "queue item", line);
 				errors++;
 			}
-		} else if (os_strcmp(buf, "wme_enabled") == 0) {
-			bss->wme_enabled = atoi(pos);
-		} else if (os_strncmp(buf, "wme_ac_", 7) == 0) {
-			if (hostapd_config_wme_ac(conf, buf, pos)) {
-				wpa_printf(MSG_ERROR, "Line %d: invalid wme "
+		} else if (os_strcmp(buf, "wme_enabled") == 0 ||
+			   os_strcmp(buf, "wmm_enabled") == 0) {
+			bss->wmm_enabled = atoi(pos);
+		} else if (os_strncmp(buf, "wme_ac_", 7) == 0 ||
+			   os_strncmp(buf, "wmm_ac_", 7) == 0) {
+			if (hostapd_config_wmm_ac(conf, buf, pos)) {
+				wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
 					   "ac item", line);
 				errors++;
 			}
@@ -2255,28 +2257,29 @@
 
 	fclose(f);
 
-	if (bss->individual_wep_key_len == 0) {
-		/* individual keys are not use; can use key idx0 for broadcast
-		 * keys */
-		bss->broadcast_key_idx_min = 0;
-	}
-
-	/* Select group cipher based on the enabled pairwise cipher suites */
-	pairwise = 0;
-	if (bss->wpa & 1)
-		pairwise |= bss->wpa_pairwise;
-	if (bss->wpa & 2) {
-		if (bss->rsn_pairwise == 0)
-			bss->rsn_pairwise = bss->wpa_pairwise;
-		pairwise |= bss->rsn_pairwise;
-	}
-	if (pairwise & WPA_CIPHER_TKIP)
-		bss->wpa_group = WPA_CIPHER_TKIP;
-	else
-		bss->wpa_group = WPA_CIPHER_CCMP;
-
 	for (i = 0; i < conf->num_bss; i++) {
 		bss = &conf->bss[i];
+
+		if (bss->individual_wep_key_len == 0) {
+			/* individual keys are not use; can use key idx0 for
+			 * broadcast keys */
+			bss->broadcast_key_idx_min = 0;
+		}
+
+		/* Select group cipher based on the enabled pairwise cipher
+		 * suites */
+		pairwise = 0;
+		if (bss->wpa & 1)
+			pairwise |= bss->wpa_pairwise;
+		if (bss->wpa & 2) {
+			if (bss->rsn_pairwise == 0)
+				bss->rsn_pairwise = bss->wpa_pairwise;
+			pairwise |= bss->rsn_pairwise;
+		}
+		if (pairwise & WPA_CIPHER_TKIP)
+			bss->wpa_group = WPA_CIPHER_TKIP;
+		else
+			bss->wpa_group = WPA_CIPHER_CCMP;
 
 		bss->radius->auth_server = bss->radius->auth_servers;
 		bss->radius->acct_server = bss->radius->acct_servers;
@@ -2476,6 +2479,8 @@
 	for (i = 0; i < conf->num_bss; i++)
 		hostapd_config_free_bss(&conf->bss[i]);
 	os_free(conf->bss);
+	os_free(conf->supported_rates);
+	os_free(conf->basic_rates);
 
 	os_free(conf);
 }

Modified: hostapd/trunk/hostapd/config.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/config.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/config.h (original)
+++ hostapd/trunk/hostapd/config.h Thu Feb 11 04:49:20 2010
@@ -135,11 +135,11 @@
 	int configured;
 };
 
-struct hostapd_wme_ac_params {
+struct hostapd_wmm_ac_params {
 	int cwmin;
 	int cwmax;
 	int aifs;
-	int txopLimit; /* in units of 32us */
+	int txop_limit; /* in units of 32us */
 	int admission_control_mandatory;
 };
 
@@ -271,7 +271,7 @@
 	int ap_max_inactivity;
 	int ignore_broadcast_ssid;
 
-	int wme_enabled;
+	int wmm_enabled;
 
 	struct hostapd_vlan *vlan, *vlan_tail;
 
@@ -371,13 +371,13 @@
 	struct hostapd_tx_queue_params tx_queue[NUM_TX_QUEUES];
 
 	/*
-	 * WME AC parameters, in same order as 802.1D, i.e.
+	 * WMM AC parameters, in same order as 802.1D, i.e.
 	 * 0 = BE (best effort)
 	 * 1 = BK (background)
 	 * 2 = VI (video)
 	 * 3 = VO (voice)
 	 */
-	struct hostapd_wme_ac_params wme_ac_params[4];
+	struct hostapd_wmm_ac_params wmm_ac_params[4];
 
 	enum {
 		INTERNAL_BRIDGE_DO_NOT_CONTROL = -1,

Modified: hostapd/trunk/hostapd/ctrl_iface.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/ctrl_iface.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/ctrl_iface.c (original)
+++ hostapd/trunk/hostapd/ctrl_iface.c Thu Feb 11 04:49:20 2010
@@ -253,10 +253,21 @@
 static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
 {
 	char *pin = os_strchr(txt, ' ');
+	char *timeout_txt;
+	int timeout;
+
 	if (pin == NULL)
 		return -1;
 	*pin++ = '\0';
-	return hostapd_wps_add_pin(hapd, txt, pin);
+
+	timeout_txt = os_strchr(pin, ' ');
+	if (timeout_txt) {
+		*timeout_txt++ = '\0';
+		timeout = atoi(timeout_txt);
+	} else
+		timeout = 0;
+
+	return hostapd_wps_add_pin(hapd, txt, pin, timeout);
 }
 #endif /* CONFIG_WPS */
 
@@ -450,8 +461,35 @@
 		goto fail;
 	os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
 	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		perror("bind(PF_UNIX)");
-		goto fail;
+		wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
+			   strerror(errno));
+		if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+			wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
+				   " allow connections - assuming it was left"
+				   "over from forced program termination");
+			if (unlink(fname) < 0) {
+				perror("unlink[ctrl_iface]");
+				wpa_printf(MSG_ERROR, "Could not unlink "
+					   "existing ctrl_iface socket '%s'",
+					   fname);
+				goto fail;
+			}
+			if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
+			    0) {
+				perror("bind(PF_UNIX)");
+				goto fail;
+			}
+			wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
+				   "ctrl_iface socket '%s'", fname);
+		} else {
+			wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
+				   "be in use - cannot override it");
+			wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
+				   "not used anymore", fname);
+			os_free(fname);
+			fname = NULL;
+			goto fail;
+		}
 	}
 
 	if (hapd->conf->ctrl_interface_gid_set &&

Modified: hostapd/trunk/hostapd/driver_nl80211.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/driver_nl80211.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/driver_nl80211.c (original)
+++ hostapd/trunk/hostapd/driver_nl80211.c Thu Feb 11 04:49:20 2010
@@ -908,7 +908,7 @@
 	if (total_flags & WLAN_STA_AUTHORIZED || !drv->ieee802_1x_active)
 		NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);
 
-	if (total_flags & WLAN_STA_WME)
+	if (total_flags & WLAN_STA_WMM)
 		NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);
 
 	if (total_flags & WLAN_STA_SHORT_PREAMBLE)
@@ -1432,7 +1432,7 @@
 
 			/* crude heuristic */
 			if (mode->channels[idx].freq < 4000)
-				if (mode->channels[idx].freq == 2848)
+				if (mode->channels[idx].freq == 2484)
 					mode->channels[idx].chan = 14;
 				else
 					mode->channels[idx].chan = (mode->channels[idx].freq - 2407) / 5;
@@ -2380,7 +2380,7 @@
 					       struct nlmsghdr *h, int len)
 {
 	struct ifinfomsg *ifi;
-	int attrlen, nlmsg_len, rta_len;
+	int attrlen, _nlmsg_len, rta_len;
 	struct rtattr *attr;
 
 	if (len < (int) sizeof(*ifi))
@@ -2391,13 +2391,13 @@
 	/* TODO: use ifi->ifi_index to filter out wireless events from other
 	 * interfaces */
 
-	nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
-	attrlen = h->nlmsg_len - nlmsg_len;
+	_nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
+
+	attrlen = h->nlmsg_len - _nlmsg_len;
 	if (attrlen < 0)
 		return;
 
-	attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+	attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
 
 	rta_len = RTA_ALIGN(sizeof(struct rtattr));
 	while (RTA_OK(attr, attrlen)) {

Modified: hostapd/trunk/hostapd/hostapd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/hostapd.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/hostapd.c (original)
+++ hostapd/trunk/hostapd/hostapd.c Thu Feb 11 04:49:20 2010
@@ -249,7 +249,7 @@
 	if (!hapd->conf->ieee802_1x && !hapd->conf->wpa)
 		accounting_sta_start(hapd, sta);
 
-	hostapd_wme_sta_config(hapd, sta);
+	hostapd_wmm_sta_config(hapd, sta);
 
 	/* Start IEEE 802.1X authentication process for new stations */
 	ieee802_1x_new_station(hapd, sta);
@@ -306,7 +306,7 @@
 	wconf->rsn_preauth = conf->rsn_preauth;
 	wconf->eapol_version = conf->eapol_version;
 	wconf->peerkey = conf->peerkey;
-	wconf->wme_enabled = conf->wme_enabled;
+	wconf->wmm_enabled = conf->wmm_enabled;
 	wconf->okc = conf->okc;
 #ifdef CONFIG_IEEE80211W
 	wconf->ieee80211w = conf->ieee80211w;
@@ -339,6 +339,7 @@
 	struct hostapd_data *hapd = iface->bss[0];
 	struct hostapd_config *newconf, *oldconf;
 	struct wpa_auth_config wpa_auth_conf;
+	size_t j;
 
 	newconf = hostapd_config_read(iface->config_fname);
 	if (newconf == NULL)
@@ -348,7 +349,8 @@
 	 * Deauthenticate all stations since the new configuration may not
 	 * allow them to use the BSS anymore.
 	 */
-	hostapd_flush_old_stations(hapd);
+	for (j = 0; j < iface->num_bss; j++)
+		hostapd_flush_old_stations(iface->bss[j]);
 
 	/* TODO: update dynamic data based on changed configuration
 	 * items (e.g., open/close sockets, etc.) */
@@ -377,6 +379,16 @@
 	}
 
 	ieee802_11_set_beacon(hapd);
+
+	if (hapd->conf->ssid.ssid_set &&
+	    hostapd_set_ssid(hapd, (u8 *) hapd->conf->ssid.ssid,
+			     hapd->conf->ssid.ssid_len)) {
+		wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
+		/* try to continue */
+	}
+
+	if (hapd->conf->ieee802_1x || hapd->conf->wpa)
+		hostapd_set_ieee8021x(hapd->conf->iface, hapd, 1);
 
 	hostapd_config_free(oldconf);
 
@@ -465,7 +477,7 @@
 			(sta->flags & WLAN_STA_SHORT_PREAMBLE ?
 			 "[SHORT_PREAMBLE]" : ""),
 			(sta->flags & WLAN_STA_PREAUTH ? "[PREAUTH]" : ""),
-			(sta->flags & WLAN_STA_WME ? "[WME]" : ""),
+			(sta->flags & WLAN_STA_WMM ? "[WMM]" : ""),
 			(sta->flags & WLAN_STA_MFP ? "[MFP]" : ""),
 			(sta->flags & WLAN_STA_WPS ? "[WPS]" : ""),
 			(sta->flags & WLAN_STA_MAYBE_WPS ? "[MAYBE_WPS]" : ""),
@@ -1308,6 +1320,13 @@
 		}
 	}
 
+	hostapd_flush_old_stations(hapd);
+	hostapd_set_privacy(hapd, 0);
+
+	hostapd_broadcast_wep_clear(hapd);
+	if (hostapd_setup_encryption(hapd->conf->iface, hapd))
+		return -1;
+
 	/*
 	 * Fetch the SSID from the system and use it or,
 	 * if one was specified in the config file, verify they
@@ -1510,7 +1529,6 @@
 	u8 *b = conf->bssid;
 	int freq;
 	size_t j;
-	int ret = 0;
 	u8 *prev_addr;
 
 	/*
@@ -1582,9 +1600,6 @@
 		}
 	}
 
-	hostapd_flush_old_stations(hapd);
-	hostapd_set_privacy(hapd, 0);
-
 	if (hapd->iconf->channel) {
 		freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel);
 		wpa_printf(MSG_DEBUG, "Mode: %s  Channel: %d  "
@@ -1601,12 +1616,7 @@
 		}
 	}
 
-	hostapd_broadcast_wep_clear(hapd);
-	if (hostapd_setup_encryption(hapd->conf->iface, hapd))
-		return -1;
-
 	hostapd_set_beacon_int(hapd, hapd->iconf->beacon_int);
-	ieee802_11_set_beacon(hapd);
 
 	if (hapd->iconf->rts_threshold > -1 &&
 	    hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
@@ -1644,7 +1654,7 @@
 		return -1;
 	}
 
-	return ret;
+	return 0;
 }
 
 
@@ -1867,7 +1877,7 @@
 	int ret = 1, k;
 	size_t i, j;
 	int c, debug = 0, daemonize = 0, tnc = 0;
-	const char *pid_file = NULL;
+	char *pid_file = NULL;
 
 	hostapd_logger_register_cb(hostapd_logger_cb);
 
@@ -1891,7 +1901,8 @@
 			wpa_debug_show_keys++;
 			break;
 		case 'P':
-			pid_file = optarg;
+			os_free(pid_file);
+			pid_file = os_rel2abs_path(optarg);
 			break;
 		case 't':
 			wpa_debug_timestamp++;
@@ -2022,6 +2033,7 @@
 	eap_server_unregister_methods();
 
 	os_daemonize_terminate(pid_file);
+	os_free(pid_file);
 
 	return ret;
 }

Modified: hostapd/trunk/hostapd/hostapd.conf
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/hostapd.conf?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/hostapd.conf (original)
+++ hostapd/trunk/hostapd/hostapd.conf Thu Feb 11 04:49:20 2010
@@ -273,38 +273,38 @@
 # note - here cwMin and cmMax are in exponent form. the actual cw value used
 # will be (2^n)-1 where n is the value given here
 #
-wme_enabled=1
+wmm_enabled=1
 #
 # Low priority / AC_BK = background
-wme_ac_bk_cwmin=4
-wme_ac_bk_cwmax=10
-wme_ac_bk_aifs=7
-wme_ac_bk_txop_limit=0
-wme_ac_bk_acm=0
+wmm_ac_bk_cwmin=4
+wmm_ac_bk_cwmax=10
+wmm_ac_bk_aifs=7
+wmm_ac_bk_txop_limit=0
+wmm_ac_bk_acm=0
 # Note: for IEEE 802.11b mode: cWmin=5 cWmax=10
 #
 # Normal priority / AC_BE = best effort
-wme_ac_be_aifs=3
-wme_ac_be_cwmin=4
-wme_ac_be_cwmax=10
-wme_ac_be_txop_limit=0
-wme_ac_be_acm=0
+wmm_ac_be_aifs=3
+wmm_ac_be_cwmin=4
+wmm_ac_be_cwmax=10
+wmm_ac_be_txop_limit=0
+wmm_ac_be_acm=0
 # Note: for IEEE 802.11b mode: cWmin=5 cWmax=7
 #
 # High priority / AC_VI = video
-wme_ac_vi_aifs=2
-wme_ac_vi_cwmin=3
-wme_ac_vi_cwmax=4
-wme_ac_vi_txop_limit=94
-wme_ac_vi_acm=0
+wmm_ac_vi_aifs=2
+wmm_ac_vi_cwmin=3
+wmm_ac_vi_cwmax=4
+wmm_ac_vi_txop_limit=94
+wmm_ac_vi_acm=0
 # Note: for IEEE 802.11b mode: cWmin=4 cWmax=5 txop_limit=188
 #
 # Highest priority / AC_VO = voice
-wme_ac_vo_aifs=2
-wme_ac_vo_cwmin=2
-wme_ac_vo_cwmax=3
-wme_ac_vo_txop_limit=47
-wme_ac_vo_acm=0
+wmm_ac_vo_aifs=2
+wmm_ac_vo_cwmin=2
+wmm_ac_vo_cwmax=3
+wmm_ac_vo_txop_limit=47
+wmm_ac_vo_acm=0
 # Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
 
 # Static WEP key configuration
@@ -375,6 +375,7 @@
 # ieee80211n: Whether IEEE 802.11n (HT) is enabled
 # 0 = disabled (default)
 # 1 = enabled
+# Note: You will also need to enable WMM for full HT functionality.
 #ieee80211n=1
 
 # ht_capab: HT capabilities (list of flags)

Modified: hostapd/trunk/hostapd/hostapd_cli.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/hostapd_cli.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/hostapd_cli.c (original)
+++ hostapd/trunk/hostapd/hostapd_cli.c Thu Feb 11 04:49:20 2010
@@ -87,7 +87,7 @@
 "   sa_query <addr>      send SA Query to a station\n"
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_WPS
-"   wps_pin <uuid> <pin> add WPS Enrollee PIN (Device Password)\n"
+"   wps_pin <uuid> <pin> [timeout]  add WPS Enrollee PIN (Device Password)\n"
 "   wps_pbc              indicate button pushed to initiate PBC\n"
 #endif /* CONFIG_WPS */
 "   help                 show this usage help\n"
@@ -260,12 +260,16 @@
 				   char *argv[])
 {
 	char buf[64];
-	if (argc != 2) {
-		printf("Invalid 'wps_pin' command - exactly two arguments, "
+	if (argc < 2) {
+		printf("Invalid 'wps_pin' command - at least two arguments, "
 		       "UUID and PIN, are required.\n");
 		return -1;
 	}
-	snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
+	if (argc > 2)
+		snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
+			 argv[0], argv[1], argv[2]);
+	else
+		snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
 	return wpa_ctrl_command(ctrl, buf);
 }
 

Modified: hostapd/trunk/hostapd/hw_features.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/hw_features.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/hw_features.c (original)
+++ hostapd/trunk/hostapd/hw_features.c Thu Feb 11 04:49:20 2010
@@ -382,6 +382,13 @@
 			break;
 		}
 	}
+	if (iface->conf->channel == 0) {
+		/* TODO: could request a scan of neighboring BSSes and select
+		 * the channel automatically */
+		wpa_printf(MSG_ERROR, "Channel not configured "
+			   "(hw_mode/channel in hostapd.conf)");
+		return -1;
+	}
 	if (ok == 0 && iface->conf->channel != 0) {
 		hostapd_logger(iface->bss[0], NULL,
 			       HOSTAPD_MODULE_IEEE80211,

Modified: hostapd/trunk/hostapd/ieee802_11.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/ieee802_11.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/ieee802_11.c (original)
+++ hostapd/trunk/hostapd/ieee802_11.c Thu Feb 11 04:49:20 2010
@@ -384,8 +384,8 @@
 			r = random();
 			os_memcpy(key, &now, 4);
 			os_memcpy(key + 4, &r, 4);
-			rc4(sta->challenge, WLAN_AUTH_CHALLENGE_LEN,
-			    key, sizeof(key));
+			rc4_skip(key, sizeof(key), 0,
+				 sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
 		}
 		return 0;
 	}
@@ -585,7 +585,7 @@
 
 	if (vlan_id > 0) {
 		if (hostapd_get_vlan_id_ifname(hapd->conf->vlan,
-					       sta->vlan_id) == NULL) {
+					       vlan_id) == NULL) {
 			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
 				       HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
 				       "%d received from RADIUS server",
@@ -766,16 +766,16 @@
 		goto fail;
 	}
 
-	sta->flags &= ~WLAN_STA_WME;
-	if (elems.wme && hapd->conf->wme_enabled) {
-		if (hostapd_eid_wme_valid(hapd, elems.wme, elems.wme_len))
+	sta->flags &= ~WLAN_STA_WMM;
+	if (elems.wmm && hapd->conf->wmm_enabled) {
+		if (hostapd_eid_wmm_valid(hapd, elems.wmm, elems.wmm_len))
 			hostapd_logger(hapd, sta->addr,
 				       HOSTAPD_MODULE_WPA,
 				       HOSTAPD_LEVEL_DEBUG,
-				       "invalid WME element in association "
+				       "invalid WMM element in association "
 				       "request");
 		else
-			sta->flags |= WLAN_STA_WME;
+			sta->flags |= WLAN_STA_WMM;
 	}
 
 	if (!elems.supp_rates) {
@@ -1124,8 +1124,8 @@
 		p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
 		/* Extended supported rates */
 		p = hostapd_eid_ext_supp_rates(hapd, p);
-		if (sta->flags & WLAN_STA_WME)
-			p = hostapd_eid_wme(hapd, p);
+		if (sta->flags & WLAN_STA_WMM)
+			p = hostapd_eid_wmm(hapd, p);
 
 		p = hostapd_eid_ht_capabilities_info(hapd, p);
 		p = hostapd_eid_ht_operation(hapd, p);
@@ -1264,6 +1264,11 @@
 {
 	struct ieee80211_mgmt mgmt;
 	u8 *end;
+
+	wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Request to "
+		   MACSTR, MAC2STR(addr));
+	wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
+		    trans_id, WLAN_SA_QUERY_TR_ID_LEN);
 
 	os_memset(&mgmt, 0, sizeof(mgmt));
 	mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
@@ -1302,6 +1307,12 @@
 		return;
 	}
 
+	wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Response from "
+		   MACSTR, MAC2STR(mgmt->sa));
+	wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID",
+		    mgmt->u.action.u.sa_query_resp.trans_id,
+		    WLAN_SA_QUERY_TR_ID_LEN);
+
 	/* MLME-SAQuery.confirm */
 
 	sta = ap_get_sta(hapd, mgmt->sa);
@@ -1330,12 +1341,21 @@
 		       "Reply to pending SA Query received");
 	ap_sta_stop_sa_query(hapd, sta);
 }
+
+
+static int robust_action_frame(u8 category)
+{
+	return category != WLAN_ACTION_PUBLIC &&
+		category != WLAN_ACTION_HT;
+}
 #endif /* CONFIG_IEEE80211W */
 
 
 static void handle_action(struct hostapd_data *hapd,
 			  struct ieee80211_mgmt *mgmt, size_t len)
 {
+	struct sta_info *sta;
+
 	if (len < IEEE80211_HDRLEN + 1) {
 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_DEBUG,
@@ -1344,13 +1364,23 @@
 		return;
 	}
 
+	sta = ap_get_sta(hapd, mgmt->sa);
+#ifdef CONFIG_IEEE80211W
+	if (sta && (sta->flags & WLAN_STA_MFP) &&
+	    !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) &&
+	      robust_action_frame(mgmt->u.action.category))) {
+		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
+			       HOSTAPD_LEVEL_DEBUG,
+			       "Dropped unprotected Robust Action frame from "
+			       "an MFP STA");
+		return;
+	}
+#endif /* CONFIG_IEEE80211W */
+
 	switch (mgmt->u.action.category) {
 #ifdef CONFIG_IEEE80211R
 	case WLAN_ACTION_FT:
 	{
-		struct sta_info *sta;
-
-		sta = ap_get_sta(hapd, mgmt->sa);
 		if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
 			wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action "
 				   "frame from unassociated STA " MACSTR,
@@ -1366,7 +1396,7 @@
 	}
 #endif /* CONFIG_IEEE80211R */
 	case WLAN_ACTION_WMM:
-		hostapd_wme_action(hapd, mgmt, len);
+		hostapd_wmm_action(hapd, mgmt, len);
 		return;
 #ifdef CONFIG_IEEE80211W
 	case WLAN_ACTION_SA_QUERY:
@@ -1533,24 +1563,16 @@
 		     struct ht_cap_ie *ht_cap_ie,
 		     struct ht_cap_ie *neg_ht_cap_ie)
 {
+	u16 cap;
 
 	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;
+	cap = le_to_host16(neg_ht_cap_ie->data.capabilities_info);
+	cap &= hapd->iconf->ht_capab;
+	cap |= (hapd->iconf->ht_capab & 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;
+	cap |= (hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK);
+	neg_ht_cap_ie->data.capabilities_info = host_to_le16(cap);
 }
 #endif /* CONFIG_IEEE80211N */
 
@@ -1566,6 +1588,7 @@
 	struct ht_cap_ie ht_cap;
 #endif /* CONFIG_IEEE80211N */
 	struct ht_cap_ie *ht_cap_ptr = NULL;
+	int set_flags, flags_and, flags_or;
 
 	if (!ok) {
 		hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
@@ -1624,6 +1647,13 @@
 #ifdef CONFIG_IEEE80211W
 	sta->sa_query_timed_out = 0;
 #endif /* CONFIG_IEEE80211W */
+
+	/*
+	 * Remove the STA entry in order to make sure the STA PS state gets
+	 * cleared and configuration gets updated in case of reassociation back
+	 * to the same AP.
+	 */
+	hostapd_sta_remove(hapd, sta->addr);
 
 	if (hostapd_sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid,
 			    sta->capability, sta->supported_rates,
@@ -1646,13 +1676,15 @@
 		/* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
 		ap_sta_bind_vlan(hapd, sta, 0);
 	}
-	if (sta->flags & WLAN_STA_SHORT_PREAMBLE) {
-		hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
-				      WLAN_STA_SHORT_PREAMBLE, ~0);
-	} else {
-		hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
-				      0, ~WLAN_STA_SHORT_PREAMBLE);
-	}
+
+	set_flags = WLAN_STA_SHORT_PREAMBLE | WLAN_STA_WMM | WLAN_STA_MFP;
+	if (!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
+	    sta->flags & WLAN_STA_AUTHORIZED)
+		set_flags |= WLAN_STA_AUTHORIZED;
+	flags_or = sta->flags & set_flags;
+	flags_and = sta->flags | ~set_flags;
+	hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+			      flags_or, flags_and);
 
 	if (sta->auth_alg == WLAN_AUTH_FT)
 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);

Modified: hostapd/trunk/hostapd/ieee802_1x.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/ieee802_1x.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/ieee802_1x.c (original)
+++ hostapd/trunk/hostapd/ieee802_1x.c Thu Feb 11 04:49:20 2010
@@ -164,7 +164,7 @@
 	}
 	os_memcpy(ekey, key->key_iv, sizeof(key->key_iv));
 	os_memcpy(ekey + sizeof(key->key_iv), sm->eap_if->eapKeyData, 32);
-	rc4((u8 *) (key + 1), key_len, ekey, ekey_len);
+	rc4_skip(ekey, ekey_len, 0, (u8 *) (key + 1), key_len);
 	os_free(ekey);
 
 	/* This header is needed here for HMAC-MD5, but it will be regenerated

Modified: hostapd/trunk/hostapd/preauth.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/preauth.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/preauth.c (original)
+++ hostapd/trunk/hostapd/preauth.c Thu Feb 11 04:49:20 2010
@@ -171,6 +171,7 @@
 
 		if (rsn_preauth_iface_add(hapd, start)) {
 			rsn_preauth_iface_deinit(hapd);
+			os_free(tmp);
 			return -1;
 		}
 

Modified: hostapd/trunk/hostapd/wme.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wme.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wme.c (original)
+++ hostapd/trunk/hostapd/wme.c Thu Feb 11 04:49:20 2010
@@ -24,47 +24,63 @@
 
 /* TODO: maintain separate sequence and fragment numbers for each AC
  * TODO: IGMP snooping to track which multicasts to forward - and use QOS-DATA
- * if only WME stations are receiving a certain group */
-
-
-static u8 wme_oui[3] = { 0x00, 0x50, 0xf2 };
-
-
-/* Add WME Parameter Element to Beacon and Probe Response frames. */
-u8 * hostapd_eid_wme(struct hostapd_data *hapd, u8 *eid)
+ * if only WMM stations are receiving a certain group */
+
+
+static inline u8 wmm_aci_aifsn(int aifsn, int acm, int aci)
+{
+	u8 ret;
+	ret = (aifsn << WMM_AC_AIFNS_SHIFT) & WMM_AC_AIFSN_MASK;
+	if (acm)
+		ret |= WMM_AC_ACM;
+	ret |= (aci << WMM_AC_ACI_SHIFT) & WMM_AC_ACI_MASK;
+	return ret;
+}
+
+
+static inline u8 wmm_ecw(int ecwmin, int ecwmax)
+{
+	return ((ecwmin << WMM_AC_ECWMIN_SHIFT) & WMM_AC_ECWMIN_MASK) |
+		((ecwmax << WMM_AC_ECWMAX_SHIFT) & WMM_AC_ECWMAX_MASK);
+}
+
+
+/*
+ * Add WMM Parameter Element to Beacon, Probe Response, and (Re)Association
+ * Response frames.
+ */
+u8 * hostapd_eid_wmm(struct hostapd_data *hapd, u8 *eid)
 {
 	u8 *pos = eid;
-	struct wme_parameter_element *wme =
-		(struct wme_parameter_element *) (pos + 2);
+	struct wmm_parameter_element *wmm =
+		(struct wmm_parameter_element *) (pos + 2);
 	int e;
 
-	if (!hapd->conf->wme_enabled)
+	if (!hapd->conf->wmm_enabled)
 		return eid;
 	eid[0] = WLAN_EID_VENDOR_SPECIFIC;
-	wme->oui[0] = 0x00;
-	wme->oui[1] = 0x50;
-	wme->oui[2] = 0xf2;
-	wme->oui_type = WME_OUI_TYPE;
-	wme->oui_subtype = WME_OUI_SUBTYPE_PARAMETER_ELEMENT;
-	wme->version = WME_VERSION;
-	wme->acInfo = hapd->parameter_set_count & 0xf;
+	wmm->oui[0] = 0x00;
+	wmm->oui[1] = 0x50;
+	wmm->oui[2] = 0xf2;
+	wmm->oui_type = WMM_OUI_TYPE;
+	wmm->oui_subtype = WMM_OUI_SUBTYPE_PARAMETER_ELEMENT;
+	wmm->version = WMM_VERSION;
+	wmm->qos_info = hapd->parameter_set_count & 0xf;
 
 	/* fill in a parameter set record for each AC */
 	for (e = 0; e < 4; e++) {
-		struct wme_ac_parameter *ac = &wme->ac[e];
-		struct hostapd_wme_ac_params *acp =
-			&hapd->iconf->wme_ac_params[e];
-
-		ac->aifsn = acp->aifs;
-		ac->acm = acp->admission_control_mandatory;
-		ac->aci = e;
-		ac->reserved = 0;
-		ac->eCWmin = acp->cwmin;
-		ac->eCWmax = acp->cwmax;
-		ac->txopLimit = host_to_le16(acp->txopLimit);
-	}
-
-	pos = (u8 *) (wme + 1);
+		struct wmm_ac_parameter *ac = &wmm->ac[e];
+		struct hostapd_wmm_ac_params *acp =
+			&hapd->iconf->wmm_ac_params[e];
+
+		ac->aci_aifsn = wmm_aci_aifsn(acp->aifs,
+					      acp->admission_control_mandatory,
+					      e);
+		ac->cw = wmm_ecw(acp->cwmin, acp->cwmax);
+		ac->txop_limit = host_to_le16(acp->txop_limit);
+	}
+
+	pos = (u8 *) (wmm + 1);
 	eid[1] = pos - eid - 2; /* element length */
 
 	return pos;
@@ -72,31 +88,28 @@
 
 
 /* This function is called when a station sends an association request with
- * WME info element. The function returns zero on success or non-zero on any
- * error in WME element. eid does not include Element ID and Length octets. */
-int hostapd_eid_wme_valid(struct hostapd_data *hapd, u8 *eid, size_t len)
-{
-	struct wme_information_element *wme;
-
-	wpa_hexdump(MSG_MSGDUMP, "WME IE", eid, len);
-
-	if (len < sizeof(struct wme_information_element)) {
-		wpa_printf(MSG_DEBUG, "Too short WME IE (len=%lu)",
+ * WMM info element. The function returns zero on success or non-zero on any
+ * error in WMM element. eid does not include Element ID and Length octets. */
+int hostapd_eid_wmm_valid(struct hostapd_data *hapd, u8 *eid, size_t len)
+{
+	struct wmm_information_element *wmm;
+
+	wpa_hexdump(MSG_MSGDUMP, "WMM IE", eid, len);
+
+	if (len < sizeof(struct wmm_information_element)) {
+		wpa_printf(MSG_DEBUG, "Too short WMM IE (len=%lu)",
 			   (unsigned long) len);
 		return -1;
 	}
 
-	wme = (struct wme_information_element *) eid;
-	wpa_printf(MSG_DEBUG, "Validating WME IE: OUI %02x:%02x:%02x  "
-		   "OUI type %d  OUI sub-type %d  version %d",
-		   wme->oui[0], wme->oui[1], wme->oui[2], wme->oui_type,
-		   wme->oui_subtype, wme->version);
-	if (os_memcmp(wme->oui, wme_oui, sizeof(wme_oui)) != 0 ||
-	    wme->oui_type != WME_OUI_TYPE ||
-	    wme->oui_subtype != WME_OUI_SUBTYPE_INFORMATION_ELEMENT ||
-	    wme->version != WME_VERSION) {
-		wpa_printf(MSG_DEBUG, "Unsupported WME IE OUI/Type/Subtype/"
-			   "Version");
+	wmm = (struct wmm_information_element *) eid;
+	wpa_printf(MSG_DEBUG, "Validating WMM IE: OUI %02x:%02x:%02x  "
+		   "OUI type %d  OUI sub-type %d  version %d  QoS info 0x%x",
+		   wmm->oui[0], wmm->oui[1], wmm->oui[2], wmm->oui_type,
+		   wmm->oui_subtype, wmm->version, wmm->qos_info);
+	if (wmm->oui_subtype != WMM_OUI_SUBTYPE_INFORMATION_ELEMENT ||
+	    wmm->version != WMM_VERSION) {
+		wpa_printf(MSG_DEBUG, "Unsupported WMM IE Subtype/Version");
 		return -1;
 	}
 
@@ -105,31 +118,30 @@
 
 
 /* This function is called when a station sends an ACK frame for an AssocResp
- * frame (status=success) and the matching AssocReq contained a WME element.
+ * frame (status=success) and the matching AssocReq contained a WMM element.
  */
-int hostapd_wme_sta_config(struct hostapd_data *hapd, struct sta_info *sta)
-{
-	/* update kernel STA data for WME related items (WLAN_STA_WPA flag) */
-	if (sta->flags & WLAN_STA_WME)
+int hostapd_wmm_sta_config(struct hostapd_data *hapd, struct sta_info *sta)
+{
+	/* update kernel STA data for WMM related items (WLAN_STA_WPA flag) */
+	if (sta->flags & WLAN_STA_WMM)
 		hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
-				      WLAN_STA_WME, ~0);
+				      WLAN_STA_WMM, ~0);
 	else
 		hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
-				      0, ~WLAN_STA_WME);
+				      0, ~WLAN_STA_WMM);
 
 	return 0;
 }
 
 
-static void wme_send_action(struct hostapd_data *hapd, const u8 *addr,
-			    const struct wme_tspec_info_element *tspec,
+static void wmm_send_action(struct hostapd_data *hapd, const u8 *addr,
+			    const struct wmm_tspec_element *tspec,
 			    u8 action_code, u8 dialogue_token, u8 status_code)
 {
 	u8 buf[256];
 	struct ieee80211_mgmt *m = (struct ieee80211_mgmt *) buf;
-	struct wme_tspec_info_element *t =
-		(struct wme_tspec_info_element *)
-		m->u.action.u.wme_action.variable;
+	struct wmm_tspec_element *t = (struct wmm_tspec_element *)
+		m->u.action.u.wmm_action.variable;
 	int len;
 
 	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
@@ -142,20 +154,20 @@
 	os_memcpy(m->sa, hapd->own_addr, ETH_ALEN);
 	os_memcpy(m->bssid, hapd->own_addr, ETH_ALEN);
 	m->u.action.category = WLAN_ACTION_WMM;
-	m->u.action.u.wme_action.action_code = action_code;
-	m->u.action.u.wme_action.dialog_token = dialogue_token;
-	m->u.action.u.wme_action.status_code = status_code;
-	os_memcpy(t, tspec, sizeof(struct wme_tspec_info_element));
+	m->u.action.u.wmm_action.action_code = action_code;
+	m->u.action.u.wmm_action.dialog_token = dialogue_token;
+	m->u.action.u.wmm_action.status_code = status_code;
+	os_memcpy(t, tspec, sizeof(struct wmm_tspec_element));
 	len = ((u8 *) (t + 1)) - buf;
 
 	if (hostapd_send_mgmt_frame(hapd, m, len, 0) < 0)
-		perror("wme_send_action: send");
-}
-
-
-static void wme_setup_request(struct hostapd_data *hapd,
-			      struct ieee80211_mgmt *mgmt,
-			      struct wme_tspec_info_element *tspec, size_t len)
+		perror("wmm_send_action: send");
+}
+
+
+static void wmm_addts_req(struct hostapd_data *hapd,
+			  struct ieee80211_mgmt *mgmt,
+			  struct wmm_tspec_element *tspec, size_t len)
 {
 	u8 *end = ((u8 *) mgmt) + len;
 	int medium_time, pps, duration;
@@ -169,7 +181,7 @@
 
 	wpa_printf(MSG_DEBUG, "WMM: ADDTS Request (Dialog Token %d) for TSPEC "
 		   "from " MACSTR,
-		   mgmt->u.action.u.wme_action.dialog_token,
+		   mgmt->u.action.u.wmm_action.dialog_token,
 		   MAC2STR(mgmt->sa));
 
 	up = (tspec->ts_info[1] >> 3) & 0x07;
@@ -229,30 +241,30 @@
 	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);
+		wmm_send_action(hapd, mgmt->sa, tspec,
+				WMM_ACTION_CODE_ADDTS_RESP,
+				mgmt->u.action.u.wmm_action.dialog_token,
+				WMM_ADDTS_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);
+	wmm_send_action(hapd, mgmt->sa, tspec, WMM_ACTION_CODE_ADDTS_RESP,
+			mgmt->u.action.u.wmm_action.dialog_token,
+			WMM_ADDTS_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);
-}
-
-
-void hostapd_wme_action(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
+	wmm_send_action(hapd, mgmt->sa, tspec,
+			WMM_ACTION_CODE_ADDTS_RESP,
+			mgmt->u.action.u.wmm_action.dialog_token,
+			WMM_ADDTS_STATUS_INVALID_PARAMETERS);
+}
+
+
+void hostapd_wmm_action(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
 			size_t len)
 {
 	int action_code;
@@ -263,11 +275,11 @@
 
 	/* check that the request comes from a valid station */
 	if (!sta ||
-	    (sta->flags & (WLAN_STA_ASSOC | WLAN_STA_WME)) !=
-	    (WLAN_STA_ASSOC | WLAN_STA_WME)) {
+	    (sta->flags & (WLAN_STA_ASSOC | WLAN_STA_WMM)) !=
+	    (WLAN_STA_ASSOC | WLAN_STA_WMM)) {
 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_DEBUG,
-			       "wme action received is not from associated wme"
+			       "wmm action received is not from associated wmm"
 			       " station");
 		/* TODO: respond with action frame refused status code */
 		return;
@@ -277,19 +289,18 @@
 	if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_DEBUG,
-			       "hostapd_wme_action - could not parse wme "
+			       "hostapd_wmm_action - could not parse wmm "
 			       "action");
 		/* TODO: respond with action frame invalid parameters status
 		 * code */
 		return;
 	}
 
-	if (!elems.wme_tspec ||
-	    elems.wme_tspec_len != (sizeof(struct wme_tspec_info_element) - 2))
-	{
+	if (!elems.wmm_tspec ||
+	    elems.wmm_tspec_len != (sizeof(struct wmm_tspec_element) - 2)) {
 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_DEBUG,
-			       "hostapd_wme_action - missing or wrong length "
+			       "hostapd_wmm_action - missing or wrong length "
 			       "tspec");
 		/* TODO: respond with action frame invalid parameters status
 		 * code */
@@ -299,26 +310,26 @@
 	/* TODO: check the request is for an AC with ACM set, if not, refuse
 	 * request */
 
-	action_code = mgmt->u.action.u.wme_action.action_code;
+	action_code = mgmt->u.action.u.wmm_action.action_code;
 	switch (action_code) {
-	case WME_ACTION_CODE_SETUP_REQUEST:
-		wme_setup_request(hapd, mgmt, (struct wme_tspec_info_element *)
-				  elems.wme_tspec, len);
+	case WMM_ACTION_CODE_ADDTS_REQ:
+		wmm_addts_req(hapd, mgmt, (struct wmm_tspec_element *)
+			      (elems.wmm_tspec - 2), len);
 		return;
 #if 0
 	/* TODO: needed for client implementation */
-	case WME_ACTION_CODE_SETUP_RESPONSE:
-		wme_setup_request(hapd, mgmt, len);
+	case WMM_ACTION_CODE_ADDTS_RESP:
+		wmm_setup_request(hapd, mgmt, len);
 		return;
 	/* TODO: handle station teardown requests */
-	case WME_ACTION_CODE_TEARDOWN:
-		wme_teardown(hapd, mgmt, len);
+	case WMM_ACTION_CODE_DELTS:
+		wmm_teardown(hapd, mgmt, len);
 		return;
 #endif
 	}
 
 	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_DEBUG,
-		       "hostapd_wme_action - unknown action code %d",
+		       "hostapd_wmm_action - unknown action code %d",
 		       action_code);
 }

Modified: hostapd/trunk/hostapd/wme.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wme.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wme.h (original)
+++ hostapd/trunk/hostapd/wme.h Thu Feb 11 04:49:20 2010
@@ -16,76 +16,57 @@
 #ifndef WME_H
 #define WME_H
 
-#ifdef __linux__
-#include <endian.h>
-#endif /* __linux__ */
-
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
-#include <sys/types.h>
-#include <sys/endian.h>
-#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
-	* defined(__DragonFly__) */
-
-
-extern inline u16 tsinfo(int tag1d, int contention_based, int direction)
-{
-	return (tag1d << 11) | (contention_based << 7) | (direction << 5) |
-	  (tag1d << 1);
-}
-
-
-struct wme_information_element {
-	/* required fields for WME version 1 */
-	u8 oui[3];
-	u8 oui_type;
-	u8 oui_subtype;
-	u8 version;
-	u8 acInfo;
+/*
+ * WMM Information Element (used in (Re)Association Request frames; may also be
+ * used in Beacon frames)
+ */
+struct wmm_information_element {
+	/* Element ID: 221 (0xdd); Length: 7 */
+	/* required fields for WMM version 1 */
+	u8 oui[3]; /* 00:50:f2 */
+	u8 oui_type; /* 2 */
+	u8 oui_subtype; /* 0 */
+	u8 version; /* 1 for WMM version 1.0 */
+	u8 qos_info; /* AP/STA specific QoS info */
 
 } __attribute__ ((packed));
 
-struct wme_ac_parameter {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-	/* byte 1 */
-	u8 	aifsn:4,
-		acm:1,
-	 	aci:2,
-	 	reserved:1;
+#define WMM_AC_AIFSN_MASK 0x0f
+#define WMM_AC_AIFNS_SHIFT 0
+#define WMM_AC_ACM 0x10
+#define WMM_AC_ACI_MASK 0x60
+#define WMM_AC_ACI_SHIFT 5
 
-	/* byte 2 */
-	u8 	eCWmin:4,
-	 	eCWmax:4;
-#elif __BYTE_ORDER == __BIG_ENDIAN
-	/* byte 1 */
-	u8 	reserved:1,
-	 	aci:2,
-	 	acm:1,
-	 	aifsn:4;
+#define WMM_AC_ECWMIN_MASK 0x0f
+#define WMM_AC_ECWMIN_SHIFT 0
+#define WMM_AC_ECWMAX_MASK 0xf0
+#define WMM_AC_ECWMAX_SHIFT 4
 
-	/* byte 2 */
-	u8 	eCWmax:4,
-	 	eCWmin:4;
-#else
-#error	"Please fix <endian.h>"
-#endif
-
-	/* bytes 3 & 4 */
-	le16 txopLimit;
+struct wmm_ac_parameter {
+	u8 aci_aifsn; /* AIFSN, ACM, ACI */
+	u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */
+	le16 txop_limit;
 } __attribute__ ((packed));
 
-struct wme_parameter_element {
-	/* required fields for WME version 1 */
-	u8 oui[3];
-	u8 oui_type;
-	u8 oui_subtype;
-	u8 version;
-	u8 acInfo;
-	u8 reserved;
-	struct wme_ac_parameter ac[4];
+/*
+ * WMM Parameter Element (used in Beacon, Probe Response, and (Re)Association
+ * Response frmaes)
+ */
+struct wmm_parameter_element {
+	/* Element ID: 221 (0xdd); Length: 24 */
+	/* required fields for WMM version 1 */
+	u8 oui[3]; /* 00:50:f2 */
+	u8 oui_type; /* 2 */
+	u8 oui_subtype; /* 1 */
+	u8 version; /* 1 for WMM version 1.0 */
+	u8 qos_info; /* AP/STA specif QoS info */
+	u8 reserved; /* 0 */
+	struct wmm_ac_parameter ac[4]; /* AC_BE, AC_BK, AC_VI, AC_VO */
 
 } __attribute__ ((packed));
 
-struct wme_tspec_info_element {
+/* WMM TSPEC Element */
+struct wmm_tspec_element {
 	u8 eid; /* 221 = 0xdd */
 	u8 length; /* 6 + 55 = 61 */
 	u8 oui[3]; /* 00:50:f2 */
@@ -112,20 +93,20 @@
 } __attribute__ ((packed));
 
 
-/* Access Categories */
+/* Access Categories / ACI to AC coding */
 enum {
-	WME_AC_BK = 1,
-	WME_AC_BE = 0,
-	WME_AC_VI = 2,
-	WME_AC_VO = 3
+	WMM_AC_BE = 0 /* Best Effort */,
+	WMM_AC_BK = 1 /* Background */,
+	WMM_AC_VI = 2 /* Video */,
+	WMM_AC_VO = 3 /* Voice */
 };
 
 struct ieee80211_mgmt;
 
-u8 * hostapd_eid_wme(struct hostapd_data *hapd, u8 *eid);
-int hostapd_eid_wme_valid(struct hostapd_data *hapd, u8 *eid, size_t len);
-int hostapd_wme_sta_config(struct hostapd_data *hapd, struct sta_info *sta);
-void hostapd_wme_action(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
+u8 * hostapd_eid_wmm(struct hostapd_data *hapd, u8 *eid);
+int hostapd_eid_wmm_valid(struct hostapd_data *hapd, u8 *eid, size_t len);
+int hostapd_wmm_sta_config(struct hostapd_data *hapd, struct sta_info *sta);
+void hostapd_wmm_action(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
 			size_t len);
 
 #endif /* WME_H */

Modified: hostapd/trunk/hostapd/wpa.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wpa.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wpa.c (original)
+++ hostapd/trunk/hostapd/wpa.c Thu Feb 11 04:49:20 2010
@@ -1,6 +1,6 @@
 /*
  * hostapd - IEEE 802.11i-2004 / WPA Authenticator
- * Copyright (c) 2004-2008, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2009, Jouni Malinen <j at w1.fi>
  *
  * 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
@@ -44,6 +44,8 @@
 static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
 			      struct wpa_group *group);
 static void wpa_request_new_ptk(struct wpa_state_machine *sm);
+static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
+			  struct wpa_group *group);
 
 static const u32 dot11RSNAConfigGroupUpdateCount = 4;
 static const u32 dot11RSNAConfigPairwiseUpdateCount = 4;
@@ -286,6 +288,25 @@
 }
 
 
+static void wpa_group_set_key_len(struct wpa_group *group, int cipher)
+{
+	switch (cipher) {
+	case WPA_CIPHER_CCMP:
+		group->GTK_len = 16;
+		break;
+	case WPA_CIPHER_TKIP:
+		group->GTK_len = 32;
+		break;
+	case WPA_CIPHER_WEP104:
+		group->GTK_len = 13;
+		break;
+	case WPA_CIPHER_WEP40:
+		group->GTK_len = 5;
+		break;
+	}
+}
+
+
 static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
 					 int vlan_id)
 {
@@ -300,20 +321,7 @@
 	group->GTKAuthenticator = TRUE;
 	group->vlan_id = vlan_id;
 
-	switch (wpa_auth->conf.wpa_group) {
-	case WPA_CIPHER_CCMP:
-		group->GTK_len = 16;
-		break;
-	case WPA_CIPHER_TKIP:
-		group->GTK_len = 32;
-		break;
-	case WPA_CIPHER_WEP104:
-		group->GTK_len = 13;
-		break;
-	case WPA_CIPHER_WEP40:
-		group->GTK_len = 5;
-		break;
-	}
+	wpa_group_set_key_len(group, wpa_auth->conf.wpa_group);
 
 	/* Counter = PRF-256(Random number, "Init Counter",
 	 *                   Local MAC Address || Time)
@@ -451,6 +459,7 @@
 int wpa_reconfig(struct wpa_authenticator *wpa_auth,
 		 struct wpa_auth_config *conf)
 {
+	struct wpa_group *group;
 	if (wpa_auth == NULL)
 		return 0;
 
@@ -459,6 +468,17 @@
 		wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
 		return -1;
 	}
+
+	/*
+	 * Reinitialize GTK to make sure it is suitable for the new
+	 * configuration.
+	 */
+	group = wpa_auth->group;
+	wpa_group_set_key_len(group, wpa_auth->conf.wpa_group);
+	group->GInit = TRUE;
+	wpa_group_sm_step(wpa_auth, group);
+	group->GInit = FALSE;
+	wpa_group_sm_step(wpa_auth, group);
 
 	return 0;
 }
@@ -617,6 +637,22 @@
 			   (unsigned long) (data_len - sizeof(*hdr) -
 					    sizeof(*key)));
 		return;
+	}
+
+	if (sm->wpa == WPA_VERSION_WPA2) {
+		if (key->type != EAPOL_KEY_TYPE_RSN) {
+			wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
+				   "unexpected type %d in RSN mode",
+				   key->type);
+			return;
+		}
+	} else {
+		if (key->type != EAPOL_KEY_TYPE_WPA) {
+			wpa_printf(MSG_DEBUG, "Ignore EAPOL-Key with "
+				   "unexpected type %d in WPA mode",
+				   key->type);
+			return;
+		}
 	}
 
 	/* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys
@@ -1403,14 +1439,15 @@
 static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *pmk,
 			  struct wpa_ptk *ptk)
 {
+	size_t ptk_len = sm->pairwise == WPA_CIPHER_CCMP ? 48 : 64;
 #ifdef CONFIG_IEEE80211R
 	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
-		return wpa_auth_derive_ptk_ft(sm, pmk, ptk);
+		return wpa_auth_derive_ptk_ft(sm, pmk, ptk, ptk_len);
 #endif /* CONFIG_IEEE80211R */
 
 	wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
 		       sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce,
-		       (u8 *) ptk, sizeof(*ptk),
+		       (u8 *) ptk, ptk_len,
 		       wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
 
 	return 0;

Modified: hostapd/trunk/hostapd/wpa.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wpa.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wpa.h (original)
+++ hostapd/trunk/hostapd/wpa.h Thu Feb 11 04:49:20 2010
@@ -141,7 +141,7 @@
 	int rsn_preauth;
 	int eapol_version;
 	int peerkey;
-	int wme_enabled;
+	int wmm_enabled;
 	int okc;
 #ifdef CONFIG_IEEE80211W
 	enum {

Modified: hostapd/trunk/hostapd/wpa_auth_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wpa_auth_i.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wpa_auth_i.h (original)
+++ hostapd/trunk/hostapd/wpa_auth_i.h Thu Feb 11 04:49:20 2010
@@ -213,7 +213,7 @@
 #ifdef CONFIG_IEEE80211R
 int wpa_write_mdie(struct wpa_auth_config *conf, u8 *buf, size_t len);
 int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
-			   struct wpa_ptk *ptk);
+			   struct wpa_ptk *ptk, size_t ptk_len);
 struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void);
 void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
 #endif /* CONFIG_IEEE80211R */

Modified: hostapd/trunk/hostapd/wpa_auth_ie.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wpa_auth_ie.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wpa_auth_ie.c (original)
+++ hostapd/trunk/hostapd/wpa_auth_ie.c Thu Feb 11 04:49:20 2010
@@ -215,8 +215,8 @@
 		capab |= WPA_CAPABILITY_PREAUTH;
 	if (conf->peerkey)
 		capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
-	if (conf->wme_enabled) {
-		/* 4 PTKSA replay counters when using WME */
+	if (conf->wmm_enabled) {
+		/* 4 PTKSA replay counters when using WMM */
 		capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
 	}
 #ifdef CONFIG_IEEE80211W

Modified: hostapd/trunk/hostapd/wpa_ft.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wpa_ft.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wpa_ft.c (original)
+++ hostapd/trunk/hostapd/wpa_ft.c Thu Feb 11 04:49:20 2010
@@ -321,7 +321,7 @@
 
 
 int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk,
-			   struct wpa_ptk *ptk)
+			   struct wpa_ptk *ptk, size_t ptk_len)
 {
 	u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN];
 	u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN];
@@ -354,8 +354,8 @@
 
 	wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
 			  sm->wpa_auth->addr, pmk_r1_name,
-			  (u8 *) ptk, sizeof(*ptk), ptk_name);
-	wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, sizeof(*ptk));
+			  (u8 *) ptk, ptk_len, ptk_name);
+	wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, ptk_len);
 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
 
 	return 0;
@@ -714,7 +714,7 @@
 	u8 ptk_name[WPA_PMK_NAME_LEN];
 	struct wpa_auth_config *conf;
 	struct wpa_ft_ies parse;
-	size_t buflen;
+	size_t buflen, ptk_len;
 	int ret;
 	u8 *pos, *end;
 
@@ -804,11 +804,12 @@
 	wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce",
 		    sm->ANonce, WPA_NONCE_LEN);
 
+	ptk_len = sm->pairwise == WPA_CIPHER_CCMP ? 48 : 64;
 	wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr,
 			  sm->wpa_auth->addr, pmk_r1_name,
-			  (u8 *) &sm->PTK, sizeof(sm->PTK), ptk_name);
+			  (u8 *) &sm->PTK, ptk_len, ptk_name);
 	wpa_hexdump_key(MSG_DEBUG, "FT: PTK",
-			(u8 *) &sm->PTK, sizeof(sm->PTK));
+			(u8 *) &sm->PTK, ptk_len);
 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
 
 	wpa_ft_install_ptk(sm);

Modified: hostapd/trunk/hostapd/wps_hostapd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wps_hostapd.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wps_hostapd.c (original)
+++ hostapd/trunk/hostapd/wps_hostapd.c Thu Feb 11 04:49:20 2010
@@ -219,19 +219,41 @@
 	if ((hapd->conf->wps_cred_processing == 1 ||
 	     hapd->conf->wps_cred_processing == 2) && cred->cred_attr) {
 		size_t blen = cred->cred_attr_len * 2 + 1;
-		char *buf = os_malloc(blen);
-		if (buf) {
-			wpa_snprintf_hex(buf, blen,
+		char *_buf = os_malloc(blen);
+		if (_buf) {
+			wpa_snprintf_hex(_buf, blen,
 					 cred->cred_attr, cred->cred_attr_len);
 			wpa_msg(hapd, MSG_INFO, "%s%s",
-				WPS_EVENT_NEW_AP_SETTINGS, buf);
-			os_free(buf);
+				WPS_EVENT_NEW_AP_SETTINGS, _buf);
+			os_free(_buf);
 		}
 	} else
 		wpa_msg(hapd, MSG_INFO, WPS_EVENT_NEW_AP_SETTINGS);
 
 	if (hapd->conf->wps_cred_processing == 1)
 		return 0;
+
+	os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len);
+	hapd->wps->ssid_len = cred->ssid_len;
+	hapd->wps->encr_types = cred->encr_type;
+	hapd->wps->auth_types = cred->auth_type;
+	if (cred->key_len == 0) {
+		os_free(hapd->wps->network_key);
+		hapd->wps->network_key = NULL;
+		hapd->wps->network_key_len = 0;
+	} else {
+		if (hapd->wps->network_key == NULL ||
+		    hapd->wps->network_key_len < cred->key_len) {
+			hapd->wps->network_key_len = 0;
+			os_free(hapd->wps->network_key);
+			hapd->wps->network_key = os_malloc(cred->key_len);
+			if (hapd->wps->network_key == NULL)
+				return -1;
+		}
+		hapd->wps->network_key_len = cred->key_len;
+		os_memcpy(hapd->wps->network_key, cred->key, cred->key_len);
+	}
+	hapd->wps->wps_state = WPS_STATE_CONFIGURED;
 
 	len = os_strlen(hapd->iface->config_fname) + 5;
 	tmp_fname = os_malloc(len);
@@ -677,7 +699,7 @@
 
 
 int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
-			const char *pin)
+			const char *pin, int timeout)
 {
 	u8 u[UUID_LEN];
 	int any = 0;
@@ -689,7 +711,8 @@
 	else if (uuid_str2bin(uuid, u))
 		return -1;
 	return wps_registrar_add_pin(hapd->wps->registrar, any ? NULL : u,
-				     (const u8 *) pin, os_strlen(pin));
+				     (const u8 *) pin, os_strlen(pin),
+				     timeout);
 }
 
 
@@ -872,8 +895,8 @@
 
 	wpa_printf(MSG_DEBUG, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr="
 		   MACSTR, ev_type, MAC2STR(mac_addr));
-	wpa_hexdump_ascii(MSG_MSGDUMP, "WPS UPnP: PutWLANResponse NewMessage",
-			  wpabuf_head(msg), wpabuf_len(msg));
+	wpa_hexdump(MSG_MSGDUMP, "WPS UPnP: PutWLANResponse NewMessage",
+		    wpabuf_head(msg), wpabuf_len(msg));
 	if (ev_type != UPNP_WPS_WLANEVENT_TYPE_EAP) {
 		wpa_printf(MSG_DEBUG, "WPS UPnP: Ignored unexpected "
 			   "PutWLANResponse WLANEventType %d", ev_type);

Modified: hostapd/trunk/hostapd/wps_hostapd.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/wps_hostapd.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/hostapd/wps_hostapd.h (original)
+++ hostapd/trunk/hostapd/wps_hostapd.h Thu Feb 11 04:49:20 2010
@@ -21,7 +21,7 @@
 		     struct hostapd_bss_config *conf);
 void hostapd_deinit_wps(struct hostapd_data *hapd);
 int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
-			const char *pin);
+			const char *pin, int timeout);
 int hostapd_wps_button_pushed(struct hostapd_data *hapd);
 void hostapd_wps_probe_req_rx(struct hostapd_data *hapd, const u8 *addr,
 			      const u8 *ie, size_t ie_len);

Modified: hostapd/trunk/src/common/ieee802_11_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/common/ieee802_11_common.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/common/ieee802_11_common.c (original)
+++ hostapd/trunk/src/common/ieee802_11_common.c Thu Feb 11 04:49:20 2010
@@ -49,26 +49,33 @@
 			elems->wpa_ie = pos;
 			elems->wpa_ie_len = elen;
 			break;
-		case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
+		case WMM_OUI_TYPE:
+			/* WMM information element */
 			if (elen < 5) {
-				wpa_printf(MSG_MSGDUMP, "short WME "
+				wpa_printf(MSG_MSGDUMP, "short WMM "
 					   "information element ignored "
 					   "(len=%lu)",
 					   (unsigned long) elen);
 				return -1;
 			}
 			switch (pos[4]) {
-			case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
-			case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
-				elems->wme = pos;
-				elems->wme_len = elen;
+			case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
+			case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
+				/*
+				 * Share same pointer since only one of these
+				 * is used and they start with same data.
+				 * Length field can be used to distinguish the
+				 * IEs.
+				 */
+				elems->wmm = pos;
+				elems->wmm_len = elen;
 				break;
-			case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
-				elems->wme_tspec = pos;
-				elems->wme_tspec_len = elen;
+			case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
+				elems->wmm_tspec = pos;
+				elems->wmm_tspec_len = elen;
 				break;
 			default:
-				wpa_printf(MSG_MSGDUMP, "unknown WME "
+				wpa_printf(MSG_MSGDUMP, "unknown WMM "
 					   "information element ignored "
 					   "(subtype=%d len=%lu)",
 					   pos[4], (unsigned long) elen);

Modified: hostapd/trunk/src/common/ieee802_11_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/common/ieee802_11_common.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/common/ieee802_11_common.h (original)
+++ hostapd/trunk/src/common/ieee802_11_common.h Thu Feb 11 04:49:20 2010
@@ -41,10 +41,10 @@
 	u8 wpa_ie_len;
 	u8 *rsn_ie;
 	u8 rsn_ie_len;
-	u8 *wme;
-	u8 wme_len;
-	u8 *wme_tspec;
-	u8 wme_tspec_len;
+	u8 *wmm; /* WMM Information or Parameter Element */
+	u8 wmm_len; /* 7 = WMM Information; 24 = WMM Parameter */
+	u8 *wmm_tspec;
+	u8 wmm_tspec_len;
 	u8 *wps_ie;
 	u8 wps_ie_len;
 	u8 *power_cap;

Modified: hostapd/trunk/src/common/ieee802_11_defs.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/common/ieee802_11_defs.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/common/ieee802_11_defs.h (original)
+++ hostapd/trunk/src/common/ieee802_11_defs.h Thu Feb 11 04:49:20 2010
@@ -210,16 +210,18 @@
 #define WLAN_ACTION_QOS 1
 #define WLAN_ACTION_DLS 2
 #define WLAN_ACTION_BLOCK_ACK 3
+#define WLAN_ACTION_PUBLIC 4
 #define WLAN_ACTION_RADIO_MEASUREMENT 5
 #define WLAN_ACTION_FT 6
+#define WLAN_ACTION_HT 7
 #define WLAN_ACTION_SA_QUERY 8
-#define WLAN_ACTION_WMM 17
-
-/* SA Query Action frame (IEEE 802.11w/D7.0, 7.4.9) */
+#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */
+
+/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */
 #define WLAN_SA_QUERY_REQUEST 0
 #define WLAN_SA_QUERY_RESPONSE 1
 
-#define WLAN_SA_QUERY_TR_ID_LEN 16
+#define WLAN_SA_QUERY_TR_ID_LEN 2
 
 /* Timeout Interval Type */
 #define WLAN_TIMEOUT_REASSOC_DEADLINE 1
@@ -300,7 +302,7 @@
 					u8 dialog_token;
 					u8 status_code;
 					u8 variable[0];
-				} STRUCT_PACKED wme_action;
+				} STRUCT_PACKED wmm_action;
 				struct{
 					u8 action_code;
 					u8 element_id;
@@ -561,23 +563,27 @@
 #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
 				* 00:50:F2 */
 
-#define WME_OUI_TYPE 2
-#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0
-#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1
-#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2
-#define WME_VERSION 1
-
-#define WME_ACTION_CODE_SETUP_REQUEST 0
-#define WME_ACTION_CODE_SETUP_RESPONSE 1
-#define WME_ACTION_CODE_TEARDOWN 2
-
-#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0
-#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1
-#define WME_SETUP_RESPONSE_STATUS_REFUSED 3
-
-#define WME_TSPEC_DIRECTION_UPLINK 0
-#define WME_TSPEC_DIRECTION_DOWNLINK 1
-#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3
+#define WMM_OUI_TYPE 2
+#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
+#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1
+#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2
+#define WMM_VERSION 1
+
+#define WMM_ACTION_CODE_ADDTS_REQ 0
+#define WMM_ACTION_CODE_ADDTS_RESP 1
+#define WMM_ACTION_CODE_DELTS 2
+
+#define WMM_ADDTS_STATUS_ADMISSION_ACCEPTED 0
+#define WMM_ADDTS_STATUS_INVALID_PARAMETERS 1
+/* 2 - Reserved */
+#define WMM_ADDTS_STATUS_REFUSED 3
+/* 4-255 - Reserved */
+
+/* WMM TSPEC Direction Field Values */
+#define WMM_TSPEC_DIRECTION_UPLINK 0
+#define WMM_TSPEC_DIRECTION_DOWNLINK 1
+/* 2 - Reserved */
+#define WMM_TSPEC_DIRECTION_BI_DIRECTIONAL 3
 
 
 #define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */

Modified: hostapd/trunk/src/common/nl80211_copy.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/common/nl80211_copy.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/common/nl80211_copy.h (original)
+++ hostapd/trunk/src/common/nl80211_copy.h Thu Feb 11 04:49:20 2010
@@ -7,7 +7,7 @@
  * Copyright 2008 Michael Wu <flamingice at sourmilk.net>
  * Copyright 2008 Luis Carlos Cobo <luisca at cozybit.com>
  * Copyright 2008 Michael Buesch <mb at bu3sch.de>
- * Copyright 2008 Luis R. Rodriguez <lrodriguez at atheros.com>
+ * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez at atheros.com>
  * Copyright 2008 Jouni Malinen <jouni.malinen at atheros.com>
  * Copyright 2008 Colin McCabe <colin at cozybit.com>
  *
@@ -25,6 +25,8 @@
  *
  */
 
+#include <linux/types.h>
+
 /**
  * DOC: Station handling
  *
@@ -46,8 +48,10 @@
  *	to get a list of all present wiphys.
  * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
  *	%NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
- *	%NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, and/or
- *	%NL80211_ATTR_WIPHY_CHANNEL_TYPE.
+ *	%NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ,
+ *	%NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
+ *	%NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ *	and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
  * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
  *	or rename notification. Has attributes %NL80211_ATTR_WIPHY and
  *	%NL80211_ATTR_WIPHY_NAME.
@@ -75,8 +79,8 @@
  * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
  *	%NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
  * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
- *	%NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER
- *	attributes.
+ *	%NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
+ *	and %NL80211_ATTR_KEY_SEQ attributes.
  * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
  *	or %NL80211_ATTR_MAC.
  *
@@ -142,6 +146,12 @@
  *	%NL80211_ATTR_IE. If the command succeeds, the requested data will be
  *	added to all specified management frames generated by
  *	kernel/firmware/driver.
+ *	Note: This command has been removed and it is only reserved at this
+ *	point to avoid re-using existing command number. The functionality this
+ *	command was planned for has been provided with cleaner design with the
+ *	option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN,
+ *	NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE,
+ *	NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE.
  *
  * @NL80211_CMD_GET_SCAN: get scan results
  * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
@@ -150,6 +160,116 @@
  * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
  *	partial scan results may be available
  *
+ * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
+ *      or noise level
+ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
+ *	NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
+ *
+ * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
+ * 	has been changed and provides details of the request information
+ * 	that caused the change such as who initiated the regulatory request
+ * 	(%NL80211_ATTR_REG_INITIATOR), the wiphy_idx
+ * 	(%NL80211_ATTR_REG_ALPHA2) on which the request was made from if
+ * 	the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or
+ * 	%NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain
+ * 	set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
+ * 	%NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
+ * 	to (%NL80211_ATTR_REG_ALPHA2).
+ * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
+ * 	has been found while world roaming thus enabling active scan or
+ * 	any mode of operation that initiates TX (beacons) on a channel
+ * 	where we would not have been able to do either before. As an example
+ * 	if you are world roaming (regulatory domain set to world or if your
+ * 	driver is using a custom world roaming regulatory domain) and while
+ * 	doing a passive scan on the 5 GHz band you find an AP there (if not
+ * 	on a DFS channel) you will now be able to actively scan for that AP
+ * 	or use AP mode on your card on that same channel. Note that this will
+ * 	never be used for channels 1-11 on the 2 GHz band as they are always
+ * 	enabled world wide. This beacon hint is only sent if your device had
+ * 	either disabled active scanning or beaconing on a channel. We send to
+ * 	userspace the wiphy on which we removed a restriction from
+ * 	(%NL80211_ATTR_WIPHY) and the channel on which this occurred
+ * 	before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
+ * 	the beacon hint was processed.
+ *
+ * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
+ *	This command is used both as a command (request to authenticate) and
+ *	as an event on the "mlme" multicast group indicating completion of the
+ *	authentication process.
+ *	When used as a command, %NL80211_ATTR_IFINDEX is used to identify the
+ *	interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and
+ *	BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
+ *	the SSID (mainly for association, but is included in authentication
+ *	request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used
+ *	to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE
+ *	is used to specify the authentication type. %NL80211_ATTR_IE is used to
+ *	define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs)
+ *	to be added to the frame.
+ *	When used as an event, this reports reception of an Authentication
+ *	frame in station and IBSS modes when the local MLME processed the
+ *	frame, i.e., it was for the local STA and was received in correct
+ *	state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
+ *	MLME SAP interface (kernel providing MLME, userspace SME). The
+ *	included %NL80211_ATTR_FRAME attribute contains the management frame
+ *	(including both the header and frame body, but not FCS). This event is
+ *	also used to indicate if the authentication attempt timed out. In that
+ *	case the %NL80211_ATTR_FRAME attribute is replaced with a
+ *	%NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ *	pending authentication timed out).
+ * @NL80211_CMD_ASSOCIATE: association request and notification; like
+ *	NL80211_CMD_AUTHENTICATE but for Association and Reassociation
+ *	(similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
+ *	MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives).
+ * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like
+ *	NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to
+ *	MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication
+ *	primitives).
+ * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like
+ *	NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
+ *	MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives).
+ *
+ * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael
+ *	MIC (part of TKIP) failure; sent on the "mlme" multicast group; the
+ *	event includes %NL80211_ATTR_MAC to describe the source MAC address of
+ *	the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key
+ *	type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and
+ *	%NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
+ *	event matches with MLME-MICHAELMICFAILURE.indication() primitive
+ *
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a
+ *	FREQ attribute (for the initial frequency if no peer can be found)
+ *	and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those
+ *	should be fixed rather than automatically determined. Can only be
+ *	executed on a network interface that is UP, and fixed BSSID/FREQ
+ *	may be rejected. Another optional parameter is the beacon interval,
+ *	given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not
+ *	given defaults to 100 TU (102.4ms).
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ *	determined by the network interface.
+ *
+ * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute
+ *	to identify the device, and the TESTDATA blob attribute to pass through
+ *	to the driver.
+ *
+ * @NL80211_CMD_CONNECT: connection request and notification; this command
+ *	requests to connect to a specified network but without separating
+ *	auth and assoc steps. For this, you need to specify the SSID in a
+ *	%NL80211_ATTR_SSID attribute, and can optionally specify the association
+ *	IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
+ *	%NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_CONTROL_PORT.
+ *	It is also sent as an event, with the BSSID and response IEs when the
+ *	connection is established or failed to be established. This can be
+ *	determined by the STATUS_CODE attribute.
+ * @NL80211_CMD_ROAM: request that the card roam (currently not implemented),
+ *	sent as an event when the card/driver roamed by itself.
+ * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
+ *	userspace that a connection was dropped by the AP or due to other
+ *	reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
+ *	%NL80211_ATTR_REASON_CODE attributes are used.
+ *
+ * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices
+ *	associated with this wiphy must be down and will follow.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -195,7 +315,7 @@
 	NL80211_CMD_GET_MESH_PARAMS,
 	NL80211_CMD_SET_MESH_PARAMS,
 
-	NL80211_CMD_SET_MGMT_EXTRA_IE,
+	NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */,
 
 	NL80211_CMD_GET_REG,
 
@@ -204,6 +324,31 @@
 	NL80211_CMD_NEW_SCAN_RESULTS,
 	NL80211_CMD_SCAN_ABORTED,
 
+	NL80211_CMD_REG_CHANGE,
+
+	NL80211_CMD_AUTHENTICATE,
+	NL80211_CMD_ASSOCIATE,
+	NL80211_CMD_DEAUTHENTICATE,
+	NL80211_CMD_DISASSOCIATE,
+
+	NL80211_CMD_MICHAEL_MIC_FAILURE,
+
+	NL80211_CMD_REG_BEACON_HINT,
+
+	NL80211_CMD_JOIN_IBSS,
+	NL80211_CMD_LEAVE_IBSS,
+
+	NL80211_CMD_TESTMODE,
+
+	NL80211_CMD_CONNECT,
+	NL80211_CMD_ROAM,
+	NL80211_CMD_DISCONNECT,
+
+	NL80211_CMD_SET_WIPHY_NETNS,
+
+	NL80211_CMD_GET_SURVEY,
+	NL80211_CMD_NEW_SURVEY_RESULTS,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -217,6 +362,12 @@
  */
 #define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
 #define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
+#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
+#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
+#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
+#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
+#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
+#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
 
 /**
  * enum nl80211_attrs - nl80211 netlink attributes
@@ -235,6 +386,18 @@
  *	NL80211_CHAN_HT20 = HT20 only
  *	NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
  *	NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
+ * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
+ *	less than or equal to the RTS threshold; allowed range: 1..255;
+ *	dot11ShortRetryLimit; u8
+ * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is
+ *	greater than the RTS threshold; allowed range: 1..255;
+ *	dot11ShortLongLimit; u8
+ * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum
+ *	length in octets for frames; allowed range: 256..8000, disable
+ *	fragmentation with (u32)-1; dot11FragmentationThreshold; u32
+ * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
+ *	larger than or equal to this use RTS/CTS handshake); allowed range:
+ *	0..65536, disable with (u32)-1; dot11RTSThreshold; u32
  *
  * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
  * @NL80211_ATTR_IFNAME: network interface name
@@ -258,7 +421,7 @@
  *
  * @NL80211_ATTR_STA_AID: Association ID for the station (u16)
  * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
- *	&enum nl80211_sta_flags.
+ *	&enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
  * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
  *	IEEE 802.11 7.3.1.6 (u16).
  * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
@@ -319,15 +482,121 @@
  *
  * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with
  *	a single scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements
+ *	that can be added to a scan request
  *
  * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
  * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
  *	scanning and include a zero-length SSID (wildcard) for wildcard scan
- * @NL80211_ATTR_SCAN_GENERATION: the scan generation increases whenever the
- *	scan result list changes (BSS expired or added) so that applications
- *	can verify that they got a single, consistent snapshot (when all dump
- *	messages carried the same generation number)
  * @NL80211_ATTR_BSS: scan result BSS
+ *
+ * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
+ * 	currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_*
+ * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently
+ * 	set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*)
+ *
+ * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies
+ *	an array of command numbers (i.e. a mapping index to command number)
+ *	that the driver for the given wiphy supports.
+ *
+ * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header
+ *	and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and
+ *	NL80211_CMD_ASSOCIATE events
+ * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets)
+ * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type,
+ *	represented as a u32
+ * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and
+ *	%NL80211_CMD_DISASSOCIATE, u16
+ *
+ * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as
+ *	a u32
+ *
+ * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
+ * 	due to considerations from a beacon hint. This attribute reflects
+ * 	the state of the channel _before_ the beacon hint processing. This
+ * 	attributes consists of a nested attribute containing
+ * 	NL80211_FREQUENCY_ATTR_*
+ * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
+ * 	due to considerations from a beacon hint. This attribute reflects
+ * 	the state of the channel _after_ the beacon hint processing. This
+ * 	attributes consists of a nested attribute containing
+ * 	NL80211_FREQUENCY_ATTR_*
+ *
+ * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
+ *	cipher suites
+ *
+ * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
+ *	for other networks on different channels
+ *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ *	is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
+ *	used for the association (&enum nl80211_mfp, represented as a u32);
+ *	this attribute can be used
+ *	with %NL80211_CMD_ASSOCIATE request
+ *
+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
+ *	&struct nl80211_sta_flag_update.
+ *
+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
+ *	IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
+ *	station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
+ *	request, the driver will assume that the port is unauthorized until
+ *	authorized by user space. Otherwise, port is marked authorized by
+ *	default in station mode.
+ *
+ * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
+ *	We recommend using nested, driver-specific attributes within this.
+ *
+ * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT
+ *	event was due to the AP disconnecting the station, and not due to
+ *	a local disconnect request.
+ * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT
+ *	event (u16)
+ * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating
+ *	that protected APs should be used.
+ *
+ * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to
+ *	indicate which unicast key ciphers will be used with the connection
+ *	(an array of u32).
+ * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate
+ *	which group key cipher will be used with the connection (a u32).
+ * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE to indicate
+ *	which WPA version(s) the AP we want to associate with is using
+ *	(a u32 with flags from &enum nl80211_wpa_versions).
+ * @NL80211_ATTR_AKM_SUITES: Used with CONNECT and ASSOCIATE to indicate
+ *	which key management algorithm(s) to use (an array of u32).
+ *
+ * @NL80211_ATTR_REQ_IE: (Re)association request information elements as
+ *	sent out by the card, for ROAM and successful CONNECT events.
+ * @NL80211_ATTR_RESP_IE: (Re)association response information elements as
+ *	sent by peer, for ROAM and successful CONNECT events.
+ *
+ * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE
+ *	commands to specify using a reassociate frame
+ *
+ * @NL80211_ATTR_KEY: key information in a nested attribute with
+ *	%NL80211_KEY_* sub-attributes
+ * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect()
+ *	and join_ibss(), key information is in a nested attribute each
+ *	with %NL80211_KEY_* sub-attributes
+ *
+ * @NL80211_ATTR_PID: Process ID of a network namespace.
+ *
+ * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
+ *	dumps. This number increases whenever the object list being
+ *	dumped changes, and as such userspace can verify that it has
+ *	obtained a complete and consistent snapshot by verifying that
+ *	all dump messages contain the same generation number. If it
+ *	changed then the list changed and the dump should be repeated
+ *	completely from scratch.
+ *
+ * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface
+ *
+ * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of
+ *      the survey response for %NL80211_CMD_GET_SURVEY, nested attribute
+ *      containing info as possible, see &enum survey_info.
  *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -400,19 +669,83 @@
 
 	NL80211_ATTR_SCAN_FREQUENCIES,
 	NL80211_ATTR_SCAN_SSIDS,
-	NL80211_ATTR_SCAN_GENERATION,
+	NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */
 	NL80211_ATTR_BSS,
+
+	NL80211_ATTR_REG_INITIATOR,
+	NL80211_ATTR_REG_TYPE,
+
+	NL80211_ATTR_SUPPORTED_COMMANDS,
+
+	NL80211_ATTR_FRAME,
+	NL80211_ATTR_SSID,
+	NL80211_ATTR_AUTH_TYPE,
+	NL80211_ATTR_REASON_CODE,
+
+	NL80211_ATTR_KEY_TYPE,
+
+	NL80211_ATTR_MAX_SCAN_IE_LEN,
+	NL80211_ATTR_CIPHER_SUITES,
+
+	NL80211_ATTR_FREQ_BEFORE,
+	NL80211_ATTR_FREQ_AFTER,
+
+	NL80211_ATTR_FREQ_FIXED,
+
+
+	NL80211_ATTR_WIPHY_RETRY_SHORT,
+	NL80211_ATTR_WIPHY_RETRY_LONG,
+	NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+	NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+
+	NL80211_ATTR_TIMED_OUT,
+
+	NL80211_ATTR_USE_MFP,
+
+	NL80211_ATTR_STA_FLAGS2,
+
+	NL80211_ATTR_CONTROL_PORT,
+
+	NL80211_ATTR_TESTDATA,
+
+	NL80211_ATTR_PRIVACY,
+
+	NL80211_ATTR_DISCONNECTED_BY_AP,
+	NL80211_ATTR_STATUS_CODE,
+
+	NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+	NL80211_ATTR_CIPHER_SUITE_GROUP,
+	NL80211_ATTR_WPA_VERSIONS,
+	NL80211_ATTR_AKM_SUITES,
+
+	NL80211_ATTR_REQ_IE,
+	NL80211_ATTR_RESP_IE,
+
+	NL80211_ATTR_PREV_BSSID,
+
+	NL80211_ATTR_KEY,
+	NL80211_ATTR_KEYS,
+
+	NL80211_ATTR_PID,
+
+	NL80211_ATTR_4ADDR,
+
+	NL80211_ATTR_SURVEY_INFO,
 
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
 	NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
 };
+
+/* source-level API compatibility */
+#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
 
 /*
  * Allow user space programs to use #ifdef on new attributes by defining them
  * here
  */
+#define NL80211_CMD_CONNECT NL80211_CMD_CONNECT
 #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
 #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
 #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
@@ -420,6 +753,18 @@
 #define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE
 #define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE
 #define NL80211_ATTR_IE NL80211_ATTR_IE
+#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
+#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
+#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME
+#define NL80211_ATTR_SSID NL80211_ATTR_SSID
+#define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE
+#define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE
+#define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE
+#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP
+#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS
+#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES
+#define NL80211_ATTR_KEY NL80211_ATTR_KEY
+#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
 
 #define NL80211_MAX_SUPP_RATES			32
 #define NL80211_MAX_SUPP_REG_RULES		32
@@ -427,6 +772,9 @@
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY	16
 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY	24
 #define NL80211_HT_CAPABILITY_LEN		26
+
+#define NL80211_MAX_NR_CIPHER_SUITES		5
+#define NL80211_MAX_NR_AKM_SUITES		2
 
 /**
  * enum nl80211_iftype - (virtual) interface types
@@ -484,6 +832,18 @@
 	__NL80211_STA_FLAG_AFTER_LAST,
 	NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
 };
+
+/**
+ * struct nl80211_sta_flag_update - station flags mask/set
+ * @mask: mask of station flags to set
+ * @set: which values to set them to
+ *
+ * Both mask and set contain bits as per &enum nl80211_sta_flags.
+ */
+struct nl80211_sta_flag_update {
+	__u32 mask;
+	__u32 set;
+} __attribute__((packed));
 
 /**
  * enum nl80211_rate_info - bitrate information
@@ -553,14 +913,14 @@
  *
  * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active
  * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running
- * @NL80211_MPATH_FLAG_DSN_VALID: the mesh path contains a valid DSN
+ * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN
  * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set
  * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded
  */
 enum nl80211_mpath_flags {
 	NL80211_MPATH_FLAG_ACTIVE =	1<<0,
 	NL80211_MPATH_FLAG_RESOLVING =	1<<1,
-	NL80211_MPATH_FLAG_DSN_VALID =	1<<2,
+	NL80211_MPATH_FLAG_SN_VALID =	1<<2,
 	NL80211_MPATH_FLAG_FIXED =	1<<3,
 	NL80211_MPATH_FLAG_RESOLVED =	1<<4,
 };
@@ -573,7 +933,7 @@
  *
  * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved
  * @NL80211_ATTR_MPATH_FRAME_QLEN: number of queued frames for this destination
- * @NL80211_ATTR_MPATH_DSN: destination sequence number
+ * @NL80211_ATTR_MPATH_SN: destination sequence number
  * @NL80211_ATTR_MPATH_METRIC: metric (cost) of this mesh path
  * @NL80211_ATTR_MPATH_EXPTIME: expiration time for the path, in msec from now
  * @NL80211_ATTR_MPATH_FLAGS: mesh path flags, enumerated in
@@ -584,7 +944,7 @@
 enum nl80211_mpath_info {
 	__NL80211_MPATH_INFO_INVALID,
 	NL80211_MPATH_INFO_FRAME_QLEN,
-	NL80211_MPATH_INFO_DSN,
+	NL80211_MPATH_INFO_SN,
 	NL80211_MPATH_INFO_METRIC,
 	NL80211_MPATH_INFO_EXPTIME,
 	NL80211_MPATH_INFO_FLAGS,
@@ -670,6 +1030,48 @@
 	/* keep last */
 	__NL80211_BITRATE_ATTR_AFTER_LAST,
 	NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_initiator - Indicates the initiator of a reg domain request
+ * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world
+ * 	regulatory domain.
+ * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the
+ * 	regulatory domain.
+ * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the
+ * 	wireless core it thinks its knows the regulatory domain we should be in.
+ * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an
+ * 	802.11 country information element with regulatory information it
+ * 	thinks we should consider.
+ */
+enum nl80211_reg_initiator {
+	NL80211_REGDOM_SET_BY_CORE,
+	NL80211_REGDOM_SET_BY_USER,
+	NL80211_REGDOM_SET_BY_DRIVER,
+	NL80211_REGDOM_SET_BY_COUNTRY_IE,
+};
+
+/**
+ * enum nl80211_reg_type - specifies the type of regulatory domain
+ * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains
+ *	to a specific country. When this is set you can count on the
+ *	ISO / IEC 3166 alpha2 country code being valid.
+ * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory
+ * 	domain.
+ * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom
+ * 	driver specific world regulatory domain. These do not apply system-wide
+ * 	and are only applicable to the individual devices which have requested
+ * 	them to be applied.
+ * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product
+ *	of an intersection between two regulatory domains -- the previously
+ *	set regulatory domain on the system and the last accepted regulatory
+ *	domain request to be processed.
+ */
+enum nl80211_reg_type {
+	NL80211_REGDOM_TYPE_COUNTRY,
+	NL80211_REGDOM_TYPE_WORLD,
+	NL80211_REGDOM_TYPE_CUSTOM_WORLD,
+	NL80211_REGDOM_TYPE_INTERSECTION,
 };
 
 /**
@@ -733,6 +1135,26 @@
 };
 
 /**
+ * enum nl80211_survey_info - survey information
+ *
+ * These attribute types are used with %NL80211_ATTR_SURVEY_INFO
+ * when getting information about a survey.
+ *
+ * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved
+ * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel
+ * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm)
+ */
+enum nl80211_survey_info {
+	__NL80211_SURVEY_INFO_INVALID,
+	NL80211_SURVEY_INFO_FREQUENCY,
+	NL80211_SURVEY_INFO_NOISE,
+
+	/* keep last */
+	__NL80211_SURVEY_INFO_AFTER_LAST,
+	NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1
+};
+
+/**
  * enum nl80211_mntr_flags - monitor configuration flags
  *
  * Monitor configuration flags.
@@ -811,6 +1233,8 @@
  *
  * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
  * that it takes for an HWMP information element to propagate across the mesh
+ *
+ * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
  *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
@@ -831,6 +1255,7 @@
 	NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
 	NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
 	NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+	NL80211_MESHCONF_HWMP_ROOTMODE,
 
 	/* keep last */
 	__NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -892,6 +1317,8 @@
  *	in mBm (100 * dBm) (s32)
  * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
  *	in unspecified units, scaled to 0..100 (u8)
+ * @NL80211_BSS_STATUS: status, if this BSS is "used"
+ * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -905,10 +1332,103 @@
 	NL80211_BSS_INFORMATION_ELEMENTS,
 	NL80211_BSS_SIGNAL_MBM,
 	NL80211_BSS_SIGNAL_UNSPEC,
+	NL80211_BSS_STATUS,
+	NL80211_BSS_SEEN_MS_AGO,
 
 	/* keep last */
 	__NL80211_BSS_AFTER_LAST,
 	NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_bss_status - BSS "status"
+ */
+enum nl80211_bss_status {
+	NL80211_BSS_STATUS_AUTHENTICATED,
+	NL80211_BSS_STATUS_ASSOCIATED,
+	NL80211_BSS_STATUS_IBSS_JOINED,
+};
+
+/**
+ * enum nl80211_auth_type - AuthenticationType
+ *
+ * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication
+ * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only)
+ * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
+ * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
+ * @__NL80211_AUTHTYPE_NUM: internal
+ * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
+ * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
+ *	trying multiple times); this is invalid in netlink -- leave out
+ *	the attribute for this on CONNECT commands.
+ */
+enum nl80211_auth_type {
+	NL80211_AUTHTYPE_OPEN_SYSTEM,
+	NL80211_AUTHTYPE_SHARED_KEY,
+	NL80211_AUTHTYPE_FT,
+	NL80211_AUTHTYPE_NETWORK_EAP,
+
+	/* keep last */
+	__NL80211_AUTHTYPE_NUM,
+	NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1,
+	NL80211_AUTHTYPE_AUTOMATIC
+};
+
+/**
+ * enum nl80211_key_type - Key Type
+ * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
+ * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
+ * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ */
+enum nl80211_key_type {
+	NL80211_KEYTYPE_GROUP,
+	NL80211_KEYTYPE_PAIRWISE,
+	NL80211_KEYTYPE_PEERKEY,
+};
+
+/**
+ * enum nl80211_mfp - Management frame protection state
+ * @NL80211_MFP_NO: Management frame protection not used
+ * @NL80211_MFP_REQUIRED: Management frame protection required
+ */
+enum nl80211_mfp {
+	NL80211_MFP_NO,
+	NL80211_MFP_REQUIRED,
+};
+
+enum nl80211_wpa_versions {
+	NL80211_WPA_VERSION_1 = 1 << 0,
+	NL80211_WPA_VERSION_2 = 1 << 1,
+};
+
+/**
+ * enum nl80211_key_attributes - key attributes
+ * @__NL80211_KEY_INVALID: invalid
+ * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *	16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *	keys
+ * @NL80211_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *	section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *	CCMP keys, each six bytes in little endian
+ * @NL80211_KEY_DEFAULT: flag indicating default key
+ * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
+ * @__NL80211_KEY_AFTER_LAST: internal
+ * @NL80211_KEY_MAX: highest key attribute
+ */
+enum nl80211_key_attributes {
+	__NL80211_KEY_INVALID,
+	NL80211_KEY_DATA,
+	NL80211_KEY_IDX,
+	NL80211_KEY_CIPHER,
+	NL80211_KEY_SEQ,
+	NL80211_KEY_DEFAULT,
+	NL80211_KEY_DEFAULT_MGMT,
+
+	/* keep last */
+	__NL80211_KEY_AFTER_LAST,
+	NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
+};
+
 #endif /* __LINUX_NL80211_H */

Modified: hostapd/trunk/src/common/version.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/common/version.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/common/version.h (original)
+++ hostapd/trunk/src/common/version.h Thu Feb 11 04:49:20 2010
@@ -1,6 +1,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define VERSION_STR "0.6.9"
+#define VERSION_STR "0.6.10"
 
 #endif /* VERSION_H */

Modified: hostapd/trunk/src/crypto/crypto_cryptoapi.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/crypto_cryptoapi.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/crypto_cryptoapi.c (original)
+++ hostapd/trunk/src/crypto/crypto_cryptoapi.c Thu Feb 11 04:49:20 2010
@@ -1,6 +1,6 @@
 /*
- * WPA Supplicant / Crypto wrapper for Microsoft CryptoAPI
- * Copyright (c) 2005-2006, Jouni Malinen <j at w1.fi>
+ * Crypto wrapper for Microsoft CryptoAPI
+ * Copyright (c) 2005-2009, Jouni Malinen <j at w1.fi>
  *
  * 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
@@ -40,12 +40,6 @@
  * define here whatever extra is needed.
  */
 
-static PCCERT_CONTEXT WINAPI
-(*CertCreateCertificateContext)(DWORD dwCertEncodingType,
-				const BYTE *pbCertEncoded,
-				DWORD cbCertEncoded)
-= NULL; /* to be loaded from crypt32.dll */
-
 static BOOL WINAPI
 (*CryptImportPublicKeyInfo)(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType,
 			    PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey)
@@ -59,22 +53,13 @@
 	/* MinGW does not yet have full CryptoAPI support, so load the needed
 	 * function here. */
 
-	if (CertCreateCertificateContext)
+	if (CryptImportPublicKeyInfo)
 		return 0;
 
 	dll = LoadLibrary("crypt32");
 	if (dll == NULL) {
 		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not load crypt32 "
 			   "library");
-		return -1;
-	}
-
-	CertCreateCertificateContext = (void *) GetProcAddress(
-		dll, "CertCreateCertificateContext");
-	if (CertCreateCertificateContext == NULL) {
-		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
-			   "CertCreateCertificateContext() address from "
-			   "crypt32 library");
 		return -1;
 	}
 

Modified: hostapd/trunk/src/crypto/crypto_internal.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/crypto_internal.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/crypto_internal.c (original)
+++ hostapd/trunk/src/crypto/crypto_internal.c Thu Feb 11 04:49:20 2010
@@ -435,6 +435,7 @@
 }
 
 
+#ifdef EAP_TLS_FUNCS
 static struct crypto_private_key *
 crypto_pkcs8_key_import(const u8 *buf, size_t len)
 {
@@ -536,6 +537,7 @@
 	return (struct crypto_private_key *)
 		crypto_rsa_import_private_key(hdr.payload, hdr.length);
 }
+#endif /* EAP_TLS_FUNCS */
 
 
 struct crypto_private_key * crypto_private_key_import(const u8 *key,

Modified: hostapd/trunk/src/crypto/dh_groups.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/dh_groups.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/dh_groups.c (original)
+++ hostapd/trunk/src/crypto/dh_groups.c Thu Feb 11 04:49:20 2010
@@ -19,6 +19,8 @@
 #include "dh_groups.h"
 
 
+#ifdef ALL_DH_GROUPS
+
 /* RFC 4306, B.1. Group 1 - 768 Bit MODP
  * Generator: 2
  * Prime: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
@@ -62,6 +64,8 @@
 	0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
+
+#endif /* ALL_DH_GROUPS */
 
 /* RFC 3526, 2. Group 5 - 1536 Bit MODP
  * Generator: 2
@@ -94,6 +98,8 @@
 	0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
+
+#ifdef ALL_DH_GROUPS
 
 /* RFC 3526, 3. Group 14 - 2048 Bit MODP
  * Generator: 2
@@ -503,6 +509,8 @@
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
 
+#endif /* ALL_DH_GROUPS */
+
 
 #define DH_GROUP(id) \
 { id, dh_group ## id ## _generator, sizeof(dh_group ## id ## _generator), \
@@ -510,14 +518,16 @@
 		
 
 static struct dh_group dh_groups[] = {
+	DH_GROUP(5),
+#ifdef ALL_DH_GROUPS
 	DH_GROUP(1),
 	DH_GROUP(2),
-	DH_GROUP(5),
 	DH_GROUP(14),
 	DH_GROUP(15),
 	DH_GROUP(16),
 	DH_GROUP(17),
 	DH_GROUP(18)
+#endif /* ALL_DH_GROUPS */
 };
 
 #define NUM_DH_GROUPS (sizeof(dh_groups) / sizeof(dh_groups[0]))

Modified: hostapd/trunk/src/crypto/ms_funcs.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/ms_funcs.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/ms_funcs.c (original)
+++ hostapd/trunk/src/crypto/ms_funcs.c Thu Feb 11 04:49:20 2010
@@ -379,7 +379,7 @@
 	 */
 	pos = &pw_block[2 * 256];
 	WPA_PUT_LE16(pos, password_len * 2);
-	rc4(pw_block, PWBLOCK_LEN, password_hash, 16);
+	rc4_skip(password_hash, 16, 0, pw_block, PWBLOCK_LEN);
 	return 0;
 }
 

Modified: hostapd/trunk/src/crypto/rc4.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/rc4.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/rc4.c (original)
+++ hostapd/trunk/src/crypto/rc4.c Thu Feb 11 04:49:20 2010
@@ -68,19 +68,3 @@
 		*pos++ ^= S[(S[i] + S[j]) & 0xff];
 	}
 }
-
-
-/**
- * rc4 - XOR RC4 stream to given data
- * @buf: data to be XOR'ed with RC4 stream
- * @len: buf length
- * @key: RC4 key
- * @key_len: RC4 key length
- *
- * Generate RC4 pseudo random stream for the given key and XOR this with the
- * data buffer to perform RC4 encryption/decryption.
- */
-void rc4(u8 *buf, size_t len, const u8 *key, size_t key_len)
-{
-	rc4_skip(key, key_len, 0, buf, len);
-}

Modified: hostapd/trunk/src/crypto/rc4.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/rc4.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/rc4.h (original)
+++ hostapd/trunk/src/crypto/rc4.h Thu Feb 11 04:49:20 2010
@@ -17,6 +17,5 @@
 
 void rc4_skip(const u8 *key, size_t keylen, size_t skip,
 	      u8 *data, size_t data_len);
-void rc4(u8 *buf, size_t len, const u8 *key, size_t key_len);
 
 #endif /* RC4_H */

Modified: hostapd/trunk/src/crypto/sha1.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/sha1.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/sha1.c (original)
+++ hostapd/trunk/src/crypto/sha1.c Thu Feb 11 04:49:20 2010
@@ -606,8 +606,8 @@
 	} CHAR64LONG16;
 	CHAR64LONG16* block;
 #ifdef SHA1HANDSOFF
-	u32 workspace[16];
-	block = (CHAR64LONG16 *) workspace;
+	CHAR64LONG16 workspace;
+	block = &workspace;
 	os_memcpy(block, buffer, 64);
 #else
 	block = (CHAR64LONG16 *) buffer;

Modified: hostapd/trunk/src/crypto/tls.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/tls.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/tls.h (original)
+++ hostapd/trunk/src/crypto/tls.h Thu Feb 11 04:49:20 2010
@@ -33,6 +33,9 @@
 	const char *pkcs11_engine_path;
 	const char *pkcs11_module_path;
 };
+
+#define TLS_CONN_ALLOW_SIGN_RSA_MD5 BIT(0)
+#define TLS_CONN_DISABLE_TIME_CHECKS BIT(1)
 
 /**
  * struct tls_connection_params - Parameters for TLS connection
@@ -68,6 +71,7 @@
  * @cert_id: the certificate's id when using engine
  * @ca_cert_id: the CA certificate's id when using engine
  * @tls_ia: Whether to enable TLS/IA (for EAP-TTLSv1)
+ * @flags: Parameter options (TLS_CONN_*)
  *
  * TLS connection parameters to be configured with tls_connection_set_params()
  * and tls_global_set_params().
@@ -103,6 +107,8 @@
 	const char *key_id;
 	const char *cert_id;
 	const char *ca_cert_id;
+
+	unsigned int flags;
 };
 
 

Modified: hostapd/trunk/src/crypto/tls_gnutls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/tls_gnutls.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/tls_gnutls.c (original)
+++ hostapd/trunk/src/crypto/tls_gnutls.c Thu Feb 11 04:49:20 2010
@@ -35,8 +35,12 @@
 #include "tls.h"
 
 
+#ifndef TLS_RANDOM_SIZE
 #define TLS_RANDOM_SIZE 32
+#endif
+#ifndef TLS_MASTER_SIZE
 #define TLS_MASTER_SIZE 48
+#endif
 
 
 #if LIBGNUTLS_VERSION_NUMBER < 0x010302
@@ -591,6 +595,17 @@
 				return -1;
 			}
 		}
+
+		if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
+			gnutls_certificate_set_verify_flags(
+				conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
+		}
+
+		if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
+			gnutls_certificate_set_verify_flags(
+				conn->xcred,
+				GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
+		}
 	}
 
 	if (params->client_cert && params->private_key) {
@@ -711,6 +726,18 @@
 				goto fail;
 			}
 		}
+
+		if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
+			gnutls_certificate_set_verify_flags(
+				global->xcred,
+				GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
+		}
+
+		if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
+			gnutls_certificate_set_verify_flags(
+				global->xcred,
+				GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
+		}
 	}
 
 	if (params->client_cert && params->private_key) {
@@ -843,7 +870,8 @@
 }
 
 
-static int tls_connection_verify_peer(struct tls_connection *conn)
+static int tls_connection_verify_peer(struct tls_connection *conn,
+				      gnutls_alert_description_t *err)
 {
 	unsigned int status, num_certs, i;
 	struct os_time now;
@@ -853,22 +881,39 @@
 	if (gnutls_certificate_verify_peers2(conn->session, &status) < 0) {
 		wpa_printf(MSG_INFO, "TLS: Failed to verify peer "
 			   "certificate chain");
+		*err = GNUTLS_A_INTERNAL_ERROR;
 		return -1;
 	}
 
 	if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) {
 		wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted");
+		if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
+			wpa_printf(MSG_INFO, "TLS: Certificate uses insecure "
+				   "algorithm");
+			*err = GNUTLS_A_INSUFFICIENT_SECURITY;
+		}
+		if (status & GNUTLS_CERT_NOT_ACTIVATED) {
+			wpa_printf(MSG_INFO, "TLS: Certificate not yet "
+				   "activated");
+			*err = GNUTLS_A_CERTIFICATE_EXPIRED;
+		}
+		if (status & GNUTLS_CERT_EXPIRED) {
+			wpa_printf(MSG_INFO, "TLS: Certificate expired");
+			*err = GNUTLS_A_CERTIFICATE_EXPIRED;
+		}
 		return -1;
 	}
 
 	if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
 		wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a "
 			   "known issuer");
+		*err = GNUTLS_A_UNKNOWN_CA;
 		return -1;
 	}
 
 	if (status & GNUTLS_CERT_REVOKED) {
 		wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked");
+		*err = GNUTLS_A_CERTIFICATE_REVOKED;
 		return -1;
 	}
 
@@ -878,6 +923,7 @@
 	if (certs == NULL) {
 		wpa_printf(MSG_INFO, "TLS: No peer certificate chain "
 			   "received");
+		*err = GNUTLS_A_UNKNOWN_CA;
 		return -1;
 	}
 
@@ -887,6 +933,7 @@
 		if (gnutls_x509_crt_init(&cert) < 0) {
 			wpa_printf(MSG_INFO, "TLS: Certificate initialization "
 				   "failed");
+			*err = GNUTLS_A_BAD_CERTIFICATE;
 			return -1;
 		}
 
@@ -895,6 +942,7 @@
 			wpa_printf(MSG_INFO, "TLS: Could not parse peer "
 				   "certificate %d/%d", i + 1, num_certs);
 			gnutls_x509_crt_deinit(cert);
+			*err = GNUTLS_A_BAD_CERTIFICATE;
 			return -1;
 		}
 
@@ -920,6 +968,7 @@
 				   "not valid at this time",
 				   i + 1, num_certs);
 			gnutls_x509_crt_deinit(cert);
+			*err = GNUTLS_A_CERTIFICATE_EXPIRED;
 			return -1;
 		}
 
@@ -981,12 +1030,15 @@
 		}
 	} else {
 		size_t size;
-
-		if (conn->verify_peer && tls_connection_verify_peer(conn)) {
+		gnutls_alert_description_t err;
+
+		if (conn->verify_peer &&
+		    tls_connection_verify_peer(conn, &err)) {
 			wpa_printf(MSG_INFO, "TLS: Peer certificate chain "
 				   "failed validation");
 			conn->failed++;
-			return NULL;
+			gnutls_alert_send(conn->session, GNUTLS_AL_FATAL, err);
+			goto out;
 		}
 
 #ifdef CONFIG_GNUTLS_EXTRA
@@ -1023,6 +1075,7 @@
 		}
 	}
 
+out:
 	out_data = conn->push_buf;
 	*out_len = conn->push_buf_len;
 	conn->push_buf = NULL;

Modified: hostapd/trunk/src/crypto/tls_openssl.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/tls_openssl.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/tls_openssl.c (original)
+++ hostapd/trunk/src/crypto/tls_openssl.c Thu Feb 11 04:49:20 2010
@@ -108,71 +108,9 @@
  * MinGW does not yet include all the needed definitions for CryptoAPI, so
  * define here whatever extra is needed.
  */
-#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
 #define CERT_SYSTEM_STORE_CURRENT_USER (1 << 16)
 #define CERT_STORE_READONLY_FLAG 0x00008000
 #define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
-#define CRYPT_ACQUIRE_COMPARE_KEY_FLAG 0x00000004
-
-static BOOL WINAPI
-(*CryptAcquireCertificatePrivateKey)(PCCERT_CONTEXT pCert, DWORD dwFlags,
-				     void *pvReserved, HCRYPTPROV *phCryptProv,
-				     DWORD *pdwKeySpec, BOOL *pfCallerFreeProv)
-= NULL; /* to be loaded from crypt32.dll */
-
-#ifdef CONFIG_MINGW32_LOAD_CERTENUM
-static PCCERT_CONTEXT WINAPI
-(*CertEnumCertificatesInStore)(HCERTSTORE hCertStore,
-			       PCCERT_CONTEXT pPrevCertContext)
-= NULL; /* to be loaded from crypt32.dll */
-#endif /* CONFIG_MINGW32_LOAD_CERTENUM */
-
-static int mingw_load_crypto_func(void)
-{
-	HINSTANCE dll;
-
-	/* MinGW does not yet have full CryptoAPI support, so load the needed
-	 * function here. */
-
-	if (CryptAcquireCertificatePrivateKey)
-		return 0;
-
-	dll = LoadLibrary("crypt32");
-	if (dll == NULL) {
-		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not load crypt32 "
-			   "library");
-		return -1;
-	}
-
-	CryptAcquireCertificatePrivateKey = GetProcAddress(
-		dll, "CryptAcquireCertificatePrivateKey");
-	if (CryptAcquireCertificatePrivateKey == NULL) {
-		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
-			   "CryptAcquireCertificatePrivateKey() address from "
-			   "crypt32 library");
-		return -1;
-	}
-
-#ifdef CONFIG_MINGW32_LOAD_CERTENUM
-	CertEnumCertificatesInStore = (void *) GetProcAddress(
-		dll, "CertEnumCertificatesInStore");
-	if (CertEnumCertificatesInStore == NULL) {
-		wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
-			   "CertEnumCertificatesInStore() address from "
-			   "crypt32 library");
-		return -1;
-	}
-#endif /* CONFIG_MINGW32_LOAD_CERTENUM */
-
-	return 0;
-}
-
-#else /* __MINGW32_VERSION */
-
-static int mingw_load_crypto_func(void)
-{
-	return 0;
-}
 
 #endif /* __MINGW32_VERSION */
 
@@ -403,9 +341,6 @@
 		goto err;
 	}
 
-	if (mingw_load_crypto_func())
-		goto err;
-
 	if (!CryptAcquireCertificatePrivateKey(priv->cert,
 					       CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
 					       NULL, &priv->crypt_prov,
@@ -475,9 +410,6 @@
 #ifdef UNICODE
 	WCHAR *wstore;
 #endif /* UNICODE */
-
-	if (mingw_load_crypto_func())
-		return -1;
 
 	if (name == NULL || strncmp(name, "cert_store://", 13) != 0)
 		return -1;
@@ -735,11 +667,23 @@
 	if (tls_openssl_ref_count == 0) {
 		SSL_load_error_strings();
 		SSL_library_init();
+#ifndef OPENSSL_NO_SHA256
+		EVP_add_digest(EVP_sha256());
+#endif /* OPENSSL_NO_SHA256 */
 		/* TODO: if /dev/urandom is available, PRNG is seeded
 		 * automatically. If this is not the case, random data should
 		 * be added here. */
 
 #ifdef PKCS12_FUNCS
+#ifndef OPENSSL_NO_RC2
+		/*
+		 * 40-bit RC2 is commonly used in PKCS#12 files, so enable it.
+		 * This is enabled by PKCS12_PBE_add() in OpenSSL 0.9.8
+		 * versions, but it looks like OpenSSL 1.0.0 does not do that
+		 * anymore.
+		 */
+		EVP_add_cipher(EVP_rc2_40_cbc());
+#endif /* OPENSSL_NO_RC2 */
 		PKCS12_PBE_add();
 #endif  /* PKCS12_FUNCS */
 	}
@@ -2105,9 +2049,18 @@
 		if (*appl_data) {
 			res = SSL_read(conn->ssl, *appl_data, in_len);
 			if (res < 0) {
-				tls_show_errors(MSG_INFO, __func__,
-						"Failed to read possible "
-						"Application Data");
+				int err = SSL_get_error(conn->ssl, res);
+				if (err == SSL_ERROR_WANT_READ ||
+				    err == SSL_ERROR_WANT_WRITE) {
+					wpa_printf(MSG_DEBUG,
+						   "SSL: No Application Data "
+						   "included");
+				} else {
+					tls_show_errors(MSG_INFO, __func__,
+							"Failed to read "
+							"possible "
+							"Application Data");
+				}
 				os_free(*appl_data);
 				*appl_data = NULL;
 			} else {

Modified: hostapd/trunk/src/drivers/driver.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver.h (original)
+++ hostapd/trunk/src/drivers/driver.h Thu Feb 11 04:49:20 2010
@@ -131,7 +131,7 @@
  * @ifname: Interface name that can be used with init() or init2()
  * @desc: Human readable adapter description (e.g., vendor/model) or NULL if
  *	not available
- * @drv_bame: struct wpa_driver_ops::name (note: unlike other strings, this one
+ * @drv_name: struct wpa_driver_ops::name (note: unlike other strings, this one
  *	is not an allocated copy, i.e., get_interfaces() caller will not free
  *	this)
  */
@@ -702,7 +702,7 @@
 	int (*flush_pmkid)(void *priv);
 
 	/**
-	 * flush_pmkid - Flush PMKSA cache
+	 * get_capa - Get driver capabilities
 	 * @priv: private driver interface data
 	 *
 	 * Returns: 0 on success, -1 on failure

Modified: hostapd/trunk/src/drivers/driver_bsd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_bsd.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_bsd.c (original)
+++ hostapd/trunk/src/drivers/driver_bsd.c Thu Feb 11 04:49:20 2010
@@ -386,10 +386,6 @@
 	/* XXX error handling is wrong but unclear what to do... */
 	if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
 		return -1;
-#ifndef NEW_FREEBSD_MLME_ASSOC
-	if (wpa_driver_bsd_set_ssid(drv, params->ssid, params->ssid_len) < 0)
-		return -1;
-#endif
 
 	privacy = !(params->pairwise_suite == CIPHER_NONE &&
 	    params->group_suite == CIPHER_NONE &&
@@ -407,11 +403,9 @@
 
 	os_memset(&mlme, 0, sizeof(mlme));
 	mlme.im_op = IEEE80211_MLME_ASSOC;
-#ifdef NEW_FREEBSD_MLME_ASSOC
 	if (params->ssid != NULL)
 		os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len);
 	mlme.im_ssid_len = params->ssid_len;
-#endif
 	if (params->bssid != NULL)
 		os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
 	if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)

Modified: hostapd/trunk/src/drivers/driver_madwifi.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_madwifi.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_madwifi.c (original)
+++ hostapd/trunk/src/drivers/driver_madwifi.c Thu Feb 11 04:49:20 2010
@@ -11,6 +11,10 @@
  * license.
  *
  * See README and COPYING for more details.
+ *
+ * Please note that madwifi supports WPA configuration via Linux wireless
+ * extensions and if the kernel includes support for this, driver_wext.c should
+ * be used instead of this driver wrapper.
  */
 
 #include "includes.h"

Modified: hostapd/trunk/src/drivers/driver_ndiswrapper.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_ndiswrapper.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_ndiswrapper.c (original)
+++ hostapd/trunk/src/drivers/driver_ndiswrapper.c Thu Feb 11 04:49:20 2010
@@ -11,6 +11,10 @@
  * license.
  *
  * See README and COPYING for more details.
+ *
+ * Please note that ndiswrapper supports WPA configuration via Linux wireless
+ * extensions and if the kernel includes support for this, driver_wext.c should
+ * be used instead of this driver wrapper.
  */
 
 #include "includes.h"
@@ -345,7 +349,7 @@
 
 const struct wpa_driver_ops wpa_driver_ndiswrapper_ops = {
 	.name = "ndiswrapper",
-	.desc = "Linux ndiswrapper",
+	.desc = "Linux ndiswrapper (deprecated; use wext)",
 	.set_wpa = wpa_ndiswrapper_set_wpa,
 	.set_key = wpa_ndiswrapper_set_key,
 	.set_countermeasures = wpa_ndiswrapper_set_countermeasures,

Modified: hostapd/trunk/src/drivers/driver_nl80211.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_nl80211.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_nl80211.c (original)
+++ hostapd/trunk/src/drivers/driver_nl80211.c Thu Feb 11 04:49:20 2010
@@ -241,8 +241,9 @@
 	req.ifinfo.ifi_change = 0;
 
 	if (linkmode != -1) {
-		rta = (struct rtattr *)
-			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+		rta = aliasing_hide_typecast(
+			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
+			struct rtattr);
 		rta->rta_type = IFLA_LINKMODE;
 		rta->rta_len = RTA_LENGTH(sizeof(char));
 		*((char *) RTA_DATA(rta)) = linkmode;
@@ -981,6 +982,9 @@
 	}
 
 	switch (gnlh->cmd) {
+	case NL80211_CMD_TRIGGER_SCAN:
+		wpa_printf(MSG_DEBUG, "nl80211: Scan trigger");
+		break;
 	case NL80211_CMD_NEW_SCAN_RESULTS:
 		wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
 		drv->scan_complete_events = 1;
@@ -1517,6 +1521,12 @@
 {
 	int flags;
 
+	drv->ifindex = if_nametoindex(drv->ifname);
+
+	if (wpa_driver_nl80211_set_mode(drv, 0) < 0) {
+		printf("Could not configure driver to use managed mode\n");
+	}
+
 	if (wpa_driver_nl80211_get_ifflags(drv, &flags) != 0)
 		printf("Could not get interface '%s' flags\n", drv->ifname);
 	else if (!(flags & IFF_UP)) {
@@ -1531,13 +1541,7 @@
 	 */
 	wpa_driver_nl80211_flush_pmkid(drv);
 
-	if (wpa_driver_nl80211_set_mode(drv, 0) < 0) {
-		printf("Could not configure driver to use managed mode\n");
-	}
-
 	wpa_driver_nl80211_get_range(drv);
-
-	drv->ifindex = if_nametoindex(drv->ifname);
 
 	wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
 }
@@ -1844,6 +1848,9 @@
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
 		if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
+		drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
+			WPA_DRIVER_AUTH_SHARED |
+			WPA_DRIVER_AUTH_LEAP;
 		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x",
 			   drv->capa.key_mgmt, drv->capa.enc);
 	} else {
@@ -1907,6 +1914,11 @@
 		case WPA_ALG_CCMP:
 			NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);
 			break;
+#ifdef CONFIG_IEEE80211W
+		case WPA_ALG_IGTK:
+			NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC06);
+			break;
+#endif /* CONFIG_IEEE80211W */
 		default:
 			nlmsg_free(msg);
 			return -1;
@@ -2252,7 +2264,8 @@
 		goto try_again;
 
 nla_put_failure:
-	wpa_printf(MSG_ERROR, "nl80211: Failed to set interface mode");
+	wpa_printf(MSG_ERROR, "nl80211: Failed to set interface mode: %d (%s)",
+		   ret, strerror(-ret));
 	return -1;
 
 try_again:
@@ -2277,7 +2290,8 @@
 		ret = send_and_recv_msgs(drv, msg, NULL, NULL);
 		if (ret) {
 			wpa_printf(MSG_ERROR, "Failed to set interface %s "
-				   "mode", drv->ifname);
+				   "mode(try_again): %d (%s)",
+				   drv->ifname, ret, strerror(-ret));
 		}
 
 		/* Ignore return value of get_ifflags to ensure that the device
@@ -2512,7 +2526,7 @@
 
 			/* crude heuristic */
 			if (mode->channels[idx].freq < 4000) {
-				if (mode->channels[idx].freq == 2848)
+				if (mode->channels[idx].freq == 2484)
 					mode->channels[idx].chan = 14;
 				else
 					mode->channels[idx].chan =

Modified: hostapd/trunk/src/drivers/driver_roboswitch.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_roboswitch.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_roboswitch.c (original)
+++ hostapd/trunk/src/drivers/driver_roboswitch.c Thu Feb 11 04:49:20 2010
@@ -16,12 +16,18 @@
 #include <sys/ioctl.h>
 #include <linux/if.h>
 #include <linux/sockios.h>
+#include <linux/if_ether.h>
 #include <linux/mii.h>
 
 #include "common.h"
 #include "driver.h"
-
-#define ROBO_PHY_ADDR		0x1E	/* RoboSwitch PHY address */
+#include "l2_packet/l2_packet.h"
+
+#ifndef ETH_P_EAPOL
+#define ETH_P_EAPOL		0x888e
+#endif
+
+#define ROBO_PHY_ADDR		0x1e	/* RoboSwitch PHY address */
 
 /* MII access registers */
 #define ROBO_MII_PAGE		0x10	/* MII page register */
@@ -46,10 +52,10 @@
 #define ROBO_ARLCTRL_VEC_2	0x26	/* Multiport vector 2 */
 
 /* VLAN page registers */
-#define ROBO_VLAN_ACCESS	0x06	/* VLAN table Access register */
-#define ROBO_VLAN_ACCESS_5365	0x08	/* VLAN table Access register (5365) */
-#define ROBO_VLAN_READ		0x0C	/* VLAN read register */
-#define ROBO_VLAN_MAX		0xFF	/* Maximum number of VLANs */
+#define ROBO_VLAN_ACCESS	0x08	/* VLAN table access register */
+#define ROBO_VLAN_ACCESS_5350	0x06	/* VLAN table access register (5350) */
+#define ROBO_VLAN_READ		0x0c	/* VLAN read register */
+#define ROBO_VLAN_MAX		0xff	/* Maximum number of VLANs */
 
 
 static const u8 pae_group_addr[ETH_ALEN] =
@@ -58,9 +64,11 @@
 
 struct wpa_driver_roboswitch_data {
 	void *ctx;
+	struct l2_packet_data *l2;
 	char ifname[IFNAMSIZ + 1];
+	u8 own_addr[ETH_ALEN];
 	struct ifreq ifr;
-	int fd;
+	int fd, is_5350;
 	u16 ports;
 };
 
@@ -69,6 +77,18 @@
 static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
 {
 	return (struct mii_ioctl_data *) &rq->ifr_ifru;
+}
+
+
+/*
+ * RoboSwitch uses 16-bit Big Endian addresses.
+ * The ordering of the words is reversed in the MII registers.
+ */
+static void wpa_driver_roboswitch_addr_be16(const u8 addr[ETH_ALEN], u16 *be)
+{
+	int i;
+	for (i = 0; i < ETH_ALEN; i += 2)
+		be[(ETH_ALEN - i) / 2 - 1] = WPA_GET_BE16(addr + i);
 }
 
 
@@ -157,6 +177,19 @@
 }
 
 
+static void wpa_driver_roboswitch_receive(void *priv, const u8 *src_addr,
+					  const u8 *buf, size_t len)
+{
+	struct wpa_driver_roboswitch_data *drv = priv;
+
+	if (len > 14 && WPA_GET_BE16(buf + 12) == ETH_P_EAPOL &&
+	    os_memcmp(buf, drv->own_addr, ETH_ALEN) == 0) {
+		wpa_supplicant_rx_eapol(drv->ctx, src_addr, buf + 14,
+					len - 14);
+	}
+}
+
+
 static int wpa_driver_roboswitch_get_ssid(void *priv, u8 *ssid)
 {
 	ssid[0] = 0;
@@ -172,6 +205,32 @@
 }
 
 
+static int wpa_driver_roboswitch_set_param(void *priv, const char *param)
+{
+	struct wpa_driver_roboswitch_data *drv = priv;
+	char *sep;
+
+	if (param == NULL || os_strstr(param, "multicast_only=1") == NULL) {
+		sep = drv->ifname + os_strlen(drv->ifname);
+		*sep = '.';
+		drv->l2 = l2_packet_init(drv->ifname, NULL, ETH_P_ALL,
+					 wpa_driver_roboswitch_receive, drv,
+					 1);
+		if (drv->l2 == NULL) {
+			wpa_printf(MSG_INFO, "%s: Unable to listen on %s",
+				   __func__, drv->ifname);
+			return -1;
+		}
+		*sep = '\0';
+		l2_packet_get_own_addr(drv->l2, drv->own_addr);
+	} else {
+		wpa_printf(MSG_DEBUG, "%s: Ignoring unicast frames", __func__);
+		drv->l2 = NULL;
+	}
+	return 0;
+}
+
+
 static const char * wpa_driver_roboswitch_get_ifname(void *priv)
 {
 	struct wpa_driver_roboswitch_data *drv = priv;
@@ -180,137 +239,109 @@
 
 
 static int wpa_driver_roboswitch_join(struct wpa_driver_roboswitch_data *drv,
-				      const u8 *addr)
-{
-	int i;
-	u16 _read, zero = 0;
-	/* For reasons of simplicity we assume ETH_ALEN is even. */
-	u16 addr_word[ETH_ALEN / 2];
-	/* RoboSwitch uses 16-bit Big Endian addresses.			*/
-	/* The ordering of the words is reversed in the MII registers.	*/
-	for (i = 0; i < ETH_ALEN; i += 2)
-		addr_word[(ETH_ALEN - i) / 2 - 1] = WPA_GET_BE16(addr + i);
-
-	/* check if multiport addresses are not yet enabled */
+				      u16 ports, const u8 *addr)
+{
+	u16 read1[3], read2[3], addr_be16[3];
+
+	wpa_driver_roboswitch_addr_be16(addr, addr_be16);
+
 	if (wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
-				       ROBO_ARLCTRL_CONF, &_read, 1) < 0)
+				       ROBO_ARLCTRL_CONF, read1, 1) < 0)
 		return -1;
-
-	if (!(_read & (1 << 4))) {
-		_read |= 1 << 4;
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_ADDR_1, addr_word, 3);
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_VEC_1, &drv->ports,
-					    1);
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_VEC_2, &zero, 1);
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_CONF, &_read, 1);
-		return 0;
-	}
-
-	/* check if multiport address 1 is free */
+	if (!(read1[0] & (1 << 4))) {
+		/* multiport addresses are not yet enabled */
+		read1[0] |= 1 << 4;
+		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+					    ROBO_ARLCTRL_ADDR_1, addr_be16, 3);
+		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+					    ROBO_ARLCTRL_VEC_1, &ports, 1);
+		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+					    ROBO_ARLCTRL_ADDR_2, addr_be16, 3);
+		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+					    ROBO_ARLCTRL_VEC_2, &ports, 1);
+		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+					    ROBO_ARLCTRL_CONF, read1, 1);
+	} else {
+		/* if both multiport addresses are the same we can add */
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_ADDR_1, read1, 3);
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_ADDR_2, read2, 3);
+		if (os_memcmp(read1, read2, 6) != 0)
+			return -1;
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_VEC_1, read1, 1);
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_VEC_2, read2, 1);
+		if (read1[0] != read2[0])
+			return -1;
+		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+					    ROBO_ARLCTRL_ADDR_1, addr_be16, 3);
+		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+					    ROBO_ARLCTRL_VEC_1, &ports, 1);
+	}
+	return 0;
+}
+
+
+static int wpa_driver_roboswitch_leave(struct wpa_driver_roboswitch_data *drv,
+				       u16 ports, const u8 *addr)
+{
+	u16 _read, addr_be16[3], addr_read[3], ports_read;
+
+	wpa_driver_roboswitch_addr_be16(addr, addr_be16);
+
+	wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_CONF,
+				   &_read, 1);
+	/* If ARL control is disabled, there is nothing to leave. */
+	if (!(_read & (1 << 4))) return -1;
+
+	wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+				   ROBO_ARLCTRL_ADDR_1, addr_read, 3);
 	wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_VEC_1,
-				   &_read, 1);
-	if (_read == 0) {
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_ADDR_1, addr_word, 3);
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_VEC_1, &drv->ports,
-					    1);
-		return 0;
-	}
-	/* check if multiport address 2 is free */
-	wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_VEC_2,
-				   &_read, 1);
-	if (_read == 0) {
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_ADDR_2, addr_word, 3);
-		wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-					    ROBO_ARLCTRL_VEC_2, &drv->ports,
-					    1);
-		return 0;
-	}
-
-	/* out of free multiport addresses */
-	return -1;
-}
-
-
-static int wpa_driver_roboswitch_leave(struct wpa_driver_roboswitch_data *drv,
-				       const u8 *addr)
-{
-	int i;
-	u16 _read[3], zero = 0;
-	u16 addr_word[ETH_ALEN / 2]; /* same as at join */
-
-	for (i = 0; i < ETH_ALEN; i += 2)
-		addr_word[(ETH_ALEN - i) / 2 - 1] = WPA_GET_BE16(addr + i);
-
-	/* check if multiport address 1 was used */
-	wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_VEC_1,
-				   _read, 1);
-	if (_read[0] == drv->ports) {
-		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
-					   ROBO_ARLCTRL_ADDR_1, _read, 3);
-		if (os_memcmp(_read, addr_word, 6) == 0) {
+				   &ports_read, 1);
+	/* check if we occupy multiport address 1 */
+	if (os_memcmp(addr_read, addr_be16, 6) == 0 && ports_read == ports) {
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_ADDR_2, addr_read, 3);
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_VEC_2, &ports_read, 1);
+		/* and multiport address 2 */
+		if (os_memcmp(addr_read, addr_be16, 6) == 0 &&
+		    ports_read == ports) {
+			_read &= ~(1 << 4);
 			wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-						    ROBO_ARLCTRL_VEC_1, &zero,
-						    1);
-			goto clean_up;
-		}
-	}
-
-	/* check if multiport address 2 was used */
-	wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_VEC_2,
-				   _read, 1);
-	if (_read[0] == drv->ports) {
-		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
-					   ROBO_ARLCTRL_ADDR_2, _read, 3);
-		if (os_memcmp(_read, addr_word, 6) == 0) {
-			wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-						    ROBO_ARLCTRL_VEC_2, &zero,
-						    1);
-			goto clean_up;
-		}
-	}
-
-	/* used multiport address not found */
-	return -1;
-
-clean_up:
-	/* leave the multiport registers in a sane state */
-	wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_VEC_1,
-				   _read, 1);
-	if (_read[0] == 0) {
-		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
-					   ROBO_ARLCTRL_VEC_2, _read, 1);
-		if (_read[0] == 0) {
-			wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
-						   ROBO_ARLCTRL_CONF, _read,
-						   1);
-			_read[0] &= ~(1 << 4);
-			wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-						    ROBO_ARLCTRL_CONF, _read,
+						    ROBO_ARLCTRL_CONF, &_read,
 						    1);
 		} else {
 			wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
-						   ROBO_ARLCTRL_ADDR_2, _read,
-						   3);
+						   ROBO_ARLCTRL_ADDR_1,
+						   addr_read, 3);
+			wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+						   ROBO_ARLCTRL_VEC_1,
+						   &ports_read, 1);
 			wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-						    ROBO_ARLCTRL_ADDR_1, _read,
-						    3);
-			wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
-						   ROBO_ARLCTRL_VEC_2, _read,
-						   1);
+						    ROBO_ARLCTRL_ADDR_2,
+						    addr_read, 3);
 			wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-						    ROBO_ARLCTRL_VEC_1, _read,
-						    1);
+						    ROBO_ARLCTRL_VEC_2,
+						    &ports_read, 1);
+		}
+	} else {
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_ADDR_2, addr_read, 3);
+		wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE,
+					   ROBO_ARLCTRL_VEC_2, &ports_read, 1);
+		/* or multiport address 2 */
+		if (os_memcmp(addr_read, addr_be16, 6) == 0 &&
+		    ports_read == ports) {
 			wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
-						    ROBO_ARLCTRL_VEC_2, &zero,
-						    1);
-		}
+						    ROBO_ARLCTRL_ADDR_1,
+						    addr_read, 3);
+			wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE,
+						    ROBO_ARLCTRL_VEC_1,
+						    &ports_read, 1);
+		} else return -1;
 	}
 	return 0;
 }
@@ -319,40 +350,35 @@
 static void * wpa_driver_roboswitch_init(void *ctx, const char *ifname)
 {
 	struct wpa_driver_roboswitch_data *drv;
-	int len = -1, sep = -1;
-	u16 vlan_max = ROBO_VLAN_MAX, vlan = 0, vlan_read[2];
+	char *sep;
+	u16 vlan = 0, _read[2];
 
 	drv = os_zalloc(sizeof(*drv));
 	if (drv == NULL) return NULL;
 	drv->ctx = ctx;
-
-	while (ifname[++len]) {
-		if (ifname[len] == '.')
-			sep = len;
-	}
-	if (sep < 0 || sep >= len - 1) {
+	drv->own_addr[0] = '\0';
+
+	/* copy ifname and take a pointer to the second to last character */
+	sep = drv->ifname +
+	      os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)) - 2;
+	/* find the '.' seperating <interface> and <vlan> */
+	while (sep > drv->ifname && *sep != '.') sep--;
+	if (sep <= drv->ifname) {
 		wpa_printf(MSG_INFO, "%s: No <interface>.<vlan> pair in "
-			   "interface name %s", __func__, ifname);
-		os_free(drv);
-		return NULL;
-	}
-	if (sep > IFNAMSIZ) {
-		wpa_printf(MSG_INFO, "%s: Interface name %s is too long",
-			   __func__, ifname);
-		os_free(drv);
-		return NULL;
-	}
-	os_memcpy(drv->ifname, ifname, sep);
-	drv->ifname[sep] = '\0';
-	while (++sep < len) {
-		if (ifname[sep] < '0' || ifname[sep] > '9') {
+			   "interface name %s", __func__, drv->ifname);
+		os_free(drv);
+		return NULL;
+	}
+	*sep = '\0';
+	while (*++sep) {
+		if (*sep < '0' || *sep > '9') {
 			wpa_printf(MSG_INFO, "%s: Invalid vlan specification "
 				   "in interface name %s", __func__, ifname);
 			os_free(drv);
 			return NULL;
 		}
 		vlan *= 10;
-		vlan += ifname[sep] - '0';
+		vlan += *sep - '0';
 		if (vlan > ROBO_VLAN_MAX) {
 			wpa_printf(MSG_INFO, "%s: VLAN out of range in "
 				   "interface name %s", __func__, ifname);
@@ -382,31 +408,32 @@
 		return NULL;
 	}
 
+	/* set and read back to see if the register can be used */
+	_read[0] = ROBO_VLAN_MAX;
+	wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350,
+				    _read, 1);
+	wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350,
+				   _read + 1, 1);
+	drv->is_5350 = _read[0] == _read[1];
+
 	/* set the read bit */
 	vlan |= 1 << 13;
-	/* set and read back to see if the register can be used */
-	wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS,
-				    &vlan_max, 1);
-	wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS,
-				   &vlan_max, 1);
-	if (vlan_max == ROBO_VLAN_MAX) /* pre-5365 */
-		wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE,
-					    ROBO_VLAN_ACCESS, &vlan, 1);
-	else /* 5365 uses a different register */
-		wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE,
-					    ROBO_VLAN_ACCESS_5365, &vlan, 1);
-	wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_READ,
-				   vlan_read, 2);
-	if (!(vlan_read[1] & (1 << 4))) {
+	wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE,
+				    drv->is_5350 ? ROBO_VLAN_ACCESS_5350
+						 : ROBO_VLAN_ACCESS,
+				    &vlan, 1);
+	wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_READ, _read,
+				   drv->is_5350 ? 2 : 1);
+	if (!(drv->is_5350 ? _read[1] & (1 << 4) : _read[0] & (1 << 14))) {
 		wpa_printf(MSG_INFO, "%s: Could not get port information for "
 				     "VLAN %d", __func__, vlan & ~(1 << 13));
 		os_free(drv);
 		return NULL;
 	}
-	drv->ports = vlan_read[0] & 0x001F;
+	drv->ports = _read[0] & 0x001F;
 	/* add the MII port */
 	drv->ports |= 1 << 8;
-	if (wpa_driver_roboswitch_join(drv, pae_group_addr) < 0) {
+	if (wpa_driver_roboswitch_join(drv, drv->ports, pae_group_addr) < 0) {
 		wpa_printf(MSG_INFO, "%s: Unable to join PAE group", __func__);
 		os_free(drv);
 		return NULL;
@@ -423,7 +450,11 @@
 {
 	struct wpa_driver_roboswitch_data *drv = priv;
 
-	if (wpa_driver_roboswitch_leave(drv, pae_group_addr) < 0) {
+	if (drv->l2) {
+		l2_packet_deinit(drv->l2);
+		drv->l2 = NULL;
+	}
+	if (wpa_driver_roboswitch_leave(drv, drv->ports, pae_group_addr) < 0) {
 		wpa_printf(MSG_DEBUG, "%s: Unable to leave PAE group",
 			   __func__);
 	}
@@ -440,5 +471,6 @@
 	.get_bssid = wpa_driver_roboswitch_get_bssid,
 	.init = wpa_driver_roboswitch_init,
 	.deinit = wpa_driver_roboswitch_deinit,
+	.set_param = wpa_driver_roboswitch_set_param,
 	.get_ifname = wpa_driver_roboswitch_get_ifname,
 };

Modified: hostapd/trunk/src/drivers/driver_wext.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_wext.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_wext.c (original)
+++ hostapd/trunk/src/drivers/driver_wext.c Thu Feb 11 04:49:20 2010
@@ -35,6 +35,7 @@
 static int wpa_driver_wext_flush_pmkid(void *priv);
 static int wpa_driver_wext_get_range(void *priv);
 static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
+static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv);
 
 
 static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
@@ -64,8 +65,9 @@
 	req.ifinfo.ifi_change = 0;
 
 	if (linkmode != -1) {
-		rta = (struct rtattr *)
-			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len));
+		rta = aliasing_hide_typecast(
+			((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
+			struct rtattr);
 		rta->rta_type = IFLA_LINKMODE;
 		rta->rta_len = RTA_LENGTH(sizeof(char));
 		*((char *) RTA_DATA(rta)) = linkmode;
@@ -982,6 +984,13 @@
 
 	wpa_driver_wext_get_range(drv);
 
+	/*
+	 * Unlock the driver's BSSID and force to a random SSID to clear any
+	 * previous association the driver might have when the supplicant
+	 * starts up.
+	 */
+	wpa_driver_wext_disconnect(drv);
+
 	drv->ifindex = if_nametoindex(drv->ifname);
 
 	if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
@@ -1021,8 +1030,7 @@
 	 * Clear possibly configured driver parameters in order to make it
 	 * easier to use the driver after wpa_supplicant has been terminated.
 	 */
-	(void) wpa_driver_wext_set_bssid(drv,
-					 (u8 *) "\x00\x00\x00\x00\x00\x00");
+	wpa_driver_wext_disconnect(drv);
 
 	wpa_driver_wext_send_oper_ifla(priv, 0, IF_OPER_UP);
 
@@ -1608,6 +1616,9 @@
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
 		if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
 			drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
+		drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
+			WPA_DRIVER_AUTH_SHARED |
+			WPA_DRIVER_AUTH_LEAP;
 
 		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
 			   "flags 0x%x",
@@ -1900,21 +1911,36 @@
 
 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
 {
+	struct iwreq iwr;
 	const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
 	u8 ssid[32];
 	int i;
 
 	/*
-	 * Clear the BSSID selection and set a random SSID to make sure the
-	 * driver will not be trying to associate with something even if it
-	 * does not understand SIOCSIWMLME commands (or tries to associate
-	 * automatically after deauth/disassoc).
+	 * Only force-disconnect when the card is in infrastructure mode,
+	 * otherwise the driver might interpret the cleared BSSID and random
+	 * SSID as an attempt to create a new ad-hoc network.
 	 */
-	wpa_driver_wext_set_bssid(drv, null_bssid);
-
-	for (i = 0; i < 32; i++)
-		ssid[i] = rand() & 0xFF;
-	wpa_driver_wext_set_ssid(drv, ssid, 32);
+	os_memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+	if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
+		perror("ioctl[SIOCGIWMODE]");
+		iwr.u.mode = IW_MODE_INFRA;
+	}
+
+	if (iwr.u.mode == IW_MODE_INFRA) {
+		/*
+		 * Clear the BSSID selection and set a random SSID to make sure
+		 * the driver will not be trying to associate with something
+		 * even if it does not understand SIOCSIWMLME commands (or
+		 * tries to associate automatically after deauth/disassoc).
+		 */
+		wpa_driver_wext_set_bssid(drv, null_bssid);
+
+		for (i = 0; i < 32; i++)
+			ssid[i] = rand() & 0xFF;
+		wpa_driver_wext_set_ssid(drv, ssid, 32);
+	}
 }
 
 
@@ -1924,8 +1950,8 @@
 	struct wpa_driver_wext_data *drv = priv;
 	int ret;
 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+	ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
 	wpa_driver_wext_disconnect(drv);
-	ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
 	return ret;
 }
 

Modified: hostapd/trunk/src/drivers/driver_wired.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_wired.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_wired.c (original)
+++ hostapd/trunk/src/drivers/driver_wired.c Thu Feb 11 04:49:20 2010
@@ -18,9 +18,9 @@
 #ifdef __linux__
 #include <netpacket/packet.h>
 #endif /* __linux__ */
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__DragonFly__)
 #include <net/if_dl.h>
-#endif /* __FreeBSD__ */
+#endif /* defined(__FreeBSD__) || defined(__DragonFly__) */
 
 #include "common.h"
 #include "driver.h"
@@ -118,7 +118,7 @@
 	ifr.ifr_hwaddr.sa_family = AF_UNSPEC;
 	os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN);
 #endif /* __linux__ */
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__DragonFly__)
 	{
 		struct sockaddr_dl *dlp;
 		dlp = (struct sockaddr_dl *) &ifr.ifr_addr;
@@ -130,7 +130,16 @@
 		dlp->sdl_slen = 0;
 		os_memcpy(LLADDR(dlp), addr, ETH_ALEN); 
 	}
-#endif /* __FreeBSD__ */
+#endif /* defined(__FreeBSD__) || defined(__DragonFly__) */
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+	{
+		struct sockaddr *sap;
+		sap = (struct sockaddr *) &ifr.ifr_addr;
+		sap->sa_len = sizeof(struct sockaddr);
+		sap->sa_family = AF_UNSPEC;
+		os_memcpy(sap->sa_data, addr, ETH_ALEN);
+	}
+#endif /* defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) */
 
 	if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) {
 		perror("ioctl[SIOC{ADD/DEL}MULTI]");

Modified: hostapd/trunk/src/eap_peer/eap_methods.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_peer/eap_methods.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_peer/eap_methods.h (original)
+++ hostapd/trunk/src/eap_peer/eap_methods.h Thu Feb 11 04:49:20 2010
@@ -62,6 +62,11 @@
 {
 }
 
+static inline char ** eap_get_names_as_string_array(size_t *num)
+{
+	return NULL;
+}
+
 #endif /* IEEE8021X_EAPOL */
 
 

Modified: hostapd/trunk/src/eap_peer/eap_sim.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_peer/eap_sim.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_peer/eap_sim.c (original)
+++ hostapd/trunk/src/eap_peer/eap_sim.c Thu Feb 11 04:49:20 2010
@@ -468,8 +468,6 @@
 	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Notification (id=%d)", id);
 	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id,
 			       EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION);
-	wpa_printf(MSG_DEBUG, "   AT_NOTIFICATION");
-	eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, notification, NULL, 0);
 	if (k_aut && data->reauth) {
 		wpa_printf(MSG_DEBUG, "   AT_IV");
 		wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");

Modified: hostapd/trunk/src/eap_peer/eap_tls_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_peer/eap_tls_common.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_peer/eap_tls_common.c (original)
+++ hostapd/trunk/src/eap_peer/eap_tls_common.c Thu Feb 11 04:49:20 2010
@@ -42,6 +42,18 @@
 	*data_len = blob->len;
 
 	return 0;
+}
+
+
+static void eap_tls_params_flags(struct tls_connection_params *params,
+				 const char *txt)
+{
+	if (txt == NULL)
+		return;
+	if (os_strstr(txt, "tls_allow_md5=1"))
+		params->flags |= TLS_CONN_ALLOW_SIGN_RSA_MD5;
+	if (os_strstr(txt, "tls_disable_time_checks=1"))
+		params->flags |= TLS_CONN_DISABLE_TIME_CHECKS;
 }
 
 
@@ -62,6 +74,7 @@
 	params->key_id = config->key_id;
 	params->cert_id = config->cert_id;
 	params->ca_cert_id = config->ca_cert_id;
+	eap_tls_params_flags(params, config->phase1);
 }
 
 
@@ -82,6 +95,7 @@
 	params->key_id = config->key2_id;
 	params->cert_id = config->cert2_id;
 	params->ca_cert_id = config->ca_cert2_id;
+	eap_tls_params_flags(params, config->phase2);
 }
 
 

Modified: hostapd/trunk/src/eap_peer/eap_ttls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_peer/eap_ttls.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_peer/eap_ttls.c (original)
+++ hostapd/trunk/src/eap_peer/eap_ttls.c Thu Feb 11 04:49:20 2010
@@ -842,7 +842,7 @@
 	/* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts
 	 * the data, so no separate encryption is used in the AVP itself.
 	 * However, the password is padded to obfuscate its length. */
-	pad = (16 - (password_len & 15)) & 15;
+	pad = password_len == 0 ? 16 : (16 - (password_len & 15)) & 15;
 	pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,
 			       password_len + pad);
 	os_memcpy(pos, password, password_len);

Modified: hostapd/trunk/src/eap_peer/eap_wsc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_peer/eap_wsc.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_peer/eap_wsc.c (original)
+++ hostapd/trunk/src/eap_peer/eap_wsc.c Thu Feb 11 04:49:20 2010
@@ -144,7 +144,7 @@
 
 	if (registrar && cfg.pin) {
 		wps_registrar_add_pin(data->wps_ctx->registrar, NULL,
-				      cfg.pin, cfg.pin_len);
+				      cfg.pin, cfg.pin_len, 0);
 	}
 
 	return data;

Modified: hostapd/trunk/src/eap_peer/tncc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_peer/tncc.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_peer/tncc.c (original)
+++ hostapd/trunk/src/eap_peer/tncc.c Thu Feb 11 04:49:20 2010
@@ -1106,6 +1106,7 @@
 	if (pos >= end || *pos != ' ') {
 		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMC line '%s' "
 			   "(no space after name)", start);
+		os_free(imc->name);
 		os_free(imc);
 		return NULL;
 	}

Modified: hostapd/trunk/src/eap_server/eap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_server/eap.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_server/eap.c (original)
+++ hostapd/trunk/src/eap_server/eap.c Thu Feb 11 04:49:20 2010
@@ -1261,7 +1261,7 @@
 		sm->m->reset(sm, sm->eap_method_priv);
 	wpabuf_free(sm->eap_if.eapReqData);
 	os_free(sm->eap_if.eapKeyData);
-	os_free(sm->lastReqData);
+	wpabuf_free(sm->lastReqData);
 	wpabuf_free(sm->eap_if.eapRespData);
 	os_free(sm->identity);
 	os_free(sm->pac_opaque_encr_key);

Modified: hostapd/trunk/src/eap_server/eap_fast.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_server/eap_fast.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_server/eap_fast.c (original)
+++ hostapd/trunk/src/eap_server/eap_fast.c Thu Feb 11 04:49:20 2010
@@ -71,6 +71,10 @@
 	int pac_key_lifetime;
 	int pac_key_refresh_time;
 };
+
+
+static int eap_fast_process_phase2_start(struct eap_sm *sm,
+					 struct eap_fast_data *data);
 
 
 static const char * eap_fast_state_txt(int state)
@@ -804,11 +808,48 @@
 }
 
 
+static int eap_fast_encrypt_phase2(struct eap_sm *sm,
+				   struct eap_fast_data *data,
+				   struct wpabuf *plain, int piggyback)
+{
+	struct wpabuf *encr;
+
+	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 TLVs",
+			    plain);
+	encr = eap_server_tls_encrypt(sm, &data->ssl, wpabuf_mhead(plain),
+				      wpabuf_len(plain));
+	wpabuf_free(plain);
+
+	if (data->ssl.out_buf && piggyback) {
+		wpa_printf(MSG_DEBUG, "EAP-FAST: Piggyback Phase 2 data "
+			   "(len=%d) with last Phase 1 Message (len=%d "
+			   "used=%d)",
+			   (int) wpabuf_len(encr),
+			   (int) wpabuf_len(data->ssl.out_buf),
+			   (int) data->ssl.out_used);
+		if (wpabuf_resize(&data->ssl.out_buf, wpabuf_len(encr)) < 0) {
+			wpa_printf(MSG_WARNING, "EAP-FAST: Failed to resize "
+				   "output buffer");
+			wpabuf_free(encr);
+			return -1;
+		}
+		wpabuf_put_buf(data->ssl.out_buf, encr);
+		wpabuf_free(encr);
+	} else {
+		wpabuf_free(data->ssl.out_buf);
+		data->ssl.out_used = 0;
+		data->ssl.out_buf = encr;
+	}
+
+	return 0;
+}
+
+
 static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_fast_data *data = priv;
 	struct wpabuf *req = NULL;
-	struct wpabuf *encr;
+	int piggyback = 0;
 
 	if (data->ssl.state == FRAG_ACK) {
 		return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
@@ -827,6 +868,19 @@
 		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 			if (eap_fast_phase1_done(sm, data) < 0)
 				return NULL;
+			if (data->state == PHASE2_START) {
+				/*
+				 * Try to generate Phase 2 data to piggyback
+				 * with the end of Phase 1 to avoid extra
+				 * roundtrip.
+				 */
+				wpa_printf(MSG_DEBUG, "EAP-FAST: Try to start "
+					   "Phase 2");
+				if (eap_fast_process_phase2_start(sm, data))
+					break;
+				req = eap_fast_build_phase2_req(sm, data, id);
+				piggyback = 1;
+			}
 		}
 		break;
 	case PHASE2_ID:
@@ -856,18 +910,9 @@
 		return NULL;
 	}
 
-	if (req) {
-		wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 "
-				    "TLVs", req);
-		encr = eap_server_tls_encrypt(sm, &data->ssl,
-					      wpabuf_mhead(req),
-					      wpabuf_len(req));
-		wpabuf_free(req);
-
-		wpabuf_free(data->ssl.out_buf);
-		data->ssl.out_used = 0;
-		data->ssl.out_buf = encr;
-	}
+	if (req &&
+	    eap_fast_encrypt_phase2(sm, data, req, piggyback) < 0)
+		return NULL;
 
 	return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
 					data->fast_version, id);
@@ -1443,8 +1488,8 @@
 }
 
 
-static void eap_fast_process_phase2_start(struct eap_sm *sm,
-					  struct eap_fast_data *data)
+static int eap_fast_process_phase2_start(struct eap_sm *sm,
+					 struct eap_fast_data *data)
 {
 	u8 next_type;
 
@@ -1474,7 +1519,7 @@
 		next_type = EAP_TYPE_IDENTITY;
 	}
 
-	eap_fast_phase2_init(sm, data, next_type);
+	return eap_fast_phase2_init(sm, data, next_type);
 }
 
 

Modified: hostapd/trunk/src/eap_server/eap_tls_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_server/eap_tls_common.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eap_server/eap_tls_common.c (original)
+++ hostapd/trunk/src/eap_server/eap_tls_common.c Thu Feb 11 04:49:20 2010
@@ -344,7 +344,7 @@
 	size_t buf_len;
 
 	/* reserve some extra room for encryption overhead */
-	buf_len = plain_len + 200;
+	buf_len = plain_len + 300;
 	buf = wpabuf_alloc(buf_len);
 	if (buf == NULL)
 		return NULL;

Modified: hostapd/trunk/src/eapol_supp/eapol_supp_sm.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eapol_supp/eapol_supp_sm.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/eapol_supp/eapol_supp_sm.c (original)
+++ hostapd/trunk/src/eapol_supp/eapol_supp_sm.c Thu Feb 11 04:49:20 2010
@@ -742,8 +742,8 @@
 		os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key,
 			  encr_key_len);
 		os_memcpy(datakey, key + 1, key_len);
-		rc4(datakey, key_len, ekey,
-		    IEEE8021X_KEY_IV_LEN + encr_key_len);
+		rc4_skip(ekey, IEEE8021X_KEY_IV_LEN + encr_key_len, 0,
+			 datakey, key_len);
 		wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key",
 				datakey, key_len);
 	} else if (key_len == 0) {

Modified: hostapd/trunk/src/hlr_auc_gw/hlr_auc_gw.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/hlr_auc_gw/hlr_auc_gw.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/hlr_auc_gw/hlr_auc_gw.c (original)
+++ hostapd/trunk/src/hlr_auc_gw/hlr_auc_gw.c Thu Feb 11 04:49:20 2010
@@ -532,7 +532,7 @@
 static void aka_auts(int s, struct sockaddr_un *from, socklen_t fromlen,
 		     char *imsi)
 {
-	char *auts, *rand;
+	char *auts, *__rand;
 	u8 _auts[EAP_AKA_AUTS_LEN], _rand[EAP_AKA_RAND_LEN], sqn[6];
 	struct milenage_parameters *m;
 
@@ -543,14 +543,14 @@
 		return;
 	*auts++ = '\0';
 
-	rand = strchr(auts, ' ');
-	if (rand == NULL)
+	__rand = strchr(auts, ' ');
+	if (__rand == NULL)
 		return;
-	*rand++ = '\0';
-
-	printf("AKA-AUTS: IMSI=%s AUTS=%s RAND=%s\n", imsi, auts, rand);
+	*__rand++ = '\0';
+
+	printf("AKA-AUTS: IMSI=%s AUTS=%s RAND=%s\n", imsi, auts, __rand);
 	if (hexstr2bin(auts, _auts, EAP_AKA_AUTS_LEN) ||
-	    hexstr2bin(rand, _rand, EAP_AKA_RAND_LEN)) {
+	    hexstr2bin(__rand, _rand, EAP_AKA_RAND_LEN)) {
 		printf("Could not parse AUTS/RAND\n");
 		return;
 	}

Modified: hostapd/trunk/src/l2_packet/l2_packet_linux.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/l2_packet/l2_packet_linux.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/l2_packet/l2_packet_linux.c (original)
+++ hostapd/trunk/src/l2_packet/l2_packet_linux.c Thu Feb 11 04:49:20 2010
@@ -185,7 +185,7 @@
 		return -1;
 	}
 	close(s);
-	saddr = (struct sockaddr_in *) &ifr.ifr_addr;
+	saddr = aliasing_hide_typecast(&ifr.ifr_addr, struct sockaddr_in);
 	if (saddr->sin_family != AF_INET)
 		return -1;
 	res = os_strlcpy(buf, inet_ntoa(saddr->sin_addr), len);

Modified: hostapd/trunk/src/radius/radius_client.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/radius/radius_client.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/radius/radius_client.c (original)
+++ hostapd/trunk/src/radius/radius_client.c Thu Feb 11 04:49:20 2010
@@ -917,6 +917,22 @@
 }
 
 
+static int radius_client_disable_pmtu_discovery(int s)
+{
+	int r = -1;
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
+	/* Turn off Path MTU discovery on IPv4/UDP sockets. */
+	int action = IP_PMTUDISC_DONT;
+	r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
+		       sizeof(action));
+	if (r == -1)
+		wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
+			   "%s", strerror(errno));
+#endif
+	return r;
+}
+
+
 static int radius_client_init_auth(struct radius_client_data *radius)
 {
 	struct hostapd_radius_servers *conf = radius->conf;
@@ -925,8 +941,10 @@
 	radius->auth_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
 	if (radius->auth_serv_sock < 0)
 		perror("socket[PF_INET,SOCK_DGRAM]");
-	else
+	else {
+		radius_client_disable_pmtu_discovery(radius->auth_serv_sock);
 		ok++;
+	}
 
 #ifdef CONFIG_IPV6
 	radius->auth_serv_sock6 = socket(PF_INET6, SOCK_DGRAM, 0);
@@ -975,8 +993,10 @@
 	radius->acct_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
 	if (radius->acct_serv_sock < 0)
 		perror("socket[PF_INET,SOCK_DGRAM]");
-	else
+	else {
+		radius_client_disable_pmtu_discovery(radius->acct_serv_sock);
 		ok++;
+	}
 
 #ifdef CONFIG_IPV6
 	radius->acct_serv_sock6 = socket(PF_INET6, SOCK_DGRAM, 0);
@@ -1060,6 +1080,12 @@
 		eloop_unregister_read_sock(radius->auth_serv_sock);
 	if (radius->acct_serv_sock >= 0)
 		eloop_unregister_read_sock(radius->acct_serv_sock);
+#ifdef CONFIG_IPV6
+	if (radius->auth_serv_sock6 >= 0)
+		eloop_unregister_read_sock(radius->auth_serv_sock6);
+	if (radius->acct_serv_sock6 >= 0)
+		eloop_unregister_read_sock(radius->acct_serv_sock6);
+#endif /* CONFIG_IPV6 */
 
 	eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL);
 

Modified: hostapd/trunk/src/radius/radius_server.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/radius/radius_server.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/radius/radius_server.c (original)
+++ hostapd/trunk/src/radius/radius_server.c Thu Feb 11 04:49:20 2010
@@ -117,7 +117,8 @@
 
 
 static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
-
+static void radius_server_session_remove_timeout(void *eloop_ctx,
+						 void *timeout_ctx);
 
 
 static struct radius_client *
@@ -179,6 +180,7 @@
 				       struct radius_session *sess)
 {
 	eloop_cancel_timeout(radius_server_session_timeout, data, sess);
+	eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
 	eap_server_sm_deinit(sess->eap);
 	if (sess->last_msg) {
 		radius_msg_free(sess->last_msg);
@@ -193,9 +195,6 @@
 	data->num_sess--;
 }
 
-
-static void radius_server_session_remove_timeout(void *eloop_ctx,
-						 void *timeout_ctx);
 
 static void radius_server_session_remove(struct radius_server_data *data,
 					 struct radius_session *sess)
@@ -493,6 +492,7 @@
 	unsigned int state;
 	struct radius_session *sess;
 	struct radius_msg *reply;
+	int is_complete = 0;
 
 	if (force_sess)
 		sess = force_sess;
@@ -603,6 +603,9 @@
 		return -1;
 	}
 
+	if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
+		is_complete = 1;
+
 	reply = radius_server_encapsulate_eap(data, client, sess, msg);
 
 	if (reply) {
@@ -644,7 +647,7 @@
 		client->counters.packets_dropped++;
 	}
 
-	if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) {
+	if (is_complete) {
 		RADIUS_DEBUG("Removing completed session 0x%x after timeout",
 			     sess->sess_id);
 		eloop_cancel_timeout(radius_server_session_remove_timeout,
@@ -663,7 +666,13 @@
 {
 	struct radius_server_data *data = eloop_ctx;
 	u8 *buf = NULL;
-	struct sockaddr_storage from;
+	union {
+		struct sockaddr_storage ss;
+		struct sockaddr_in sin;
+#ifdef CONFIG_IPV6
+		struct sockaddr_in6 sin6;
+#endif /* CONFIG_IPV6 */
+	} from;
 	socklen_t fromlen;
 	int len;
 	struct radius_client *client = NULL;
@@ -678,7 +687,7 @@
 
 	fromlen = sizeof(from);
 	len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
-		       (struct sockaddr *) &from, &fromlen);
+		       (struct sockaddr *) &from.ss, &fromlen);
 	if (len < 0) {
 		perror("recvfrom[radius_server]");
 		goto fail;
@@ -686,28 +695,26 @@
 
 #ifdef CONFIG_IPV6
 	if (data->ipv6) {
-		struct sockaddr_in6 *from6 = (struct sockaddr_in6 *) &from;
-		if (inet_ntop(AF_INET6, &from6->sin6_addr, abuf, sizeof(abuf))
-		    == NULL)
+		if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
+			      sizeof(abuf)) == NULL)
 			abuf[0] = '\0';
-		from_port = ntohs(from6->sin6_port);
+		from_port = ntohs(from.sin6.sin6_port);
 		RADIUS_DEBUG("Received %d bytes from %s:%d",
 			     len, abuf, from_port);
 
 		client = radius_server_get_client(data,
 						  (struct in_addr *)
-						  &from6->sin6_addr, 1);
+						  &from.sin6.sin6_addr, 1);
 	}
 #endif /* CONFIG_IPV6 */
 
 	if (!data->ipv6) {
-		struct sockaddr_in *from4 = (struct sockaddr_in *) &from;
-		os_strlcpy(abuf, inet_ntoa(from4->sin_addr), sizeof(abuf));
-		from_port = ntohs(from4->sin_port);
+		os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
+		from_port = ntohs(from.sin.sin_port);
 		RADIUS_DEBUG("Received %d bytes from %s:%d",
 			     len, abuf, from_port);
 
-		client = radius_server_get_client(data, &from4->sin_addr, 0);
+		client = radius_server_get_client(data, &from.sin.sin_addr, 0);
 	}
 
 	RADIUS_DUMP("Received data", buf, len);
@@ -765,6 +772,22 @@
 }
 
 
+static int radius_server_disable_pmtu_discovery(int s)
+{
+	int r = -1;
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
+	/* Turn off Path MTU discovery on IPv4/UDP sockets. */
+	int action = IP_PMTUDISC_DONT;
+	r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
+		       sizeof(action));
+	if (r == -1)
+		wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
+			   "%s", strerror(errno));
+#endif
+	return r;
+}
+
+
 static int radius_server_open_socket(int port)
 {
 	int s;
@@ -775,6 +798,8 @@
 		perror("socket");
 		return -1;
 	}
+
+	radius_server_disable_pmtu_discovery(s);
 
 	os_memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;

Modified: hostapd/trunk/src/rsn_supp/wpa.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/rsn_supp/wpa.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/rsn_supp/wpa.c (original)
+++ hostapd/trunk/src/rsn_supp/wpa.c Thu Feb 11 04:49:20 2010
@@ -358,14 +358,15 @@
 			  const struct wpa_eapol_key *key,
 			  struct wpa_ptk *ptk)
 {
+	size_t ptk_len = sm->pairwise_cipher == WPA_CIPHER_CCMP ? 48 : 64;
 #ifdef CONFIG_IEEE80211R
 	if (wpa_key_mgmt_ft(sm->key_mgmt))
-		return wpa_derive_ptk_ft(sm, src_addr, key, ptk);
+		return wpa_derive_ptk_ft(sm, src_addr, key, ptk, ptk_len);
 #endif /* CONFIG_IEEE80211R */
 
 	wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
 		       sm->own_addr, sm->bssid, sm->snonce, key->key_nonce,
-		       (u8 *) ptk, sizeof(*ptk),
+		       (u8 *) ptk, ptk_len,
 		       wpa_key_mgmt_sha256(sm->key_mgmt));
 	return 0;
 }
@@ -407,13 +408,13 @@
 #endif /* CONFIG_NO_WPA2 */
 
 	if (wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid))
-		return;
+		goto failed;
 
 	if (sm->renew_snonce) {
 		if (os_get_random(sm->snonce, WPA_NONCE_LEN)) {
 			wpa_msg(sm->ctx->ctx, MSG_WARNING,
 				"WPA: Failed to get random data for SNonce");
-			return;
+			goto failed;
 		}
 		sm->renew_snonce = 0;
 		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
@@ -433,9 +434,13 @@
 	if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
 				       sm->assoc_wpa_ie, sm->assoc_wpa_ie_len,
 				       ptk))
-		return;
+		goto failed;
 
 	os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
+	return;
+
+failed:
+	wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
 }
 
 
@@ -537,7 +542,8 @@
 	if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,
 			   (u8 *) sm->ptk.tk1, keylen) < 0) {
 		wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the "
-			   "driver.");
+			   "driver (alg=%d keylen=%d bssid=" MACSTR ")",
+			   alg, keylen, MAC2STR(sm->bssid));
 		return -1;
 	}
 
@@ -647,7 +653,8 @@
 				  gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,
 				  _gtk, gd->gtk_len) < 0) {
 		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "
-			   "the driver.");
+			   "the driver (alg=%d keylen=%d keyidx=%d)",
+			   gd->alg, gd->gtk_len, gd->keyidx);
 		return -1;
 	}
 
@@ -944,30 +951,30 @@
 	wpa_supplicant_parse_ies(pos, len, &ie);
 	if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
 		wpa_printf(MSG_WARNING, "WPA: GTK IE in unencrypted key data");
-		return;
+		goto failed;
 	}
 #ifdef CONFIG_IEEE80211W
 	if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
 		wpa_printf(MSG_WARNING, "WPA: IGTK KDE in unencrypted key "
 			   "data");
-		return;
+		goto failed;
 	}
 
 	if (ie.igtk && ie.igtk_len != sizeof(struct wpa_igtk_kde)) {
 		wpa_printf(MSG_WARNING, "WPA: Invalid IGTK KDE length %lu",
 			   (unsigned long) ie.igtk_len);
-		return;
+		goto failed;
 	}
 #endif /* CONFIG_IEEE80211W */
 
 	if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
-		return;
+		goto failed;
 
 	if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
 		wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way "
 			   "Handshake differs from 3 of 4-Way Handshake - drop"
 			   " packet (src=" MACSTR ")", MAC2STR(sm->bssid));
-		return;
+		goto failed;
 	}
 
 	keylen = WPA_GET_BE16(key->key_length);
@@ -977,7 +984,7 @@
 			wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "
 				   "%d (src=" MACSTR ")",
 				   keylen, MAC2STR(sm->bssid));
-			return;
+			goto failed;
 		}
 		break;
 	case WPA_CIPHER_TKIP:
@@ -985,14 +992,15 @@
 			wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length "
 				   "%d (src=" MACSTR ")",
 				   keylen, MAC2STR(sm->bssid));
-			return;
+			goto failed;
 		}
 		break;
 	}
 
 	if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
-				       NULL, 0, &sm->ptk))
-		return;
+				       NULL, 0, &sm->ptk)) {
+		goto failed;
+	}
 
 	/* SNonce was successfully used in msg 3/4, so mark it to be renewed
 	 * for the next 4-Way Handshake. If msg 3 is received again, the old
@@ -1000,7 +1008,8 @@
 	sm->renew_snonce = 1;
 
 	if (key_info & WPA_KEY_INFO_INSTALL) {
-		wpa_supplicant_install_ptk(sm, key);
+		if (wpa_supplicant_install_ptk(sm, key))
+			goto failed;
 	}
 
 	if (key_info & WPA_KEY_INFO_SECURE) {
@@ -1015,10 +1024,18 @@
 	    wpa_supplicant_pairwise_gtk(sm, key,
 					ie.gtk, ie.gtk_len, key_info) < 0) {
 		wpa_printf(MSG_INFO, "RSN: Failed to configure GTK");
-	}
-
-	if (ieee80211w_set_keys(sm, &ie) < 0)
+		goto failed;
+	}
+
+	if (ieee80211w_set_keys(sm, &ie) < 0) {
 		wpa_printf(MSG_INFO, "RSN: Failed to configure IGTK");
+		goto failed;
+	}
+
+	return;
+
+failed:
+	wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
 }
 
 
@@ -1209,11 +1226,11 @@
 	wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
 
 	if (ret)
-		return;
+		goto failed;
 
 	if (wpa_supplicant_install_gtk(sm, &gd, key->key_rsc) ||
 	    wpa_supplicant_send_2_of_2(sm, key, ver, key_info))
-		return;
+		goto failed;
 
 	if (rekey) {
 		wpa_msg(sm->ctx->ctx, MSG_INFO, "WPA: Group rekeying "
@@ -1226,6 +1243,10 @@
 						key_info &
 						WPA_KEY_INFO_SECURE);
 	}
+	return;
+
+failed:
+	wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
 }
 
 

Modified: hostapd/trunk/src/rsn_supp/wpa_ft.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/rsn_supp/wpa_ft.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/rsn_supp/wpa_ft.c (original)
+++ hostapd/trunk/src/rsn_supp/wpa_ft.c Thu Feb 11 04:49:20 2010
@@ -25,7 +25,7 @@
 
 int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 		      const struct wpa_eapol_key *key,
-		      struct wpa_ptk *ptk)
+		      struct wpa_ptk *ptk, size_t ptk_len)
 {
 	u8 pmk_r1_name[WPA_PMK_NAME_LEN];
 	u8 ptk_name[WPA_PMK_NAME_LEN];
@@ -50,8 +50,8 @@
 	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN);
 	wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, anonce, sm->own_addr,
 			  sm->bssid, pmk_r1_name,
-			  (u8 *) ptk, sizeof(*ptk), ptk_name);
-	wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, sizeof(*ptk));
+			  (u8 *) ptk, ptk_len, ptk_name);
+	wpa_hexdump_key(MSG_DEBUG, "FT: PTK", (u8 *) ptk, ptk_len);
 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
 
 	return 0;
@@ -455,7 +455,7 @@
 			    int ft_action, const u8 *target_ap)
 {
 	u8 *ft_ies;
-	size_t ft_ies_len;
+	size_t ft_ies_len, ptk_len;
 	struct wpa_ft_ies parse;
 	struct rsn_mdie *mdie;
 	struct rsn_ftie *ftie;
@@ -545,11 +545,12 @@
 		    sm->pmk_r1_name, WPA_PMK_NAME_LEN);
 
 	bssid = target_ap;
+	ptk_len = sm->pairwise_cipher == WPA_CIPHER_CCMP ? 48 : 64;
 	wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, ftie->anonce, sm->own_addr,
 			  bssid, sm->pmk_r1_name,
-			  (u8 *) &sm->ptk, sizeof(sm->ptk), ptk_name);
+			  (u8 *) &sm->ptk, ptk_len, ptk_name);
 	wpa_hexdump_key(MSG_DEBUG, "FT: PTK",
-			(u8 *) &sm->ptk, sizeof(sm->ptk));
+			(u8 *) &sm->ptk, ptk_len);
 	wpa_hexdump(MSG_DEBUG, "FT: PTKName", ptk_name, WPA_PMK_NAME_LEN);
 
 	ft_ies = wpa_ft_gen_req_ies(sm, &ft_ies_len, ftie->anonce,

Modified: hostapd/trunk/src/rsn_supp/wpa_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/rsn_supp/wpa_i.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/rsn_supp/wpa_i.h (original)
+++ hostapd/trunk/src/rsn_supp/wpa_i.h Thu Feb 11 04:49:20 2010
@@ -240,6 +240,6 @@
 
 int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
 		      const struct wpa_eapol_key *key,
-		      struct wpa_ptk *ptk);
+		      struct wpa_ptk *ptk, size_t ptk_len);
 
 #endif /* WPA_I_H */

Modified: hostapd/trunk/src/tls/rsa.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/tls/rsa.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/tls/rsa.c (original)
+++ hostapd/trunk/src/tls/rsa.c Thu Feb 11 04:49:20 2010
@@ -35,6 +35,7 @@
 };
 
 
+#ifdef EAP_TLS_FUNCS
 static const u8 * crypto_rsa_parse_integer(const u8 *pos, const u8 *end,
 					   struct bignum *num)
 {
@@ -223,6 +224,7 @@
 	crypto_rsa_free(key);
 	return NULL;
 }
+#endif /* EAP_TLS_FUNCS */
 
 
 /**

Modified: hostapd/trunk/src/tls/tlsv1_client.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/tls/tlsv1_client.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/tls/tlsv1_client.c (original)
+++ hostapd/trunk/src/tls/tlsv1_client.c Thu Feb 11 04:49:20 2010
@@ -627,7 +627,7 @@
 		 * 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
+		 * workaround, add 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;

Modified: hostapd/trunk/src/tls/tlsv1_server_read.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/tls/tlsv1_server_read.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/tls/tlsv1_server_read.c (original)
+++ hostapd/trunk/src/tls/tlsv1_server_read.c Thu Feb 11 04:49:20 2010
@@ -40,6 +40,7 @@
 	u16 cipher_suite;
 	u16 num_suites;
 	int compr_null_found;
+	u16 ext_type, ext_len;
 
 	if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
@@ -183,10 +184,7 @@
 	}
 
 	if (end - pos >= 2) {
-		u16 ext_len;
-
 		/* Extension client_hello_extension_list<0..2^16-1> */
-
 		ext_len = WPA_GET_BE16(pos);
 		pos += 2;
 
@@ -195,7 +193,7 @@
 		if (end - pos != ext_len) {
 			wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientHello "
 				   "extension list length %u (expected %u)",
-				   ext_len, end - pos);
+				   ext_len, (unsigned int) (end - pos));
 			goto decode_error;
 		}
 
@@ -207,8 +205,6 @@
 		 */
 
 		while (pos < end) {
-			u16 ext_type, ext_len;
-
 			if (end - pos < 2) {
 				wpa_printf(MSG_DEBUG, "TLSv1: Invalid "
 					   "extension_type field");
@@ -520,7 +516,7 @@
 						 out, &outlen) < 0) {
 		wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt "
 			   "PreMasterSecret (encr_len=%d outlen=%lu)",
-			   end - pos, (unsigned long) outlen);
+			   (int) (end - pos), (unsigned long) outlen);
 		use_random = 1;
 	}
 

Modified: hostapd/trunk/src/utils/base64.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/base64.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/utils/base64.c (original)
+++ hostapd/trunk/src/utils/base64.c Thu Feb 11 04:49:20 2010
@@ -43,6 +43,8 @@
 	olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
 	olen += olen / 72; /* line feeds */
 	olen++; /* nul termination */
+	if (olen < len)
+		return NULL; /* integer overflow */
 	out = os_malloc(olen);
 	if (out == NULL)
 		return NULL;

Modified: hostapd/trunk/src/utils/common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/common.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/utils/common.c (original)
+++ hostapd/trunk/src/utils/common.c Thu Feb 11 04:49:20 2010
@@ -325,3 +325,9 @@
 	}
 	return ssid_txt;
 }
+
+
+void * __hide_aliasing_typecast(void *foo)
+{
+	return foo;
+}

Modified: hostapd/trunk/src/utils/common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/common.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/utils/common.h (original)
+++ hostapd/trunk/src/utils/common.h Thu Feb 11 04:49:20 2010
@@ -22,17 +22,24 @@
 #include <byteswap.h>
 #endif /* __linux__ */
 
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
+    defined(__OpenBSD__)
 #include <sys/types.h>
 #include <sys/endian.h>
 #define __BYTE_ORDER	_BYTE_ORDER
 #define	__LITTLE_ENDIAN	_LITTLE_ENDIAN
 #define	__BIG_ENDIAN	_BIG_ENDIAN
+#ifdef __OpenBSD__
+#define bswap_16 swap16
+#define bswap_32 swap32
+#define bswap_64 swap64
+#else /* __OpenBSD__ */
 #define bswap_16 bswap16
 #define bswap_32 bswap32
 #define bswap_64 bswap64
+#endif /* __OpenBSD__ */
 #endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
-	* defined(__DragonFly__) */
+	* defined(__DragonFly__) || defined(__OpenBSD__) */
 
 #ifdef __APPLE__
 #include <sys/types.h>
@@ -435,4 +442,17 @@
 
 #include "wpa_debug.h"
 
+
+/*
+ * gcc 4.4 ends up generating strict-aliasing warnings about some very common
+ * networking socket uses that do not really result in a real problem and
+ * cannot be easily avoided with union-based type-punning due to struct
+ * definitions including another struct in system header files. To avoid having
+ * to fully disable strict-aliasing warnings, provide a mechanism to hide the
+ * typecast from aliasing for now. A cleaner solution will hopefully be found
+ * in the future to handle these cases.
+ */
+void * __hide_aliasing_typecast(void *foo);
+#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a))
+
 #endif /* COMMON_H */

Modified: hostapd/trunk/src/utils/os_unix.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/os_unix.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/utils/os_unix.c (original)
+++ hostapd/trunk/src/utils/os_unix.c Thu Feb 11 04:49:20 2010
@@ -227,7 +227,8 @@
 
 int os_unsetenv(const char *name)
 {
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \
+    defined(__OpenBSD__)
 	unsetenv(name);
 	return 0;
 #else

Modified: hostapd/trunk/src/utils/wpa_debug.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/wpa_debug.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/utils/wpa_debug.c (original)
+++ hostapd/trunk/src/utils/wpa_debug.c Thu Feb 11 04:49:20 2010
@@ -56,7 +56,7 @@
  *
  * Note: New line '\n' is added to the end of the text when printing to stdout.
  */
-void wpa_printf(int level, char *fmt, ...)
+void wpa_printf(int level, const char *fmt, ...)
 {
 	va_list ap;
 
@@ -267,7 +267,7 @@
 }
 
 
-void wpa_msg(void *ctx, int level, char *fmt, ...)
+void wpa_msg(void *ctx, int level, const char *fmt, ...)
 {
 	va_list ap;
 	char *buf;
@@ -286,6 +286,30 @@
 	wpa_printf(level, "%s", buf);
 	if (wpa_msg_cb)
 		wpa_msg_cb(ctx, level, buf, len);
+	os_free(buf);
+}
+
+
+void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
+{
+	va_list ap;
+	char *buf;
+	const int buflen = 2048;
+	int len;
+
+	if (!wpa_msg_cb)
+		return;
+
+	buf = os_malloc(buflen);
+	if (buf == NULL) {
+		wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
+			   "message buffer");
+		return;
+	}
+	va_start(ap, fmt);
+	len = vsnprintf(buf, buflen, fmt, ap);
+	va_end(ap);
+	wpa_msg_cb(ctx, level, buf, len);
 	os_free(buf);
 }
 #endif /* CONFIG_NO_WPA_MSG */

Modified: hostapd/trunk/src/utils/wpa_debug.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/wpa_debug.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/utils/wpa_debug.h (original)
+++ hostapd/trunk/src/utils/wpa_debug.h Thu Feb 11 04:49:20 2010
@@ -60,7 +60,7 @@
  *
  * Note: New line '\n' is added to the end of the text when printing to stdout.
  */
-void wpa_printf(int level, char *fmt, ...)
+void wpa_printf(int level, const char *fmt, ...)
 PRINTF_FORMAT(2, 3);
 
 /**
@@ -141,6 +141,7 @@
 
 #ifdef CONFIG_NO_WPA_MSG
 #define wpa_msg(args...) do { } while (0)
+#define wpa_msg_ctrl(args...) do { } while (0)
 #define wpa_msg_register_cb(f) do { } while (0)
 #else /* CONFIG_NO_WPA_MSG */
 /**
@@ -157,7 +158,22 @@
  *
  * Note: New line '\n' is added to the end of the text when printing to stdout.
  */
-void wpa_msg(void *ctx, int level, char *fmt, ...) PRINTF_FORMAT(3, 4);
+void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4);
+
+/**
+ * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors
+ * @ctx: Pointer to context data; this is the ctx variable registered
+ *	with struct wpa_driver_ops::init()
+ * @level: priority level (MSG_*) of the message
+ * @fmt: printf format string, followed by optional arguments
+ *
+ * This function is used to print conditional debugging and error messages.
+ * This function is like wpa_msg(), but it sends the output only to the
+ * attached ctrl_iface monitors. In other words, it can be used for frequent
+ * events that do not need to be sent to syslog.
+ */
+void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
+PRINTF_FORMAT(3, 4);
 
 typedef void (*wpa_msg_cb_func)(void *ctx, int level, const char *txt,
 				size_t len);

Modified: hostapd/trunk/src/utils/wpabuf.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/wpabuf.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/utils/wpabuf.c (original)
+++ hostapd/trunk/src/utils/wpabuf.c Thu Feb 11 04:49:20 2010
@@ -29,6 +29,10 @@
 int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
 {
 	struct wpabuf *buf = *_buf;
+	if (buf == NULL) {
+		*_buf = wpabuf_alloc(add_len);
+		return *_buf == NULL ? -1 : 0;
+	}
 	if (buf->used + add_len > buf->size) {
 		unsigned char *nbuf;
 		if (buf->ext_data) {

Modified: hostapd/trunk/src/wps/httpread.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/httpread.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/httpread.c (original)
+++ hostapd/trunk/src/wps/httpread.c Thu Feb 11 04:49:20 2010
@@ -206,7 +206,8 @@
 		h->got_content_length = 1;
 		return 0;
 	}
-	if (word_eq(hbp, "TRANSFER_ENCODING:")) {
+	if (word_eq(hbp, "TRANSFER_ENCODING:") ||
+	    word_eq(hbp, "TRANSFER-ENCODING:")) {
 		while (isgraph(*hbp))
 			hbp++;
 		while (*hbp == ' ' || *hbp == '\t')
@@ -214,7 +215,7 @@
 		/* There should (?) be no encodings of interest
 		 * other than chunked...
 		 */
-		if (os_strncmp(hbp, "CHUNKED", 7)) {
+		if (word_eq(hbp, "CHUNKED")) {
 			h->chunked = 1;
 			h->in_chunk_data = 0;
 			/* ignore possible ;<parameters> */
@@ -513,6 +514,8 @@
 	 * consists of chunks each with a header, ending with
 	 * an ending header.
 	 */
+	if (nread == 0)
+		goto get_more;
 	if (!h->got_body) {
 		/* Here to get (more of) body */
 		/* ensure we have enough room for worst case for body

Modified: hostapd/trunk/src/wps/wps.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps.h (original)
+++ hostapd/trunk/src/wps/wps.h Thu Feb 11 04:49:20 2010
@@ -42,7 +42,7 @@
  * @key_idx: Key index
  * @key: Key
  * @key_len: Key length in octets
- * @mac_addr: MAC address of the peer
+ * @mac_addr: MAC address of the Credential receiver
  * @cred_attr: Unparsed Credential attribute data (used only in cred_cb());
  *	this may be %NULL, if not used
  * @cred_attr_len: Length of cred_attr in octets
@@ -296,7 +296,17 @@
 	/**
 	 * WPS_EV_PWD_AUTH_FAIL - Password authentication failed
 	 */
-	WPS_EV_PWD_AUTH_FAIL
+	WPS_EV_PWD_AUTH_FAIL,
+
+	/**
+	 * WPS_EV_PBC_OVERLAP - PBC session overlap detected
+	 */
+	WPS_EV_PBC_OVERLAP,
+
+	/**
+	 * WPS_EV_PBC_TIMEOUT - PBC walktime expired before protocol run start
+	 */
+	WPS_EV_PBC_TIMEOUT
 };
 
 /**
@@ -505,7 +515,7 @@
 		   const struct wps_registrar_config *cfg);
 void wps_registrar_deinit(struct wps_registrar *reg);
 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
-			  const u8 *pin, size_t pin_len);
+			  const u8 *pin, size_t pin_len, int timeout);
 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid);
 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid);
 int wps_registrar_button_pushed(struct wps_registrar *reg);

Modified: hostapd/trunk/src/wps/wps_attr_parse.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_attr_parse.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_attr_parse.c (original)
+++ hostapd/trunk/src/wps/wps_attr_parse.c Thu Feb 11 04:49:20 2010
@@ -381,6 +381,14 @@
 		attr->eap_identity = pos;
 		attr->eap_identity_len = len;
 		break;
+	case ATTR_AP_SETUP_LOCKED:
+		if (len != 1) {
+			wpa_printf(MSG_DEBUG, "WPS: Invalid AP Setup Locked "
+				   "length %u", len);
+			return -1;
+		}
+		attr->ap_setup_locked = pos;
+		break;
 	default:
 		wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
 			   "len=%u", type, len);

Modified: hostapd/trunk/src/wps/wps_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_common.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_common.c (original)
+++ hostapd/trunk/src/wps/wps_common.c Thu Feb 11 04:49:20 2010
@@ -128,56 +128,6 @@
 }
 
 
-int wps_derive_mgmt_keys(struct wps_data *wps)
-{
-	u8 nonces[2 * WPS_NONCE_LEN];
-	u8 keys[WPS_MGMTAUTHKEY_LEN + WPS_MGMTENCKEY_LEN];
-	u8 hash[SHA256_MAC_LEN];
-	const u8 *addr[2];
-	size_t len[2];
-	const char *auth_label = "WFA-WLAN-Management-MgmtAuthKey";
-	const char *enc_label = "WFA-WLAN-Management-MgmtEncKey";
-
-	/* MgmtAuthKey || MgmtEncKey =
-	 * kdf(EMSK, N1 || N2 || "WFA-WLAN-Management-Keys", 384) */
-	os_memcpy(nonces, wps->nonce_e, WPS_NONCE_LEN);
-	os_memcpy(nonces + WPS_NONCE_LEN, wps->nonce_r, WPS_NONCE_LEN);
-	wps_kdf(wps->emsk, nonces, sizeof(nonces), "WFA-WLAN-Management-Keys",
-		keys, sizeof(keys));
-	os_memcpy(wps->mgmt_auth_key, keys, WPS_MGMTAUTHKEY_LEN);
-	os_memcpy(wps->mgmt_enc_key, keys + WPS_MGMTAUTHKEY_LEN,
-		  WPS_MGMTENCKEY_LEN);
-
-	addr[0] = nonces;
-	len[0] = sizeof(nonces);
-
-	/* MgmtEncKeyID = first 128 bits of
-	 * SHA-256(N1 || N2 || "WFA-WLAN-Management-MgmtAuthKey") */
-	addr[1] = (const u8 *) auth_label;
-	len[1] = os_strlen(auth_label);
-	sha256_vector(2, addr, len, hash);
-	os_memcpy(wps->mgmt_auth_key_id, hash, WPS_MGMT_KEY_ID_LEN);
-
-	/* MgmtEncKeyID = first 128 bits of
-	 * SHA-256(N1 || N2 || "WFA-WLAN-Management-MgmtEncKey") */
-	addr[1] = (const u8 *) enc_label;
-	len[1] = os_strlen(enc_label);
-	sha256_vector(2, addr, len, hash);
-	os_memcpy(wps->mgmt_enc_key_id, hash, WPS_MGMT_KEY_ID_LEN);
-
-	wpa_hexdump_key(MSG_DEBUG, "WPS: MgmtAuthKey",
-			wps->mgmt_auth_key, WPS_MGMTAUTHKEY_LEN);
-	wpa_hexdump(MSG_DEBUG, "WPS: MgmtAuthKeyID",
-		    wps->mgmt_auth_key_id, WPS_MGMT_KEY_ID_LEN);
-	wpa_hexdump_key(MSG_DEBUG, "WPS: MgmtEncKey",
-			wps->mgmt_enc_key, WPS_MGMTENCKEY_LEN);
-	wpa_hexdump(MSG_DEBUG, "WPS: MgmtEncKeyID",
-		    wps->mgmt_enc_key_id, WPS_MGMT_KEY_ID_LEN);
-
-	return 0;
-}
-
-
 void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
 		    size_t dev_passwd_len)
 {
@@ -335,3 +285,21 @@
 	data.pwd_auth_fail.part = part;
 	wps->event_cb(wps->cb_ctx, WPS_EV_PWD_AUTH_FAIL, &data);
 }
+
+
+void wps_pbc_overlap_event(struct wps_context *wps)
+{
+	if (wps->event_cb == NULL)
+		return;
+
+	wps->event_cb(wps->cb_ctx, WPS_EV_PBC_OVERLAP, NULL);
+}
+
+
+void wps_pbc_timeout_event(struct wps_context *wps)
+{
+	if (wps->event_cb == NULL)
+		return;
+
+	wps->event_cb(wps->cb_ctx, WPS_EV_PBC_TIMEOUT, NULL);
+}

Modified: hostapd/trunk/src/wps/wps_enrollee.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_enrollee.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_enrollee.c (original)
+++ hostapd/trunk/src/wps/wps_enrollee.c Thu Feb 11 04:49:20 2010
@@ -521,10 +521,6 @@
 	if (wps_derive_keys(wps) < 0)
 		return -1;
 
-	if (wps->request_type == WPS_REQ_WLAN_MANAGER_REGISTRAR &&
-	    wps_derive_mgmt_keys(wps) < 0)
-		return -1;
-
 	return 0;
 }
 
@@ -650,6 +646,21 @@
 	    wps_process_cred(&attr, &wps->cred))
 		return -1;
 
+	if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
+	    0) {
+		wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
+			   MACSTR ") does not match with own address (" MACSTR
+			   ")", MAC2STR(wps->cred.mac_addr),
+			   MAC2STR(wps->wps->dev.mac_addr));
+		/*
+		 * In theory, this could be consider fatal error, but there are
+		 * number of deployed implementations using other address here
+		 * due to unclarity in the specification. For interoperability
+		 * reasons, allow this to be processed since we do not really
+		 * use the MAC Address information for anything.
+		 */
+	}
+
 	if (wps->wps->cred_cb) {
 		wps->cred.cred_attr = cred - 4;
 		wps->cred.cred_attr_len = cred_len + 4;
@@ -699,6 +710,21 @@
 
 	wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
 		   "Registrar");
+
+	if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
+	    0) {
+		wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
+			   MACSTR ") does not match with own address (" MACSTR
+			   ")", MAC2STR(cred.mac_addr),
+			   MAC2STR(wps->wps->dev.mac_addr));
+		/*
+		 * In theory, this could be consider fatal error, but there are
+		 * number of deployed implementations using other address here
+		 * due to unclarity in the specification. For interoperability
+		 * reasons, allow this to be processed since we do not really
+		 * use the MAC Address information for anything.
+		 */
+	}
 
 	if (wps->wps->cred_cb) {
 		cred.cred_attr = wpabuf_head(attrs);
@@ -1159,6 +1185,17 @@
 		   "op_code=%d)",
 		   (unsigned long) wpabuf_len(msg), op_code);
 
+	if (op_code == WSC_UPnP) {
+		/* Determine the OpCode based on message type attribute */
+		struct wps_parse_attr attr;
+		if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
+			if (*attr.msg_type == WPS_WSC_ACK)
+				op_code = WSC_ACK;
+			else if (*attr.msg_type == WPS_WSC_NACK)
+				op_code = WSC_NACK;
+		}
+	}
+
 	switch (op_code) {
 	case WSC_MSG:
 	case WSC_UPnP:

Modified: hostapd/trunk/src/wps/wps_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_i.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_i.h (original)
+++ hostapd/trunk/src/wps/wps_i.h Thu Feb 11 04:49:20 2010
@@ -62,10 +62,6 @@
 	u8 authkey[WPS_AUTHKEY_LEN];
 	u8 keywrapkey[WPS_KEYWRAPKEY_LEN];
 	u8 emsk[WPS_EMSK_LEN];
-	u8 mgmt_auth_key[WPS_MGMTAUTHKEY_LEN];
-	u8 mgmt_auth_key_id[WPS_MGMT_KEY_ID_LEN];
-	u8 mgmt_enc_key[WPS_MGMTENCKEY_LEN];
-	u8 mgmt_enc_key_id[WPS_MGMT_KEY_ID_LEN];
 
 	struct wpabuf *last_msg;
 
@@ -146,6 +142,7 @@
 	const u8 *selected_registrar; /* 1 octet (Bool) */
 	const u8 *request_type; /* 1 octet */
 	const u8 *response_type; /* 1 octet */
+	const u8 *ap_setup_locked; /* 1 octet */
 
 	/* variable length fields */
 	const u8 *manufacturer;
@@ -182,7 +179,6 @@
 void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
 	     const char *label, u8 *res, size_t res_len);
 int wps_derive_keys(struct wps_data *wps);
-int wps_derive_mgmt_keys(struct wps_data *wps);
 void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
 		    size_t dev_passwd_len);
 struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
@@ -190,6 +186,8 @@
 void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg);
 void wps_success_event(struct wps_context *wps);
 void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
+void wps_pbc_overlap_event(struct wps_context *wps);
+void wps_pbc_timeout_event(struct wps_context *wps);
 
 /* wps_attr_parse.c */
 int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);

Modified: hostapd/trunk/src/wps/wps_registrar.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_registrar.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_registrar.c (original)
+++ hostapd/trunk/src/wps/wps_registrar.c Thu Feb 11 04:49:20 2010
@@ -23,6 +23,7 @@
 #include "wps_dev_attr.h"
 #include "wps_upnp.h"
 
+#define WPS_WORKAROUNDS
 
 struct wps_uuid_pin {
 	struct wps_uuid_pin *next;
@@ -30,7 +31,10 @@
 	int wildcard_uuid;
 	u8 *pin;
 	size_t pin_len;
-	int locked;
+#define PIN_LOCKED BIT(0)
+#define PIN_EXPIRES BIT(1)
+	int flags;
+	struct os_time expiration;
 };
 
 
@@ -99,6 +103,8 @@
 	int sel_reg_dev_password_id_override;
 	int sel_reg_config_methods_override;
 	int static_wep_only;
+
+	int force_pbc_overlap;
 };
 
 
@@ -411,10 +417,11 @@
  * @uuid: UUID-E or %NULL for wildcard (any UUID)
  * @pin: PIN (Device Password)
  * @pin_len: Length of pin in octets
+ * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
  * Returns: 0 on success, -1 on failure
  */
 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
-			  const u8 *pin, size_t pin_len)
+			  const u8 *pin, size_t pin_len, int timeout)
 {
 	struct wps_uuid_pin *p;
 
@@ -433,17 +440,56 @@
 	os_memcpy(p->pin, pin, pin_len);
 	p->pin_len = pin_len;
 
+	if (timeout) {
+		p->flags |= PIN_EXPIRES;
+		os_get_time(&p->expiration);
+		p->expiration.sec += timeout;
+	}
+
 	p->next = reg->pins;
 	reg->pins = p;
 
-	wpa_printf(MSG_DEBUG, "WPS: A new PIN configured");
+	wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
+		   timeout);
 	wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
 	wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
 	reg->selected_registrar = 1;
 	reg->pbc = 0;
 	wps_set_ie(reg);
-
-	return 0;
+	eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
+	eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
+			       wps_registrar_set_selected_timeout,
+			       reg, NULL);
+
+	return 0;
+}
+
+
+static void wps_registrar_expire_pins(struct wps_registrar *reg)
+{
+	struct wps_uuid_pin *pin, *prev, *del;
+	struct os_time now;
+
+	os_get_time(&now);
+	prev = NULL;
+	pin = reg->pins;
+	while (pin) {
+		if ((pin->flags & PIN_EXPIRES) &&
+		    os_time_before(&pin->expiration, &now)) {
+			if (prev == NULL)
+				reg->pins = pin->next;
+			else
+				prev->next = pin->next;
+			del = pin;
+			pin = pin->next;
+			wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
+				    del->uuid, WPS_UUID_LEN);
+			wps_free_pin(del);
+			continue;
+		}
+		prev = pin;
+		pin = pin->next;
+	}
 }
 
 
@@ -483,6 +529,8 @@
 {
 	struct wps_uuid_pin *pin;
 
+	wps_registrar_expire_pins(reg);
+
 	pin = reg->pins;
 	while (pin) {
 		if (!pin->wildcard_uuid &&
@@ -514,13 +562,13 @@
 	 * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
 	 * that could otherwise avoid PIN invalidations.
 	 */
-	if (pin->locked) {
+	if (pin->flags & PIN_LOCKED) {
 		wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
 			   "allow concurrent re-use");
 		return NULL;
 	}
 	*pin_len = pin->pin_len;
-	pin->locked = 1;
+	pin->flags |= PIN_LOCKED;
 	return pin->pin;
 }
 
@@ -547,7 +595,7 @@
 					   "wildcard PIN");
 				return wps_registrar_invalidate_pin(reg, uuid);
 			}
-			pin->locked = 0;
+			pin->flags &= ~PIN_LOCKED;
 			return 0;
 		}
 		pin = pin->next;
@@ -570,6 +618,7 @@
 	struct wps_registrar *reg = eloop_ctx;
 
 	wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
+	wps_pbc_timeout_event(reg->wps);
 	wps_registrar_stop_pbc(reg);
 }
 
@@ -588,9 +637,11 @@
 	if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
 		wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
 			   "mode");
+		wps_pbc_overlap_event(reg->wps);
 		return -1;
 	}
 	wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
+	reg->force_pbc_overlap = 0;
 	reg->selected_registrar = 1;
 	reg->pbc = 1;
 	wps_set_ie(reg);
@@ -607,6 +658,14 @@
 	wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
 	eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
 	wps_registrar_stop_pbc(reg);
+}
+
+static void wps_registrar_pin_completed(struct wps_registrar *reg)
+{
+	wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
+	eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
+	reg->selected_registrar = 0;
+	wps_set_ie(reg);
 }
 
 
@@ -650,8 +709,18 @@
 
 	wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
 		   MACSTR, MAC2STR(addr));
+	if (attr.uuid_e == NULL) {
+		wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No "
+			   "UUID-E included");
+		return;
+	}
 
 	wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
+	if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
+		wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
+		reg->force_pbc_overlap = 1;
+		wps_pbc_overlap_event(reg->wps);
+	}
 }
 
 
@@ -1057,8 +1126,10 @@
 		}
 	}
 	wps->cred.encr_type = wps->encr_type;
-	/* Set MAC address in the Credential to be the AP's address (BSSID) */
-	os_memcpy(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN);
+	/*
+	 * Set MAC address in the Credential to be the Enrollee's MAC address
+	 */
+	os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
 
 	if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
 	    !wps->wps->registrar->disable_auto_conf) {
@@ -1183,14 +1254,15 @@
 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
 {
 	struct wpabuf *msg;
-	u16 err = WPS_CFG_NO_ERROR;
+	u16 err = wps->config_error;
 
 	wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
 	msg = wpabuf_alloc(1000);
 	if (msg == NULL)
 		return NULL;
 
-	if (wps->wps->ap && wps->wps->ap_setup_locked)
+	if (wps->wps->ap && wps->wps->ap_setup_locked &&
+	    err == WPS_CFG_NO_ERROR)
 		err = WPS_CFG_SETUP_LOCKED;
 
 	if (wps_build_version(msg) ||
@@ -1392,8 +1464,18 @@
 			else
 				wps->wps->upnp_msgs = NULL;
 			msg = p->msg;
+			switch (p->type) {
+			case WPS_WSC_ACK:
+				*op_code = WSC_ACK;
+				break;
+			case WPS_WSC_NACK:
+				*op_code = WSC_NACK;
+				break;
+			default:
+				*op_code = WSC_MSG;
+				break;
+			}
 			os_free(p);
-			*op_code = WSC_MSG;
 			if (wps->ext_reg == 0)
 				wps->ext_reg = 1;
 			return msg;
@@ -1678,7 +1760,21 @@
 		wpa_printf(MSG_DEBUG, "WPS: No match in supported "
 			   "authentication types (own 0x%x Enrollee 0x%x)",
 			   wps->wps->auth_types, auth_types);
-		return -1;
+#ifdef WPS_WORKAROUNDS
+		/*
+		 * Some deployed implementations seem to advertise incorrect
+		 * information in this attribute. For example, Linksys WRT350N
+		 * seems to have a byteorder bug that breaks this negotiation.
+		 * In order to interoperate with existing implementations,
+		 * assume that the Enrollee supports everything we do.
+		 */
+		wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
+			   "does not advertise supported authentication types "
+			   "correctly");
+		wps->auth_type = wps->wps->auth_types;
+#else /* WPS_WORKAROUNDS */
+		return -1;
+#endif /* WPS_WORKAROUNDS */
 	}
 
 	return 0;
@@ -1702,8 +1798,23 @@
 	wps->encr_type = wps->wps->encr_types & encr_types;
 	if (wps->encr_type == 0) {
 		wpa_printf(MSG_DEBUG, "WPS: No match in supported "
-			   "encryption types");
-		return -1;
+			   "encryption types (own 0x%x Enrollee 0x%x)",
+			   wps->wps->encr_types, encr_types);
+#ifdef WPS_WORKAROUNDS
+		/*
+		 * Some deployed implementations seem to advertise incorrect
+		 * information in this attribute. For example, Linksys WRT350N
+		 * seems to have a byteorder bug that breaks this negotiation.
+		 * In order to interoperate with existing implementations,
+		 * assume that the Enrollee supports everything we do.
+		 */
+		wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
+			   "does not advertise supported encryption types "
+			   "correctly");
+		wps->encr_type = wps->wps->encr_types;
+#else /* WPS_WORKAROUNDS */
+		return -1;
+#endif /* WPS_WORKAROUNDS */
 	}
 
 	return 0;
@@ -1830,11 +1941,15 @@
 	}
 
 	if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
-		if (wps_registrar_pbc_overlap(wps->wps->registrar,
+		if (wps->wps->registrar->force_pbc_overlap ||
+		    wps_registrar_pbc_overlap(wps->wps->registrar,
 					      wps->mac_addr_e, wps->uuid_e)) {
 			wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
 				   "negotiation");
 			wps->state = SEND_M2D;
+			wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
+			wps_pbc_overlap_event(wps->wps);
+			wps->wps->registrar->force_pbc_overlap = 1;
 			return WPS_CONTINUE;
 		}
 		wps_registrar_add_pbc_session(wps->wps->registrar,
@@ -1857,6 +1972,14 @@
 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
 			   "receiving M3", wps->state);
 		wps->state = SEND_WSC_NACK;
+		return WPS_CONTINUE;
+	}
+
+	if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
+		wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
+			   "session overlap");
+		wps->state = SEND_WSC_NACK;
+		wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
 		return WPS_CONTINUE;
 	}
 
@@ -1886,6 +2009,14 @@
 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
 			   "receiving M5", wps->state);
 		wps->state = SEND_WSC_NACK;
+		return WPS_CONTINUE;
+	}
+
+	if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
+		wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
+			   "session overlap");
+		wps->state = SEND_WSC_NACK;
+		wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
 		return WPS_CONTINUE;
 	}
 
@@ -1920,6 +2051,28 @@
 }
 
 
+static void wps_sta_cred_cb(struct wps_data *wps)
+{
+	/*
+	 * Update credential to only include a single authentication and
+	 * encryption type in case the AP configuration includes more than one
+	 * option.
+	 */
+	if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
+		wps->cred.auth_type = WPS_AUTH_WPA2PSK;
+	else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
+		wps->cred.auth_type = WPS_AUTH_WPAPSK;
+	if (wps->cred.encr_type & WPS_ENCR_AES)
+		wps->cred.encr_type = WPS_ENCR_AES;
+	else if (wps->cred.encr_type & WPS_ENCR_TKIP)
+		wps->cred.encr_type = WPS_ENCR_TKIP;
+	wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
+		   "AP configuration");
+	if (wps->wps->cred_cb)
+		wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
+}
+
+
 static int wps_process_ap_settings_r(struct wps_data *wps,
 				     struct wps_parse_attr *attr)
 {
@@ -1932,12 +2085,21 @@
 
 	wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
 
+#if 0
 	/*
 	 * TODO: Provide access to AP settings and allow changes before sending
 	 * out M8. For now, just copy the settings unchanged into M8.
 	 */
 
 	return 0;
+#else
+	/*
+	 * For now, use the AP PIN only to receive the current AP settings,
+	 * not to reconfigure the AP.
+	 */
+	wps_sta_cred_cb(wps);
+	return 1;
+#endif
 }
 
 
@@ -1954,6 +2116,14 @@
 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
 			   "receiving M7", wps->state);
 		wps->state = SEND_WSC_NACK;
+		return WPS_CONTINUE;
+	}
+
+	if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
+		wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
+			   "session overlap");
+		wps->state = SEND_WSC_NACK;
+		wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
 		return WPS_CONTINUE;
 	}
 
@@ -2305,12 +2475,8 @@
 		wps->new_psk = NULL;
 	}
 
-	if (!wps->wps->ap) {
-		wpa_printf(MSG_DEBUG, "WPS: Update local configuration based "
-			   "on the modified AP configuration");
-		if (wps->wps->cred_cb)
-			wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
-	}
+	if (!wps->wps->ap)
+		wps_sta_cred_cb(wps);
 
 	if (wps->new_psk) {
 		if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
@@ -2328,6 +2494,8 @@
 		wps_registrar_remove_pbc_session(wps->wps->registrar,
 						 wps->mac_addr_e, wps->uuid_e);
 		wps_registrar_pbc_completed(wps->wps->registrar);
+	} else {
+		wps_registrar_pin_completed(wps->wps->registrar);
 	}
 
 	wps_success_event(wps->wps);
@@ -2357,7 +2525,8 @@
 		wps_registrar_free_pending_m2(wps->wps);
 	if (wps->wps->wps_upnp && wps->ext_reg &&
 	    wps->wps->upnp_msgs == NULL &&
-	    (op_code == WSC_MSG || op_code == WSC_Done)) {
+	    (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
+	{
 		struct wps_parse_attr attr;
 		int type;
 		if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)

Modified: hostapd/trunk/src/wps/wps_upnp.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp.c (original)
+++ hostapd/trunk/src/wps/wps_upnp.c Thu Feb 11 04:49:20 2010
@@ -47,9 +47,6 @@
  * -- Needs renaming with module prefix to avoid polluting the debugger
  * namespace and causing possible collisions with other static fncs
  * and structure declarations when using the debugger.
- * -- Just what should be in the first event message sent after subscription
- * for the WLANEvent field? If i pass it empty, Vista replies with OK
- * but apparently barfs on the message.
  * -- The http error code generation is pretty bogus, hopefully noone cares.
  *
  * Author: Ted Merrill, Atheros Communications, based upon earlier work
@@ -641,6 +638,27 @@
 }
 
 
+static struct wpabuf * build_fake_wsc_ack(void)
+{
+	struct wpabuf *msg = wpabuf_alloc(100);
+	if (msg == NULL)
+		return NULL;
+	wpabuf_put_u8(msg, UPNP_WPS_WLANEVENT_TYPE_EAP);
+	wpabuf_put_str(msg, "00:00:00:00:00:00");
+	wps_build_version(msg);
+	wps_build_msg_type(msg, WPS_WSC_ACK);
+	/* Enrollee Nonce */
+	wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE);
+	wpabuf_put_be16(msg, WPS_NONCE_LEN);
+	wpabuf_put(msg, WPS_NONCE_LEN);
+	/* Registrar Nonce */
+	wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
+	wpabuf_put_be16(msg, WPS_NONCE_LEN);
+	wpabuf_put(msg, WPS_NONCE_LEN);
+	return msg;
+}
+
+
 /* subscription_first_event -- send format/queue event that is automatically
  * sent on a new subscription.
  */
@@ -665,6 +683,28 @@
 	const char *tail = "</e:propertyset>\n";
 	char txt[10];
 
+	if (s->sm->wlanevent == NULL) {
+		/*
+		 * There has been no events before the subscription. However,
+		 * UPnP device architecture specification requires all the
+		 * evented variables to be included, so generate a dummy event
+		 * for this particular case using a WSC_ACK and all-zeros
+		 * nonces. The ER (UPnP control point) will ignore this, but at
+		 * least it will learn that WLANEvent variable will be used in
+		 * event notifications in the future.
+		 */
+		struct wpabuf *msg;
+		wpa_printf(MSG_DEBUG, "WPS UPnP: Use a fake WSC_ACK as the "
+			   "initial WLANEvent");
+		msg = build_fake_wsc_ack();
+		if (msg) {
+			s->sm->wlanevent = (char *)
+				base64_encode(wpabuf_head(msg),
+					      wpabuf_len(msg), NULL);
+			wpabuf_free(msg);
+		}
+	}
+
 	wlan_event = s->sm->wlanevent;
 	if (wlan_event == NULL || *wlan_event == '\0') {
 		wpa_printf(MSG_DEBUG, "WPS UPnP: WLANEvent not known for "
@@ -694,13 +734,13 @@
 
 
 /**
- * subscription_start - Rremember a UPnP control point to send events to.
+ * subscription_start - Remember a UPnP control point to send events to.
  * @sm: WPS UPnP state machine from upnp_wps_device_init()
- * @callback_urls: malloc' mem given to the subscription
+ * @callback_urls: Callback URLs
  * Returns: %NULL on error, or pointer to new subscription structure.
  */
 struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
-					 char *callback_urls)
+					 const char *callback_urls)
 {
 	struct subscription *s;
 	time_t now = time(NULL);
@@ -740,7 +780,6 @@
 	}
 	wpa_printf(MSG_DEBUG, "WPS UPnP: Subscription %p started with %s",
 		   s, callback_urls);
-	os_free(callback_urls);
 	/* Schedule sending this */
 	event_send_all_later(sm);
 	return s;
@@ -967,8 +1006,7 @@
 		subscription_destroy(s);
 	}
 
-	advertisement_state_machine_stop(sm);
-	/* TODO: send byebye notifications */
+	advertisement_state_machine_stop(sm, 1);
 
 	event_send_stop_all(sm);
 	os_free(sm->wlanevent);

Modified: hostapd/trunk/src/wps/wps_upnp_event.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp_event.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp_event.c (original)
+++ hostapd/trunk/src/wps/wps_upnp_event.c Thu Feb 11 04:49:20 2010
@@ -89,7 +89,7 @@
 /* event_delete -- delete single unqueued event
  * (be sure to dequeue first if need be)
  */
-void event_delete(struct wps_event_ *e)
+static void event_delete(struct wps_event_ *e)
 {
 	event_clean(e);
 	wpabuf_free(e->data);
@@ -432,7 +432,7 @@
 
 
 /* event_send_all_later_handler -- actually send events as needed */
-void event_send_all_later_handler(void *eloop_data, void *user_ctx)
+static void event_send_all_later_handler(void *eloop_data, void *user_ctx)
 {
 	struct upnp_wps_device_sm *sm = user_ctx;
 	struct subscription *s;

Modified: hostapd/trunk/src/wps/wps_upnp_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp_i.h?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp_i.h (original)
+++ hostapd/trunk/src/wps/wps_upnp_i.h Thu Feb 11 04:49:20 2010
@@ -160,7 +160,7 @@
 /* wps_upnp.c */
 void format_date(struct wpabuf *buf);
 struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
-					 char *callback_urls);
+					 const char *callback_urls);
 struct subscription * subscription_renew(struct upnp_wps_device_sm *sm,
 					 const u8 uuid[UUID_LEN]);
 void subscription_unlink(struct subscription *s);
@@ -172,7 +172,8 @@
 /* wps_upnp_ssdp.c */
 void msearchreply_state_machine_stop(struct advertisement_state_machine *a);
 int advertisement_state_machine_start(struct upnp_wps_device_sm *sm);
-void advertisement_state_machine_stop(struct upnp_wps_device_sm *sm);
+void advertisement_state_machine_stop(struct upnp_wps_device_sm *sm,
+				      int send_byebye);
 void ssdp_listener_stop(struct upnp_wps_device_sm *sm);
 int ssdp_listener_start(struct upnp_wps_device_sm *sm);
 int add_ssdp_network(char *net_if);
@@ -185,7 +186,6 @@
 
 /* wps_upnp_event.c */
 int event_add(struct subscription *s, const struct wpabuf *data);
-void event_delete(struct wps_event_ *e);
 void event_delete_all(struct subscription *s);
 void event_send_all_later(struct upnp_wps_device_sm *sm);
 void event_send_stop_all(struct upnp_wps_device_sm *sm);

Modified: hostapd/trunk/src/wps/wps_upnp_ssdp.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp_ssdp.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp_ssdp.c (original)
+++ hostapd/trunk/src/wps/wps_upnp_ssdp.c Thu Feb 11 04:49:20 2010
@@ -229,10 +229,41 @@
 /**
  * advertisement_state_machine_stop - Stop SSDP advertisements
  * @sm: WPS UPnP state machine from upnp_wps_device_init()
- */
-void advertisement_state_machine_stop(struct upnp_wps_device_sm *sm)
-{
+ * @send_byebye: Send byebye advertisement messages immediately
+ */
+void advertisement_state_machine_stop(struct upnp_wps_device_sm *sm,
+				      int send_byebye)
+{
+	struct advertisement_state_machine *a = &sm->advertisement;
+	int islast = 0;
+	struct wpabuf *msg;
+	struct sockaddr_in dest;
+
 	eloop_cancel_timeout(advertisement_state_machine_handler, NULL, sm);
+	if (!send_byebye || sm->multicast_sd < 0)
+		return;
+
+	a->type = ADVERTISE_DOWN;
+	a->state = 0;
+	a->sm = sm;
+
+	os_memset(&dest, 0, sizeof(dest));
+	dest.sin_family = AF_INET;
+	dest.sin_addr.s_addr = inet_addr(UPNP_MULTICAST_ADDRESS);
+	dest.sin_port = htons(UPNP_MULTICAST_PORT);
+
+	while (!islast) {
+		msg = next_advertisement(a, &islast);
+		if (msg == NULL)
+			break;
+		if (sendto(sm->multicast_sd, wpabuf_head(msg), wpabuf_len(msg),
+			   0, (struct sockaddr *) &dest, sizeof(dest)) < 0) {
+			wpa_printf(MSG_INFO, "WPS UPnP: Advertisement sendto "
+				   "failed: %d (%s)", errno, strerror(errno));
+		}
+		wpabuf_free(msg);
+		a->state++;
+	}
 }
 
 
@@ -318,7 +349,7 @@
 	struct advertisement_state_machine *a = &sm->advertisement;
 	int next_timeout_msec;
 
-	advertisement_state_machine_stop(sm);
+	advertisement_state_machine_stop(sm, 0);
 
 	/*
 	 * Start out advertising down, this automatically switches
@@ -461,7 +492,7 @@
 	a->type = MSEARCH_REPLY;
 	a->state = 0;
 	a->sm = sm;
-	os_memcpy(&a->client, client, sizeof(client));
+	os_memcpy(&a->client, client, sizeof(*client));
 	/* Wait time depending on MX value */
 	next_timeout_msec = (1000 * mx * (os_random() & 0xFF)) >> 8;
 	next_timeout_sec = next_timeout_msec / 1000;
@@ -799,11 +830,11 @@
 		goto fail;
 
 	rt.rt_dev = net_if;
-	sin = (struct sockaddr_in *) &rt.rt_dst;
+	sin = aliasing_hide_typecast(&rt.rt_dst, struct sockaddr_in);
 	sin->sin_family = AF_INET;
 	sin->sin_port = 0;
 	sin->sin_addr.s_addr = inet_addr(SSDP_TARGET);
-	sin = (struct sockaddr_in *) &rt.rt_genmask;
+	sin = aliasing_hide_typecast(&rt.rt_genmask, struct sockaddr_in);
 	sin->sin_family = AF_INET;
 	sin->sin_port = 0;
 	sin->sin_addr.s_addr = inet_addr(SSDP_NETMASK);

Modified: hostapd/trunk/src/wps/wps_upnp_web.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp_web.c?rev=1474&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp_web.c (original)
+++ hostapd/trunk/src/wps/wps_upnp_web.c Thu Feb 11 04:49:20 2010
@@ -1578,7 +1578,6 @@
 			ret = HTTP_INTERNAL_SERVER_ERROR;
 			goto error;
 		}
-		callback_urls = NULL;   /* is now owned by subscription */
 	} else {
 		ret = HTTP_PRECONDITION_FAILED;
 		goto error;
@@ -1630,6 +1629,7 @@
 	http_put_empty(buf, ret);
 	send_wpabuf(c->sd, buf);
 	wpabuf_free(buf);
+	os_free(callback_urls);
 }
 
 




More information about the Pkg-wpa-devel mailing list