--- /dev/null
+---
+ 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-14 17:30:38.000000000 +0100
++++ hostap/hostapd/driver.h 2007-11-14 17:30:47.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-14 17:30:38.000000000 +0100
++++ hostap/hostapd/driver_bsd.c 2007-11-14 17:30:47.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-14 17:30:39.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-14 17:30:47.000000000 +0100
+@@ -74,7 +74,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)
+@@ -666,7 +666,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(¶m, 0, sizeof(param));
+ param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+@@ -678,7 +678,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-14 17:30:38.000000000 +0100
++++ hostap/hostapd/driver_hostap.c 2007-11-14 17:30:47.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(¶m, 0, sizeof(param));
+ param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+--- hostap.orig/hostapd/driver_madwifi.c 2007-11-14 17:30:38.000000000 +0100
++++ hostap/hostapd/driver_madwifi.c 2007-11-14 17:30:47.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-14 17:30:38.000000000 +0100
++++ hostap/hostapd/driver_prism54.c 2007-11-14 17:30:47.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-14 17:30:37.000000000 +0100
++++ hostap/hostapd/ieee802_11.c 2007-11-14 17:30:47.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-14 17:30:37.000000000 +0100
++++ hostap/hostapd/ieee802_1x.c 2007-11-14 17:30:47.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-14 17:30:38.000000000 +0100
++++ hostap/hostapd/wme.c 2007-11-14 17:30:47.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;
+ }
+++ /dev/null
----
- 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.
--- /dev/null
+---
+ hostapd/driver_devicescape.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-14 17:30:47.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-14 17:31:07.000000000 +0100
+@@ -1264,6 +1264,7 @@ static void dump_frame_info(struct ieee8
+ }
+
+
++/*
+ static void hostapd_michael_mic_failure(struct hostapd_data *hapd, u8 *buf,
+ size_t len)
+ {
+@@ -1278,6 +1279,7 @@ static void hostapd_michael_mic_failure(
+
+ mlme_michaelmicfailure_indication(hapd, hdr->addr2);
+ }
++*/
+
+
+ static void handle_frame(struct hostapd_iface *iface, u8 *buf, size_t len,
+@@ -1386,10 +1388,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.
+++ /dev/null
----
- 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;
- }
-
+++ /dev/null
----
- 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 = (¶m->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(¶m->u.beacon.data[0], head, head_len);
-- memcpy(¶m->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;
- }
-
-
--- /dev/null
+---
+ 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;
+ }
+
--- /dev/null
+---
+ 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 = (¶m->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(¶m->u.beacon.data[0], head, head_len);
+- memcpy(¶m->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;
+ }
+
+
+++ /dev/null
----
- 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;
- }
-
+++ /dev/null
----
- 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(¶m, 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(¶m, 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;
- }
--- /dev/null
+---
+ 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;
+ }
+
---
- hostapd/driver_devicescape.c | 330 ++++++++++++++++++++++++++++++++-----------
- 1 file changed, 249 insertions(+), 81 deletions(-)
+ hostapd/driver_devicescape.c | 332 ++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 251 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
+--- hostap.orig/hostapd/driver_devicescape.c 2007-11-14 17:31:15.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c 2007-11-14 17:31:16.000000000 +0100
@@ -75,8 +75,14 @@ struct i802_driver_data {
#define HAPD_DECL struct hostapd_data *hapd = iface->bss[0]
+ int ret = -1;
+ int err = 0;
+ int finished = 0;
-
-- memset(data, 0, sizeof(*data));
++
+ msg = nlmsg_alloc();
+ if (!msg)
+ goto out;
+- memset(data, 0, sizeof(*data));
++ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++ 0, NL80211_CMD_GET_STATION, 0);
+
- memset(¶m, 0, sizeof(param));
- param.cmd = PRISM2_HOSTAPD_GET_INFO_STA;
- memcpy(param.sta_addr, addr, ETH_ALEN);
- 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));
+
}
-@@ -744,35 +825,68 @@ static int i802_sta_add(const char *ifna
+@@ -744,35 +825,70 @@ static int i802_sta_add(const char *ifna
size_t supp_rates_len, int flags)
{
struct i802_driver_data *drv = priv;
+ supp_rates);
+ NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL, 0);
+
-+ ret = 0;
++ ret = nl_send_auto_complete(drv->nl_handle, msg);
++ if (ret < 0)
++ goto nla_put_failure;
+
-+ if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
-+ nl_wait_for_ack(drv->nl_handle) < 0) {
-+ ret = -1;
-+ }
++ ret = nl_wait_for_ack(drv->nl_handle);
++ /* ignore EEXIST, this happens if a STA associates while associated */
++ if (ret == -EEXIST || ret >= 0)
++ ret = 0;
+
+ nla_put_failure:
+ nlmsg_free(msg);
}
-@@ -780,14 +894,51 @@ static int i802_sta_set_flags(void *priv
+@@ -780,14 +896,51 @@ static int i802_sta_set_flags(void *priv
int total_flags, int flags_or, int flags_and)
{
struct i802_driver_data *drv = priv;
}
-@@ -1257,18 +1408,38 @@ static struct hostapd_hw_modes * i802_ge
+@@ -1257,18 +1410,38 @@ static struct hostapd_hw_modes * i802_ge
}
}
-@@ -1750,17 +1921,14 @@ static int i802_init_sockets(struct i802
+@@ -1752,17 +1925,14 @@ static int i802_init_sockets(struct i802
static int i802_get_inact_sec(void *priv, const u8 *addr)
{