aboutsummaryrefslogtreecommitdiffstats
path: root/package/hostapd/patches
diff options
context:
space:
mode:
Diffstat (limited to 'package/hostapd/patches')
-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
8 files changed, 979 insertions, 90 deletions
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,
- };
-