diff options
Diffstat (limited to 'package/hostapd/patches/006-use-nl80211-for-sta.patch')
-rw-r--r-- | package/hostapd/patches/006-use-nl80211-for-sta.patch | 413 |
1 files changed, 0 insertions, 413 deletions
diff --git a/package/hostapd/patches/006-use-nl80211-for-sta.patch b/package/hostapd/patches/006-use-nl80211-for-sta.patch deleted file mode 100644 index 133a750194..0000000000 --- a/package/hostapd/patches/006-use-nl80211-for-sta.patch +++ /dev/null @@ -1,413 +0,0 @@ ---- - hostapd/driver_devicescape.c | 332 ++++++++++++++++++++++++++++++++----------- - 1 file changed, 251 insertions(+), 81 deletions(-) - ---- 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] - --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(¶m, 0, sizeof(param)); -- param.cmd = PRISM2_HOSTAPD_FLUSH; -- return hostapd_ioctl(drv, ¶m, 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; -+ -+ 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); -- if (hostapd_ioctl(drv, ¶m, sizeof(param))) { -- printf(" Could not get station info from kernel driver.\n"); -- return -1; -- } -+ 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,70 @@ 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(¶m, 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, ¶m, 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 = nl_send_auto_complete(drv->nl_handle, msg); -+ if (ret < 0) -+ goto nla_put_failure; -+ -+ 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); -+ -+ 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(¶m, 0, sizeof(param)); -- param.cmd = PRISM2_HOSTAPD_REMOVE_STA; -- memcpy(param.sta_addr, addr, ETH_ALEN); -- if (hostapd_ioctl(drv, ¶m, 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 +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; -- struct prism2_hostapd_param param; -+ struct nl_msg *msg, *flags = NULL; -+ int ret = -1; - -- memset(¶m, 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, ¶m, 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 +1410,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(¶m, 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, ¶m, 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; - } - - -@@ -1752,17 +1925,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(¶m, 0, sizeof(param)); -- param.cmd = PRISM2_HOSTAPD_GET_INFO_STA; -- memcpy(param.sta_addr, addr, ETH_ALEN); -- if (hostapd_ioctl(drv, ¶m, 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; - } - - |