aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-03-07 20:47:39 (GMT)
committerJouni Malinen <j@w1.fi>2010-03-07 20:47:39 (GMT)
commit7b90c16aa9ca377b1a6d160c1ba0f2bd304f7e2f (patch)
treec9781151f30b4740bde2a9fa3b794972effba759 /src
parent1b484d60e55a01d02bf01f790a7c6fb9ea606098 (diff)
downloadhostap-7b90c16aa9ca377b1a6d160c1ba0f2bd304f7e2f.zip
hostap-7b90c16aa9ca377b1a6d160c1ba0f2bd304f7e2f.tar.gz
hostap-7b90c16aa9ca377b1a6d160c1ba0f2bd304f7e2f.tar.bz2
nl80211: Add preliminary implementation of FT Action send
This is a step in adding FT support with nl80211-based drivers. driver_nl80211.c is now registering to handle the FT Action frames and is able to transmit FT Request frame. Received FT Action frames are not yet indicated as driver events.
Diffstat (limited to 'src')
-rw-r--r--src/drivers/driver_nl80211.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index edbe69b..d4679b9 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1338,6 +1338,14 @@ static int nl80211_register_action_frames(struct wpa_driver_nl80211_data *drv)
/* Public Action frames */
return nl80211_register_action_frame(drv, (u8 *) "\x04", 1);
}
+
+ /* FT Action frames */
+ if (nl80211_register_action_frame(drv, (u8 *) "\x06", 1) < 0)
+ return -1;
+ else
+ drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
+ WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
+
return 0;
}
@@ -1369,8 +1377,15 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
1, IF_OPER_DORMANT);
#endif /* HOSTAPD */
- if (nl80211_register_action_frames(drv) < 0)
- return -1;
+ if (nl80211_register_action_frames(drv) < 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
+ "frame processing - ignore for now");
+ /*
+ * Older kernel versions did not support this, so ignore the
+ * error for now. Some functionality may not be available
+ * because of this.
+ */
+ }
return 0;
}
@@ -5083,6 +5098,56 @@ static void wpa_driver_nl80211_resume(void *priv)
}
+static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
+ const u8 *ies, size_t ies_len)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ int ret;
+ u8 *data, *pos;
+ size_t data_len;
+ u8 own_addr[ETH_ALEN];
+
+ if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, own_addr) < 0)
+ return -1;
+
+ if (action != 1) {
+ wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
+ "action %d", action);
+ return -1;
+ }
+
+ /*
+ * Action frame payload:
+ * Category[1] = 6 (Fast BSS Transition)
+ * Action[1] = 1 (Fast BSS Transition Request)
+ * STA Address
+ * Target AP Address
+ * FT IEs
+ */
+
+ data_len = ies_len;
+ data = os_malloc(2 + 2 * ETH_ALEN + data_len);
+ if (data == NULL)
+ return -1;
+ pos = data;
+ *pos++ = 0x06; /* FT Action category */
+ *pos++ = action;
+ os_memcpy(pos, own_addr, ETH_ALEN);
+ pos += ETH_ALEN;
+ os_memcpy(pos, target_ap, ETH_ALEN);
+ pos += ETH_ALEN;
+ os_memcpy(pos, ies, ies_len);
+
+ ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, drv->bssid,
+ own_addr, drv->bssid,
+ data, data_len);
+ os_free(data);
+
+ return ret;
+}
+
+
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@@ -5141,4 +5206,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.disable_11b_rates = wpa_driver_nl80211_disable_11b_rates,
.deinit_ap = wpa_driver_nl80211_deinit_ap,
.resume = wpa_driver_nl80211_resume,
+ .send_ft_action = nl80211_send_ft_action,
};