aboutsummaryrefslogtreecommitdiffstats
path: root/package/hostapd
diff options
context:
space:
mode:
Diffstat (limited to 'package/hostapd')
-rw-r--r--package/hostapd/Makefile60
-rw-r--r--package/hostapd/files/default.config81
-rw-r--r--package/hostapd/files/mini.config83
-rw-r--r--package/hostapd/patches/001-cross_compile_fix.patch36
-rw-r--r--package/hostapd/patches/001-remove-michael-mic.patch18
-rw-r--r--package/hostapd/patches/002-use-nl80211-for-keys.patch112
-rw-r--r--package/hostapd/patches/003-use-nl80211-for-beacons.patch149
-rw-r--r--package/hostapd/patches/004-use-nl80211-for-get-key.patch116
-rw-r--r--package/hostapd/patches/005-pass-full-flags-to-sta-function.patch173
-rw-r--r--package/hostapd/patches/006-use-nl80211-for-sta.patch411
-rw-r--r--package/hostapd/patches/100-madwifi_fixes.patch54
11 files changed, 1141 insertions, 152 deletions
diff --git a/package/hostapd/Makefile b/package/hostapd/Makefile
index 85f42dc6a1..d7910737b6 100644
--- a/package/hostapd/Makefile
+++ b/package/hostapd/Makefile
@@ -9,14 +9,15 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=hostapd
-PKG_VERSION:=0.5.8
+PKG_REV:=03ec0ec5cdb974d51a4a2a566bea4c4568138576
+PKG_VERSION:=20071107_$(PKG_REV)
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://hostap.epitest.fi/releases/
-PKG_MD5SUM:=40416b48cae9c78e5a2452caf214aff3
-
-PKG_BUILD_DEPENDS:=madwifi
+PKG_SOURCE_URL:=git://w1.fi/srv/git/hostap.git
+PKG_SOURCE_SUBDIR:=hostapd-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_BUILD_DEPENDS:=madwifi mac80211
include $(INCLUDE_DIR)/package.mk
@@ -25,7 +26,7 @@ define Package/hostapd/Default
CATEGORY:=Network
TITLE:=IEEE 802.1x Authenticator
URL:=http://hostap.epitest.fi/
- DEPENDS:=@!TARGET_avr32 @!TARGET_etrax
+ DEPENDS:=@!TARGET_avr32 @!TARGET_etrax $(if $(DUMP)$(CONFIG_LINUX_2_6_23),+libnl)
endef
define Package/hostapd
@@ -34,9 +35,9 @@ $(call Package/hostapd/Default)
DEPENDS+= +libopenssl
endef
-define Package/hostapd/conffiles
-/etc/hostapd.conf
-endef
+#define Package/hostapd/conffiles
+#/etc/hostapd.conf
+#endef
define Package/hostapd/description
This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS
@@ -48,9 +49,9 @@ $(call Package/hostapd/Default)
TITLE+= (WPA-PSK only)
endef
-define Package/hostapd-mini/conffiles
-/etc/hostapd.conf
-endef
+#define Package/hostapd-mini/conffiles
+#/etc/hostapd.conf
+#endef
define Package/hostapd-mini/description
This package contains a minimal IEEE 802.1x/WPA/EAP/RADIUS Authenticator
@@ -69,38 +70,31 @@ define Package/hostapd-utils/description
endef
define Build/ConfigureTarget
- $(CP) $(PKG_BUILD_DIR) $(PKG_BUILD_DIR)_$(1)
- $(CP) ./files/$(1).config $(PKG_BUILD_DIR)_$(1)/.config
-ifneq ($(CONFIG_PACKAGE_kmod-madwifi),)
- echo "CONFIG_DRIVER_MADWIFI=y" >> $(PKG_BUILD_DIR)_$(1)/.config
-endif
+ rm -rf $(PKG_BUILD_DIR)/hostapd.$(1)
+ $(CP) $(PKG_BUILD_DIR)/hostapd $(PKG_BUILD_DIR)/hostapd.$(1)
+ $(CP) ./files/$(1).config $(PKG_BUILD_DIR)/hostapd.$(1)/.config
+ [ -d $(STAGING_DIR)/usr/include/mac80211 ] || $(SED) 's,^CONFIG_DRIVER_DEVICESCAPE,#CONFIG_DRIVER_DEVICESCAPE,g' $(PKG_BUILD_DIR)/hostapd.$(1)/.config
+ [ -d $(STAGING_DIR)/usr/include/madwifi ] || $(SED) 's,^CONFIG_DRIVER_MADWIFI,#CONFIG_DRIVER_MADWIFI,g' $(PKG_BUILD_DIR)/hostapd.$(1)/.config
endef
define Build/CompileTarget
- $(MAKE) -C $(PKG_BUILD_DIR)_$(1) \
+ CFLAGS="$(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include/madwifi -I$(STAGING_DIR)/usr/include/mac80211 -I$(STAGING_DIR)/usr/include" \
+ $(MAKE) -C $(PKG_BUILD_DIR)/hostapd.$(1) \
$(TARGET_CONFIGURE_OPTS) \
- OPTFLAGS="$(TARGET_CFLAGS)" \
- CPPFLAGS="$(TARGET_CPPFLAGS) -I$(STAGING_DIR)/usr/include/madwifi" \
- LDFLAGS="$(TARGET_LDFLAGS)" \
+ LIBS="$(TARGET_LDFLAGS) -L$(STAGING_DIR)/usr/lib \
+ $(if $(wildcard $(STAGING_DIR)/usr/include/mac80211/*),-lnl)" \
hostapd hostapd_cli
- $(CP) $(PKG_BUILD_DIR)_$(1)/hostapd_cli $(PKG_BUILD_DIR)/
+ $(CP) $(PKG_BUILD_DIR)/hostapd.$(1)/hostapd_cli $(PKG_BUILD_DIR)/
endef
define Package/InstallTemplate
- if [ \! -f "$(PKG_BUILD_DIR)_$(2)/hostapd" ]; then \
- rm -f $(PKG_BUILD_DIR)/.built; \
- $(MAKE) $(PKG_BUILD_DIR)/.built; \
- fi
$(INSTALL_DIR) $$(1)/lib/wifi
$(INSTALL_DATA) ./files/hostapd.sh $$(1)/lib/wifi/hostapd.sh
- $(INSTALL_DIR) $$(1)/etc
-ifneq ($(CONFIG_PACKAGE_kmod-madwifi),)
- $(INSTALL_CONF) $(PKG_BUILD_DIR)_$(2)/madwifi.conf $$(1)/etc/hostapd.conf
-else
- $(INSTALL_CONF) $(PKG_BUILD_DIR)_$(2)/hostapd.conf $$(1)/etc/hostapd.conf
-endif
+# config is managed through uci
+# $(INSTALL_DIR) $$(1)/etc
+# $(INSTALL_CONF) $(PKG_BUILD_DIR)/hostapd.$(2)/hostapd.conf $$(1)/etc/hostapd.conf
$(INSTALL_DIR) $$(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)_$(2)/hostapd $$(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd.$(2)/hostapd $$(1)/usr/sbin/
endef
define Package/Template
diff --git a/package/hostapd/files/default.config b/package/hostapd/files/default.config
index de27420b9d..700217dada 100644
--- a/package/hostapd/files/default.config
+++ b/package/hostapd/files/default.config
@@ -13,15 +13,29 @@
CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
-#CONFIG_DRIVER_WIRED=y
+CONFIG_DRIVER_WIRED=y
# Driver interface for madwifi driver
-#CONFIG_DRIVER_MADWIFI=y
+CONFIG_DRIVER_MADWIFI=y
#CFLAGS += -I../head # change to reflect local setup; directory for madwifi src
# Driver interface for Prism54 driver
#CONFIG_DRIVER_PRISM54=y
+# Driver interface for drivers using Devicescape IEEE 802.11 stack
+CONFIG_DRIVER_DEVICESCAPE=y
+# Currently, driver_devicescape.c build requires some additional parameters
+# to be able to include some of the kernel header files. Following lines can
+# be used to set these (WIRELESS_DEV must point to the root directory of the
+# wireless-dev.git tree).
+#WIRELESS_DEV=/usr/src/wireless-dev
+#CFLAGS += -I$(WIRELESS_DEV)/net/mac80211
+# driver_devicescape.c requires a rather new libnl, probably not
+# shipped with your distribution yet
+#LIBNL=/usr/src/libnl
+#CFLAGS += -I$(LIBNL)/include
+#LIBS += -L$(LIBNL)/lib
+
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
@@ -33,37 +47,76 @@ CONFIG_IAPP=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
-# Integrated EAP authenticator
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
CONFIG_EAP=y
-# EAP-MD5 for the integrated EAP authenticator
+# EAP-MD5 for the integrated EAP server
CONFIG_EAP_MD5=y
-# EAP-TLS for the integrated EAP authenticator
+# EAP-TLS for the integrated EAP server
CONFIG_EAP_TLS=y
-# EAP-MSCHAPv2 for the integrated EAP authenticator
+# EAP-MSCHAPv2 for the integrated EAP server
CONFIG_EAP_MSCHAPV2=y
-# EAP-PEAP for the integrated EAP authenticator
+# EAP-PEAP for the integrated EAP server
CONFIG_EAP_PEAP=y
-# EAP-PSK for the integrated EAP authenticator
-CONFIG_EAP_PSK=y
-
-# EAP-GTC for the integrated EAP authenticator
+# EAP-GTC for the integrated EAP server
CONFIG_EAP_GTC=y
-# EAP-TTLS for the integrated EAP authenticator
+# EAP-TTLS for the integrated EAP server
CONFIG_EAP_TTLS=y
-# EAP-SIM for the integrated EAP authenticator
+# EAP-SIM for the integrated EAP server
#CONFIG_EAP_SIM=y
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
# RADIUS authentication server. This provides access to the integrated EAP
-# authenticator from external hosts using RADIUS.
+# server from external hosts using RADIUS.
#CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+CONFIG_IPV6=y
+
+# IEEE 802.11r/D4.1 (Fast BSS Transition)
+# This enables an experimental implementation of a draft version of
+# IEEE 802.11r. This draft is still subject to change, so it should be noted
+# that this version may not comply with the final standard.
+#CONFIG_IEEE80211R=y
diff --git a/package/hostapd/files/mini.config b/package/hostapd/files/mini.config
index cfdc485eed..a2f3f62bba 100644
--- a/package/hostapd/files/mini.config
+++ b/package/hostapd/files/mini.config
@@ -13,15 +13,29 @@
CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
-#CONFIG_DRIVER_WIRED=y
+CONFIG_DRIVER_WIRED=y
# Driver interface for madwifi driver
-#CONFIG_DRIVER_MADWIFI=y
+CONFIG_DRIVER_MADWIFI=y
#CFLAGS += -I../head # change to reflect local setup; directory for madwifi src
# Driver interface for Prism54 driver
#CONFIG_DRIVER_PRISM54=y
+# Driver interface for drivers using Devicescape IEEE 802.11 stack
+CONFIG_DRIVER_DEVICESCAPE=y
+# Currently, driver_devicescape.c build requires some additional parameters
+# to be able to include some of the kernel header files. Following lines can
+# be used to set these (WIRELESS_DEV must point to the root directory of the
+# wireless-dev.git tree).
+#WIRELESS_DEV=/usr/src/wireless-dev
+#CFLAGS += -I$(WIRELESS_DEV)/net/mac80211
+# driver_devicescape.c requires a rather new libnl, probably not
+# shipped with your distribution yet
+#LIBNL=/usr/src/libnl
+#CFLAGS += -I$(LIBNL)/include
+#LIBS += -L$(LIBNL)/lib
+
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
@@ -33,37 +47,76 @@ CONFIG_IAPP=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
-# Integrated EAP authenticator
-CONFIG_EAP=y
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
+#CONFIG_EAP=y
-# EAP-MD5 for the integrated EAP authenticator
+# EAP-MD5 for the integrated EAP server
#CONFIG_EAP_MD5=y
-# EAP-TLS for the integrated EAP authenticator
+# EAP-TLS for the integrated EAP server
#CONFIG_EAP_TLS=y
-# EAP-MSCHAPv2 for the integrated EAP authenticator
+# EAP-MSCHAPv2 for the integrated EAP server
#CONFIG_EAP_MSCHAPV2=y
-# EAP-PEAP for the integrated EAP authenticator
+# EAP-PEAP for the integrated EAP server
#CONFIG_EAP_PEAP=y
-# EAP-PSK for the integrated EAP authenticator
-CONFIG_EAP_PSK=y
-
-# EAP-GTC for the integrated EAP authenticator
+# EAP-GTC for the integrated EAP server
#CONFIG_EAP_GTC=y
-# EAP-TTLS for the integrated EAP authenticator
+# EAP-TTLS for the integrated EAP server
#CONFIG_EAP_TTLS=y
-# EAP-SIM for the integrated EAP authenticator
+# EAP-SIM for the integrated EAP server
#CONFIG_EAP_SIM=y
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
#CONFIG_PKCS12=y
# RADIUS authentication server. This provides access to the integrated EAP
-# authenticator from external hosts using RADIUS.
+# server from external hosts using RADIUS.
#CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+#CONFIG_IPV6=y
+
+# IEEE 802.11r/D4.1 (Fast BSS Transition)
+# This enables an experimental implementation of a draft version of
+# IEEE 802.11r. This draft is still subject to change, so it should be noted
+# that this version may not comply with the final standard.
+#CONFIG_IEEE80211R=y
diff --git a/package/hostapd/patches/001-cross_compile_fix.patch b/package/hostapd/patches/001-cross_compile_fix.patch
deleted file mode 100644
index 669264cb64..0000000000
--- a/package/hostapd/patches/001-cross_compile_fix.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-Common subdirectories: hostapd-0.5.2/logwatch and hostapd-0.5.2.new/logwatch
-Index: hostapd-0.5.7/Makefile
-===================================================================
---- hostapd-0.5.7.orig/Makefile 2007-06-04 13:22:31.790022464 +0200
-+++ hostapd-0.5.7/Makefile 2007-06-04 13:22:31.856012432 +0200
-@@ -2,7 +2,7 @@
- DIR_WPA_SUPPLICANT=.
-
- ifndef CFLAGS
--CFLAGS = -MMD -O2 -Wall -g
-+CFLAGS = -MMD $(OPTFLAGS) $(CPPFLAGS)
- endif
-
- # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
-@@ -336,7 +336,7 @@
- for i in $(ALL); do cp $$i /usr/local/bin/$$i; done
-
- hostapd: $(OBJS)
-- $(CC) -o hostapd $(OBJS) $(LIBS)
-+ $(CC) -o hostapd $(OBJS) $(LDFLAGS) $(LIBS)
-
- driver_conf.c: Makefile .config
- rm -f driver_conf.c
-@@ -400,10 +400,10 @@
- endif
-
- nt_password_hash: $(NOBJS)
-- $(CC) -o nt_password_hash $(NOBJS) $(LIBS_n)
-+ $(CC) -o nt_password_hash $(NOBJS) $(LDFLAGS) $(LIBS_n)
-
- hlr_auc_gw: $(HOBJS)
-- $(CC) -o hlr_auc_gw $(HOBJS) $(LIBS_h)
-+ $(CC) -o hlr_auc_gw $(HOBJS) $(LDFLAGS) $(LIBS_h)
-
- clean:
- rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw
diff --git a/package/hostapd/patches/001-remove-michael-mic.patch b/package/hostapd/patches/001-remove-michael-mic.patch
new file mode 100644
index 0000000000..de76c06930
--- /dev/null
+++ b/package/hostapd/patches/001-remove-michael-mic.patch
@@ -0,0 +1,18 @@
+---
+ hostapd/driver_devicescape.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:08.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:12.000000000 +0100
+@@ -1386,10 +1386,10 @@ static void handle_frame(struct hostapd_
+ case ieee80211_msg_wep_frame_unknown_key:
+ ieee802_11_rx_unknown_key(hapd, buf, data_len);
+ return;
+- */
+ case ieee80211_msg_michael_mic_failure:
+ hostapd_michael_mic_failure(hapd, buf, data_len);
+ return;
++ */
+ /*
+ * TODO
+ * We should be telling them to go away. But we don't support that now.
diff --git a/package/hostapd/patches/002-use-nl80211-for-keys.patch b/package/hostapd/patches/002-use-nl80211-for-keys.patch
new file mode 100644
index 0000000000..6b7fe80984
--- /dev/null
+++ b/package/hostapd/patches/002-use-nl80211-for-keys.patch
@@ -0,0 +1,112 @@
+---
+ hostapd/driver_devicescape.c | 93 ++++++++++++++++++++++++++++++-------------
+ 1 file changed, 67 insertions(+), 26 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:12.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:13.000000000 +0100
+@@ -150,38 +150,79 @@ static int i802_set_encryption(const cha
+ size_t key_len, int txkey)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param *param;
+- u8 *buf;
+- size_t blen;
+- int ret = 0;
++ struct nl_msg *msg;
++ int ret = -1;
++ int err = 0;
+
+- blen = sizeof(*param) + key_len;
+- buf = os_zalloc(blen);
+- if (buf == NULL)
+- return -1;
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
+
+- param = (struct prism2_hostapd_param *) buf;
+- param->cmd = PRISM2_SET_ENCRYPTION;
+- if (addr == NULL)
+- memset(param->sta_addr, 0xff, ETH_ALEN);
+- else
+- memcpy(param->sta_addr, addr, ETH_ALEN);
+- os_strlcpy((char *) param->u.crypt.alg, alg,
+- HOSTAP_CRYPT_ALG_NAME_LEN);
+- param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;
+- param->u.crypt.idx = idx;
+- param->u.crypt.key_len = key_len;
+- memcpy(param->u.crypt.key, key, key_len);
++ if (strcmp(alg, "none") == 0) {
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_DEL_KEY, 0);
++ } else {
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_NEW_KEY, 0);
++ NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
++ if (strcmp(alg, "WEP") == 0) {
++ if (key_len == 5)
++ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
++ 0x000FAC01);
++ else
++ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
++ 0x000FAC05);
++ } else if (strcmp(alg, "TKIP") == 0)
++ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02);
++ else if (strcmp(alg, "CCMP") == 0)
++ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);
++ else
++ goto out;
++ }
+
+- if (hostapd_ioctl_iface(iface, drv, param, blen) && errno != ENOENT) {
+- printf("%s: Failed to set encryption to alg '%s' addr " MACSTR
+- " errno=%d\n",
+- iface, alg, MAC2STR(param->sta_addr), errno);
+- ret = -1;
++ if (addr)
++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++ NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ (err = nl_wait_for_ack(drv->nl_handle)) < 0) {
++ if (err != -ENOENT) {
++ err = 0;
++ goto out;
++ }
+ }
+
+- free(buf);
++ if (!txkey) {
++ ret = 0;
++ goto out;
++ }
++
++ nlmsg_free(msg);
++
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
+
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_SET_KEY, 0);
++ NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++ NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ (err = nl_wait_for_ack(drv->nl_handle)) < 0) {
++ if (err != -ENOENT) {
++ err = 0;
++ goto out;
++ }
++ }
++
++ ret = 0;
++
++ out:
++ nla_put_failure:
++ nlmsg_free(msg);
+ return ret;
+ }
+
diff --git a/package/hostapd/patches/003-use-nl80211-for-beacons.patch b/package/hostapd/patches/003-use-nl80211-for-beacons.patch
new file mode 100644
index 0000000000..34fa841d61
--- /dev/null
+++ b/package/hostapd/patches/003-use-nl80211-for-beacons.patch
@@ -0,0 +1,149 @@
+---
+ hostapd/driver_devicescape.c | 111 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 82 insertions(+), 29 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:13.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:13.000000000 +0100
+@@ -68,6 +68,8 @@ struct i802_driver_data {
+ struct nl_handle *nl_handle;
+ struct nl_cache *nl_cache;
+ struct genl_family *nl80211;
++ int dtim_period;
++ unsigned int beacon_set:1;
+ };
+
+
+@@ -908,37 +910,44 @@ static int i802_bss_remove(void *priv, c
+ }
+
+
+-static int i802_set_beacon(const char *ifname, void *priv,
++static int i802_set_beacon(const char *iface, void *priv,
+ u8 *head, size_t head_len,
+ u8 *tail, size_t tail_len)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param *param;
+- int len, ret = 0;
++ struct nl_msg *msg;
++ u8 cmd = NL80211_CMD_NEW_BEACON;
++ int ret = -1;
+
+- param = os_zalloc(sizeof(*param) + head_len + tail_len);
+- if (param == NULL) {
+- printf("Failed to alloc memory for beacon ioctl\n");
+- return -1;
+- }
+- len = (&param->u.beacon.data[0] - (u8 *) param) + head_len + tail_len;
+- param->cmd = PRISM2_HOSTAPD_SET_BEACON;
+- param->u.beacon.head_len = head_len;
+- param->u.beacon.tail_len = tail_len;
+- memcpy(&param->u.beacon.data[0], head, head_len);
+- memcpy(&param->u.beacon.data[0] + head_len, tail, tail_len);
+-
+- if (len < (int) sizeof(*param))
+- len = sizeof(*param);
+- if (hostapd_ioctl_iface(ifname, drv, param, len)) {
+- printf("Could not set beacon data to kernel driver.\n");
+- printf("ifname='%s' head=%p head_len=%d tail=%p tail_len=%d "
+- "cmd=%d\n",
+- ifname, head, head_len, tail, tail_len, param->cmd);
+- ret = -1;
+- }
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
+
+- free(param);
++ if (drv->beacon_set)
++ cmd = NL80211_CMD_SET_BEACON;
++
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, cmd, 0);
++ NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);
++ NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++ NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, 1000);
++
++ if (!drv->dtim_period)
++ drv->dtim_period = 2;
++ NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0)
++ goto out;
++
++ ret = 0;
++
++ drv->beacon_set = 1;
++
++ out:
++ nla_put_failure:
++ nlmsg_free(msg);
+ return ret;
+ }
+
+@@ -985,15 +994,59 @@ static int i802_set_internal_bridge(void
+ static int i802_set_beacon_int(void *priv, int value)
+ {
+ struct i802_driver_data *drv = priv;
+- return hostap_ioctl_prism2param(drv, PRISM2_PARAM_BEACON_INT, value);
++ struct nl_msg *msg;
++ int ret = -1;
++
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
++
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_SET_BEACON, 0);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));
++
++ NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, value);
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0)
++ goto out;
++
++ ret = 0;
++
++ out:
++ nla_put_failure:
++ nlmsg_free(msg);
++ return ret;
+ }
+
+
+-static int i802_set_dtim_period(const char *ifname, void *priv, int value)
++static int i802_set_dtim_period(const char *iface, void *priv, int value)
+ {
+ struct i802_driver_data *drv = priv;
+- return hostap_ioctl_prism2param_iface(ifname, drv,
+- PRISM2_PARAM_DTIM_PERIOD, value);
++ struct nl_msg *msg;
++ int ret = -1;
++
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
++
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_SET_BEACON, 0);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++
++ drv->dtim_period = value;
++ NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0)
++ goto out;
++
++ ret = 0;
++
++ out:
++ nla_put_failure:
++ nlmsg_free(msg);
++ return ret;
+ }
+
+
diff --git a/package/hostapd/patches/004-use-nl80211-for-get-key.patch b/package/hostapd/patches/004-use-nl80211-for-get-key.patch
new file mode 100644
index 0000000000..142c1939d2
--- /dev/null
+++ b/package/hostapd/patches/004-use-nl80211-for-get-key.patch
@@ -0,0 +1,116 @@
+---
+ hostapd/driver_devicescape.c | 96 ++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 76 insertions(+), 20 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:13.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:14.000000000 +0100
+@@ -228,33 +228,89 @@ static int i802_set_encryption(const cha
+ return ret;
+ }
+
++static inline int min_int(int a, int b)
++{
++ if (a<b)
++ return a;
++ return b;
++}
++
++static int get_key_handler(struct nl_msg *msg, void *arg)
++{
++ struct nlattr *tb[NL80211_ATTR_MAX];
++ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
++
++ nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
++ genlmsg_attrlen(gnlh, 0), NULL);
++
++ /*
++ * TODO: validate the key index and mac address!
++ * Otherwise, there's a race condition as soon as
++ * the kernel starts sending key notifications.
++ */
++
++ if (tb[NL80211_ATTR_KEY_SEQ])
++ memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
++ min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
++ return NL_SKIP;
++}
++
++static int ack_wait_handler(struct nl_msg *msg, void *arg)
++{
++ int *finished = arg;
++
++ *finished = 1;
++ return NL_STOP;
++}
+
+ static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
+ int idx, u8 *seq)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param *param;
+- size_t param_len;
+- int ret;
++ struct nl_msg *msg;
++ struct nl_cb *cb = NULL;
++ int ret = -1;
++ int err = 0;
++ int finished = 0;
+
+- param_len = sizeof(struct prism2_hostapd_param) + 32;
+- param = os_zalloc(param_len);
+- if (param == NULL)
+- return -1;
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
+
+- param->cmd = PRISM2_GET_ENCRYPTION;
+- if (addr == NULL)
+- memset(param->sta_addr, 0xff, ETH_ALEN);
+- else
+- memcpy(param->sta_addr, addr, ETH_ALEN);
+- param->u.crypt.idx = idx;
+-
+- ret = hostapd_ioctl_iface(iface, drv, param, param_len);
+- if (ret == 0) {
+- memcpy(seq, param->u.crypt.seq_counter,
+- HOSTAP_SEQ_COUNTER_SIZE);
+- }
+- free(param);
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_GET_KEY, 0);
++
++ if (addr)
++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++ NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++
++ cb = nl_cb_alloc(NL_CB_CUSTOM);
++ if (!cb)
++ goto out;
++
++ memset(seq, 0, 6);
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0)
++ goto out;
++
++ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_key_handler, seq);
++ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
++
++ err = nl_recvmsgs(drv->nl_handle, cb);
++
++ if (!finished)
++ err = nl_wait_for_ack(drv->nl_handle);
++
++ if (err < 0)
++ goto out;
++
++ ret = 0;
++
++ out:
++ nl_cb_put(cb);
++ nla_put_failure:
++ nlmsg_free(msg);
+ return ret;
+ }
+
diff --git a/package/hostapd/patches/005-pass-full-flags-to-sta-function.patch b/package/hostapd/patches/005-pass-full-flags-to-sta-function.patch
new file mode 100644
index 0000000000..11c8c5fd46
--- /dev/null
+++ b/package/hostapd/patches/005-pass-full-flags-to-sta-function.patch
@@ -0,0 +1,173 @@
+---
+ hostapd/driver.h | 8 ++++----
+ hostapd/driver_bsd.c | 3 ++-
+ hostapd/driver_devicescape.c | 6 +++---
+ hostapd/driver_hostap.c | 4 ++--
+ hostapd/driver_madwifi.c | 3 ++-
+ hostapd/driver_prism54.c | 3 ++-
+ hostapd/ieee802_11.c | 4 ++--
+ hostapd/ieee802_1x.c | 4 ++--
+ hostapd/wme.c | 6 ++++--
+ 9 files changed, 23 insertions(+), 18 deletions(-)
+
+--- hostap.orig/hostapd/driver.h 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver.h 2007-11-09 13:41:15.000000000 +0100
+@@ -92,7 +92,7 @@ struct wpa_driver_ops {
+ int (*get_retry)(void *priv, int *short_retry, int *long_retry);
+
+ int (*sta_set_flags)(void *priv, const u8 *addr,
+- int flags_or, int flags_and);
++ int total_flags, int flags_or, int flags_and);
+ int (*set_rate_sets)(void *priv, int *supp_rates, int *basic_rates,
+ int mode);
+ int (*set_channel_flag)(void *priv, int mode, int chan, int flag,
+@@ -427,12 +427,12 @@ hostapd_get_retry(struct hostapd_data *h
+
+ static inline int
+ hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
+- int flags_or, int flags_and)
++ int total_flags, int flags_or, int flags_and)
+ {
+ if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
+ return 0;
+- return hapd->driver->sta_set_flags(hapd->drv_priv, addr, flags_or,
+- flags_and);
++ return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
++ flags_or, flags_and);
+ }
+
+ static inline int
+--- hostap.orig/hostapd/driver_bsd.c 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_bsd.c 2007-11-09 13:41:15.000000000 +0100
+@@ -322,7 +322,8 @@ bsd_set_sta_authorized(void *priv, const
+ }
+
+ static int
+-bsd_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and)
++bsd_sta_set_flags(void *priv, const u8 *addr, int total_flags, int flags_or,
++ int flags_and)
+ {
+ /* For now, only support setting Authorized flag */
+ if (flags_or & WLAN_STA_AUTHORIZED)
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:14.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:15.000000000 +0100
+@@ -76,7 +76,7 @@ struct i802_driver_data {
+ #define HAPD_DECL struct hostapd_data *hapd = iface->bss[0]
+
+ static int i802_sta_set_flags(void *priv, const u8 *addr,
+- int flags_or, int flags_and);
++ int total_flags, int flags_or, int flags_and);
+
+
+ static int hostapd_set_iface_flags(struct i802_driver_data *drv, int dev_up)
+@@ -765,7 +765,7 @@ static int i802_sta_remove(void *priv, c
+ struct i802_driver_data *drv = priv;
+ struct prism2_hostapd_param param;
+
+- i802_sta_set_flags(drv, addr, 0, ~WLAN_STA_AUTHORIZED);
++ i802_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED);
+
+ memset(&param, 0, sizeof(param));
+ param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+@@ -777,7 +777,7 @@ static int i802_sta_remove(void *priv, c
+
+
+ static int i802_sta_set_flags(void *priv, const u8 *addr,
+- int flags_or, int flags_and)
++ int total_flags, int flags_or, int flags_and)
+ {
+ struct i802_driver_data *drv = priv;
+ struct prism2_hostapd_param param;
+--- hostap.orig/hostapd/driver_hostap.c 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_hostap.c 2007-11-09 13:41:15.000000000 +0100
+@@ -374,7 +374,7 @@ static int hostap_send_eapol(void *priv,
+
+
+ static int hostap_sta_set_flags(void *priv, const u8 *addr,
+- int flags_or, int flags_and)
++ int total_flags, int flags_or, int flags_and)
+ {
+ struct hostap_driver_data *drv = priv;
+ struct prism2_hostapd_param param;
+@@ -694,7 +694,7 @@ static int hostap_sta_remove(void *priv,
+ struct hostap_driver_data *drv = priv;
+ struct prism2_hostapd_param param;
+
+- hostap_sta_set_flags(drv, addr, 0, ~WLAN_STA_AUTHORIZED);
++ hostap_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED);
+
+ memset(&param, 0, sizeof(param));
+ param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+--- hostap.orig/hostapd/driver_madwifi.c 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_madwifi.c 2007-11-09 13:41:15.000000000 +0100
+@@ -410,7 +410,8 @@ madwifi_set_sta_authorized(void *priv, c
+ }
+
+ static int
+-madwifi_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and)
++madwifi_sta_set_flags(void *priv, const u8 *addr, int total_flags,
++ int flags_or, int flags_and)
+ {
+ /* For now, only support setting Authorized flag */
+ if (flags_or & WLAN_STA_AUTHORIZED)
+--- hostap.orig/hostapd/driver_prism54.c 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_prism54.c 2007-11-09 13:41:15.000000000 +0100
+@@ -187,7 +187,8 @@ static int prism54_set_sta_authorized(vo
+
+
+ static int
+-prism54_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and)
++prism54_sta_set_flags(void *priv, const u8 *addr, int total_flags,
++ int flags_or, int flags_and)
+ {
+ /* For now, only support setting Authorized flag */
+ if (flags_or & WLAN_STA_AUTHORIZED)
+--- hostap.orig/hostapd/ieee802_11.c 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/ieee802_11.c 2007-11-09 13:41:15.000000000 +0100
+@@ -1625,10 +1625,10 @@ static void handle_assoc_cb(struct hosta
+ ap_sta_bind_vlan(hapd, sta, 0);
+ }
+ if (sta->flags & WLAN_STA_SHORT_PREAMBLE) {
+- hostapd_sta_set_flags(hapd, sta->addr,
++ hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+ WLAN_STA_SHORT_PREAMBLE, ~0);
+ } else {
+- hostapd_sta_set_flags(hapd, sta->addr,
++ hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+ 0, ~WLAN_STA_SHORT_PREAMBLE);
+ }
+
+--- hostap.orig/hostapd/ieee802_1x.c 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/ieee802_1x.c 2007-11-09 13:41:15.000000000 +0100
+@@ -94,13 +94,13 @@ void ieee802_1x_set_sta_authorized(struc
+
+ if (authorized) {
+ sta->flags |= WLAN_STA_AUTHORIZED;
+- res = hostapd_sta_set_flags(hapd, sta->addr,
++ res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+ WLAN_STA_AUTHORIZED, ~0);
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_DEBUG, "authorizing port");
+ } else {
+ sta->flags &= ~WLAN_STA_AUTHORIZED;
+- res = hostapd_sta_set_flags(hapd, sta->addr,
++ res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+ 0, ~WLAN_STA_AUTHORIZED);
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
+--- hostap.orig/hostapd/wme.c 2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/wme.c 2007-11-09 13:41:15.000000000 +0100
+@@ -110,9 +110,11 @@ int hostapd_wme_sta_config(struct hostap
+ {
+ /* update kernel STA data for WME related items (WLAN_STA_WPA flag) */
+ if (sta->flags & WLAN_STA_WME)
+- hostapd_sta_set_flags(hapd, sta->addr, WLAN_STA_WME, ~0);
++ hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
++ WLAN_STA_WME, ~0);
+ else
+- hostapd_sta_set_flags(hapd, sta->addr, 0, ~WLAN_STA_WME);
++ hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
++ 0, ~WLAN_STA_WME);
+
+ return 0;
+ }
diff --git a/package/hostapd/patches/006-use-nl80211-for-sta.patch b/package/hostapd/patches/006-use-nl80211-for-sta.patch
new file mode 100644
index 0000000000..f94ba42886
--- /dev/null
+++ b/package/hostapd/patches/006-use-nl80211-for-sta.patch
@@ -0,0 +1,411 @@
+---
+ hostapd/driver_devicescape.c | 330 ++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 249 insertions(+), 81 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-09 13:41:15.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-09 13:41:16.000000000 +0100
+@@ -75,8 +75,14 @@ struct i802_driver_data {
+
+ #define HAPD_DECL struct hostapd_data *hapd = iface->bss[0]
+
+-static int i802_sta_set_flags(void *priv, const u8 *addr,
+- int total_flags, int flags_or, int flags_and);
++/* helper for netlink get routines */
++static int ack_wait_handler(struct nl_msg *msg, void *arg)
++{
++ int *finished = arg;
++
++ *finished = 1;
++ return NL_STOP;
++}
+
+
+ static int hostapd_set_iface_flags(struct i802_driver_data *drv, int dev_up)
+@@ -255,14 +261,6 @@ static int get_key_handler(struct nl_msg
+ return NL_SKIP;
+ }
+
+-static int ack_wait_handler(struct nl_msg *msg, void *arg)
+-{
+- int *finished = arg;
+-
+- *finished = 1;
+- return NL_STOP;
+-}
+-
+ static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
+ int idx, u8 *seq)
+ {
+@@ -629,43 +627,126 @@ static int i802_get_retry(void *priv, in
+ static int i802_flush(void *priv)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param param;
++ struct nl_msg *msg;
++ int ret = -1;
+
+- memset(&param, 0, sizeof(param));
+- param.cmd = PRISM2_HOSTAPD_FLUSH;
+- return hostapd_ioctl(drv, &param, sizeof(param));
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
++
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_NEW_STATION, 0);
++
++ /*
++ * XXX: FIX! this needs to flush all VLANs too
++ */
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++ if_nametoindex(drv->iface));
++
++ ret = 0;
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0) {
++ ret = -1;
++ }
++
++ nla_put_failure:
++ nlmsg_free(msg);
++
++ out:
++ return ret;
+ }
+
+
++static int get_sta_handler(struct nl_msg *msg, void *arg)
++{
++ struct nlattr *tb[NL80211_ATTR_MAX + 1];
++ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
++ struct hostap_sta_driver_data *data = arg;
++ struct nlattr *stats[NL80211_STA_STAT_MAX + 1];
++ static struct nla_policy stats_policy[NL80211_STA_STAT_MAX + 1] = {
++ [NL80211_STA_STAT_INACTIVE_TIME] = { .type = NLA_U32 },
++ [NL80211_STA_STAT_RX_BYTES] = { .type = NLA_U32 },
++ [NL80211_STA_STAT_TX_BYTES] = { .type = NLA_U32 },
++ };
++
++ nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
++ genlmsg_attrlen(gnlh, 0), NULL);
++
++ /*
++ * TODO: validate the interface and mac address!
++ * Otherwise, there's a race condition as soon as
++ * the kernel starts sending station notifications.
++ */
++
++ if (!tb[NL80211_ATTR_STA_STATS]) {
++ printf("sta stats missing!\n");
++ return NL_SKIP;
++ }
++ if (nla_parse_nested(stats, NL80211_STA_STAT_MAX,
++ tb[NL80211_ATTR_STA_STATS],
++ stats_policy)) {
++ printf("failed to parse nested attributes!\n");
++ return NL_SKIP;
++ }
++
++ if (stats[NL80211_STA_STAT_INACTIVE_TIME])
++ data->inactive_msec =
++ nla_get_u32(stats[NL80211_STA_STAT_INACTIVE_TIME]);
++ if (stats[NL80211_STA_STAT_RX_BYTES])
++ data->rx_bytes = nla_get_u32(stats[NL80211_STA_STAT_RX_BYTES]);
++ if (stats[NL80211_STA_STAT_TX_BYTES])
++ data->rx_bytes = nla_get_u32(stats[NL80211_STA_STAT_TX_BYTES]);
++
++ return NL_SKIP;
++}
++
+ static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
+ const u8 *addr)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param param;
++ struct nl_msg *msg;
++ struct nl_cb *cb = NULL;
++ int ret = -1;
++ int err = 0;
++ int finished = 0;
+
+- memset(data, 0, sizeof(*data));
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
+
+- memset(&param, 0, sizeof(param));
+- param.cmd = PRISM2_HOSTAPD_GET_INFO_STA;
+- memcpy(param.sta_addr, addr, ETH_ALEN);
+- if (hostapd_ioctl(drv, &param, sizeof(param))) {
+- printf(" Could not get station info from kernel driver.\n");
+- return -1;
+- }
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_GET_STATION, 0);
++
++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));
++
++ cb = nl_cb_alloc(NL_CB_CUSTOM);
++ if (!cb)
++ goto out;
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0)
++ goto out;
++
++ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_sta_handler, data);
++ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
++
++ err = nl_recvmsgs(drv->nl_handle, cb);
++
++ if (!finished)
++ err = nl_wait_for_ack(drv->nl_handle);
++
++ if (err < 0)
++ goto out;
++
++ ret = 0;
++
++ out:
++ nl_cb_put(cb);
++ nla_put_failure:
++ nlmsg_free(msg);
++ return ret;
+
+- data->inactive_msec = param.u.get_info_sta.inactive_msec;
+- data->rx_packets = param.u.get_info_sta.rx_packets;
+- data->tx_packets = param.u.get_info_sta.tx_packets;
+- data->rx_bytes = param.u.get_info_sta.rx_bytes;
+- data->tx_bytes = param.u.get_info_sta.tx_bytes;
+- data->current_tx_rate = param.u.get_info_sta.current_tx_rate;
+- data->flags = param.u.get_info_sta.flags;
+- data->num_ps_buf_frames = param.u.get_info_sta.num_ps_buf_frames;
+- data->tx_retry_failed = param.u.get_info_sta.tx_retry_failed;
+- data->tx_retry_count = param.u.get_info_sta.tx_retry_count;
+- data->last_rssi = param.u.get_info_sta.last_rssi;
+- data->last_ack_rssi = param.u.get_info_sta.last_ack_rssi;
+- return 0;
+ }
+
+
+@@ -744,35 +825,68 @@ static int i802_sta_add(const char *ifna
+ size_t supp_rates_len, int flags)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param param;
+- size_t len;
++ struct nl_msg *msg;
++ int ret = -1;
+
+- memset(&param, 0, sizeof(param));
+- param.cmd = PRISM2_HOSTAPD_ADD_STA;
+- memcpy(param.sta_addr, addr, ETH_ALEN);
+- param.u.add_sta.aid = aid;
+- param.u.add_sta.capability = capability;
+- len = supp_rates_len;
+- if (len > sizeof(param.u.add_sta.supp_rates))
+- len = sizeof(param.u.add_sta.supp_rates);
+- memcpy(param.u.add_sta.supp_rates, supp_rates, len);
+- return hostapd_ioctl_iface(ifname, drv, &param, sizeof(param));
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
++
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_NEW_STATION, 0);
++
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++ if_nametoindex(drv->iface));
++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++ NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, aid);
++ NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, supp_rates_len,
++ supp_rates);
++ NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL, 0);
++
++ ret = 0;
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0) {
++ ret = -1;
++ }
++
++ nla_put_failure:
++ nlmsg_free(msg);
++
++ out:
++ return ret;
+ }
+
+
+ static int i802_sta_remove(void *priv, const u8 *addr)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param param;
++ struct nl_msg *msg;
++ int ret = -1;
+
+- i802_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED);
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
+
+- memset(&param, 0, sizeof(param));
+- param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+- memcpy(param.sta_addr, addr, ETH_ALEN);
+- if (hostapd_ioctl(drv, &param, sizeof(param)))
+- return -1;
+- return 0;
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_DEL_STATION, 0);
++
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++ if_nametoindex(drv->iface));
++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++
++ ret = 0;
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0) {
++ ret = -1;
++ }
++
++ nla_put_failure:
++ nlmsg_free(msg);
++
++ out:
++ return ret;
+ }
+
+
+@@ -780,14 +894,51 @@ static int i802_sta_set_flags(void *priv
+ int total_flags, int flags_or, int flags_and)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param param;
++ struct nl_msg *msg, *flags = NULL;
++ int ret = -1;
+
+- memset(&param, 0, sizeof(param));
+- param.cmd = PRISM2_HOSTAPD_SET_FLAGS_STA;
+- memcpy(param.sta_addr, addr, ETH_ALEN);
+- param.u.set_flags_sta.flags_or = flags_or;
+- param.u.set_flags_sta.flags_and = flags_and;
+- return hostapd_ioctl(drv, &param, sizeof(param));
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
++
++ flags = nlmsg_alloc();
++ if (!flags)
++ goto free_msg;
++
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_SET_STATION, 0);
++
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++ if_nametoindex(drv->iface));
++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++
++ if (total_flags & WLAN_STA_AUTHORIZED)
++ NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);
++
++ if (total_flags & WLAN_STA_WME)
++ NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);
++
++ if (total_flags & WLAN_STA_SHORT_PREAMBLE)
++ NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);
++
++ if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))
++ goto nla_put_failure;
++
++ ret = 0;
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0) {
++ ret = -1;
++ }
++
++ nla_put_failure:
++ nlmsg_free(flags);
++
++ free_msg:
++ nlmsg_free(msg);
++
++ out:
++ return ret;
+ }
+
+
+@@ -1257,18 +1408,38 @@ static struct hostapd_hw_modes * i802_ge
+ }
+
+
+-static int i802_set_sta_vlan(void *priv, const u8 *addr, const char *ifname,
+- int vlan_id)
++static int i802_set_sta_vlan(void *priv, const u8 *addr,
++ const char *ifname, int vlan_id)
+ {
+ struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param param;
++ struct nl_msg *msg;
++ int ret = -1;
+
+- memset(&param, 0, sizeof(param));
+- param.cmd = PRISM2_HOSTAPD_SET_STA_VLAN;
+- memcpy(param.sta_addr, addr, ETH_ALEN);
+- os_strlcpy(param.u.set_sta_vlan.vlan_name, ifname, IFNAMSIZ);
+- param.u.set_sta_vlan.vlan_id = vlan_id;
+- return hostapd_ioctl(drv, &param, sizeof(param));
++ msg = nlmsg_alloc();
++ if (!msg)
++ goto out;
++
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_SET_STATION, 0);
++
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++ if_nametoindex(drv->iface));
++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++ if_nametoindex(ifname));
++
++ ret = 0;
++
++ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++ nl_wait_for_ack(drv->nl_handle) < 0) {
++ ret = -1;
++ }
++
++ nla_put_failure:
++ nlmsg_free(msg);
++
++ out:
++ return ret;
+ }
+
+
+@@ -1750,17 +1921,14 @@ static int i802_init_sockets(struct i802
+
+ static int i802_get_inact_sec(void *priv, const u8 *addr)
+ {
+- struct i802_driver_data *drv = priv;
+- struct prism2_hostapd_param param;
++ struct hostap_sta_driver_data data;
++ int ret;
+
+- memset(&param, 0, sizeof(param));
+- param.cmd = PRISM2_HOSTAPD_GET_INFO_STA;
+- memcpy(param.sta_addr, addr, ETH_ALEN);
+- if (hostapd_ioctl(drv, &param, sizeof(param))) {
++ data.inactive_msec = -1;
++ ret = i802_read_sta_data(priv, &data, addr);
++ if (ret || data.inactive_msec == -1)
+ return -1;
+- }
+-
+- return param.u.get_info_sta.inactive_msec / 1000;
++ return data.inactive_msec / 1000;
+ }
+
+
diff --git a/package/hostapd/patches/100-madwifi_fixes.patch b/package/hostapd/patches/100-madwifi_fixes.patch
deleted file mode 100644
index 74d0c44d63..0000000000
--- a/package/hostapd/patches/100-madwifi_fixes.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-Index: hostapd-0.5.7/driver_madwifi.c
-===================================================================
---- hostapd-0.5.7.orig/driver_madwifi.c 2007-06-04 13:22:31.768025808 +0200
-+++ hostapd-0.5.7/driver_madwifi.c 2007-06-04 13:22:32.051982640 +0200
-@@ -21,12 +21,9 @@
- #include <include/compat.h>
- #include <net80211/ieee80211.h>
- #ifdef WME_NUM_AC
--/* Assume this is built against BSD branch of madwifi driver. */
--#define MADWIFI_BSD
--#include <net80211/_ieee80211.h>
--#endif /* WME_NUM_AC */
- #include <net80211/ieee80211_crypto.h>
- #include <net80211/ieee80211_ioctl.h>
-+#endif /* WME_NUM_AC */
-
- #ifdef IEEE80211_IOCTL_SETWMMPARAMS
- /* Assume this is built against madwifi-ng */
-@@ -169,6 +166,11 @@
- return 0;
- }
-
-+static int madwifi_get_inact_sec(void *priv, const u8 *addr)
-+{
-+ return 0;
-+}
-+
- static int
- set80211param(struct madwifi_driver_data *drv, int op, int arg)
- {
-@@ -1258,7 +1260,6 @@
- goto bad;
- }
-
-- madwifi_set_iface_flags(drv, 0); /* mark down during setup */
- madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */
-
- hapd->driver = &drv->ops;
-@@ -1281,7 +1282,6 @@
-
- drv->hapd->driver = NULL;
-
-- (void) madwifi_set_iface_flags(drv, 0);
- if (drv->ioctl_sock >= 0)
- close(drv->ioctl_sock);
- if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
-@@ -1367,6 +1367,7 @@
- .get_ssid = madwifi_get_ssid,
- .set_countermeasures = madwifi_set_countermeasures,
- .sta_clear_stats = madwifi_sta_clear_stats,
-+ .get_inact_sec = madwifi_get_inact_sec,
- .commit = madwifi_commit,
- };
-