aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2010-03-29 19:01:40 (GMT)
committerJouni Malinen <j@w1.fi>2010-03-29 19:01:40 (GMT)
commitb91ab76e8ca3dceb6b0d9262988bbff12e722220 (patch)
treee26ee04e081322f9a4f7c8397b2c057ac3498662
parent90a3206a1449af0058704482b4703b1a9f7c3d95 (diff)
downloadhostap-b91ab76e8ca3dceb6b0d9262988bbff12e722220.zip
hostap-b91ab76e8ca3dceb6b0d9262988bbff12e722220.tar.gz
hostap-b91ab76e8ca3dceb6b0d9262988bbff12e722220.tar.bz2
Add test commands for sending deauth/disassoc without dropping state
This can be used to test 802.11w by sending a protected or unprotected deauth/disassoc frame. hostapd_cli deauth <dst addr> test=<0/1> hostapd_cli disassoc <dst addr> test=<0/1> test=0: unprotected test=1: protected
-rw-r--r--hostapd/ctrl_iface.c50
-rw-r--r--hostapd/hostapd_cli.c16
-rw-r--r--src/drivers/driver.h14
-rw-r--r--src/drivers/driver_ndis.c3
-rw-r--r--src/drivers/driver_nl80211.c10
5 files changed, 88 insertions, 5 deletions
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index fe32282..fca4189 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -160,12 +160,37 @@ static int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
{
u8 addr[ETH_ALEN];
struct sta_info *sta;
+ const char *pos;
wpa_printf(MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s", txtaddr);
if (hwaddr_aton(txtaddr, addr))
return -1;
+ pos = os_strstr(txtaddr, " test=");
+ if (pos) {
+ struct ieee80211_mgmt mgmt;
+ int encrypt;
+ if (hapd->driver->send_frame == NULL)
+ return -1;
+ pos += 6;
+ encrypt = atoi(pos);
+ os_memset(&mgmt, 0, sizeof(mgmt));
+ mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+ WLAN_FC_STYPE_DEAUTH);
+ os_memcpy(mgmt.da, addr, ETH_ALEN);
+ os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
+ os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
+ mgmt.u.deauth.reason_code =
+ host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+ if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
+ IEEE80211_HDRLEN +
+ sizeof(mgmt.u.deauth),
+ encrypt) < 0)
+ return -1;
+ return 0;
+ }
+
hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
sta = ap_get_sta(hapd, addr);
if (sta)
@@ -181,12 +206,37 @@ static int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
{
u8 addr[ETH_ALEN];
struct sta_info *sta;
+ const char *pos;
wpa_printf(MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", txtaddr);
if (hwaddr_aton(txtaddr, addr))
return -1;
+ pos = os_strstr(txtaddr, " test=");
+ if (pos) {
+ struct ieee80211_mgmt mgmt;
+ int encrypt;
+ if (hapd->driver->send_frame == NULL)
+ return -1;
+ pos += 6;
+ encrypt = atoi(pos);
+ os_memset(&mgmt, 0, sizeof(mgmt));
+ mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+ WLAN_FC_STYPE_DISASSOC);
+ os_memcpy(mgmt.da, addr, ETH_ALEN);
+ os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
+ os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
+ mgmt.u.deauth.reason_code =
+ host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+ if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
+ IEEE80211_HDRLEN +
+ sizeof(mgmt.u.deauth),
+ encrypt) < 0)
+ return -1;
+ return 0;
+ }
+
hapd->drv.sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
sta = ap_get_sta(hapd, addr);
if (sta)
diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
index 4548924..6fab4ad 100644
--- a/hostapd/hostapd_cli.c
+++ b/hostapd/hostapd_cli.c
@@ -246,12 +246,16 @@ static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char buf[64];
- if (argc != 1) {
+ if (argc < 1) {
printf("Invalid 'deauthenticate' command - exactly one "
"argument, STA address, is required.\n");
return -1;
}
- snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
+ if (argc > 1)
+ os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
+ argv[0], argv[1]);
+ else
+ os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
return wpa_ctrl_command(ctrl, buf);
}
@@ -260,12 +264,16 @@ static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char buf[64];
- if (argc != 1) {
+ if (argc < 1) {
printf("Invalid 'disassociate' command - exactly one "
"argument, STA address, is required.\n");
return -1;
}
- snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
+ if (argc > 1)
+ os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
+ argv[0], argv[1]);
+ else
+ os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
return wpa_ctrl_command(ctrl, buf);
}
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 1d51a49..39bbcd9 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1774,6 +1774,20 @@ struct wpa_driver_ops {
* least %hysteresis from the previously indicated signal change event.
*/
int (*signal_monitor)(void *priv, int threshold, int hysteresis);
+
+ /**
+ * send_frame - Send IEEE 802.11 frame (testing use only)
+ * @priv: Private driver interface data
+ * @data: IEEE 802.11 frame with IEEE 802.11 header
+ * @data_len: Size of the frame
+ * @encrypt: Whether to encrypt the frame (if keys are set)
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is only used for debugging purposes and is not
+ * required to be implemented for normal operations.
+ */
+ int (*send_frame)(void *priv, const u8 *data, size_t data_len,
+ int encrypt);
};
diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c
index 662b1a1..6d7a1fc 100644
--- a/src/drivers/driver_ndis.c
+++ b/src/drivers/driver_ndis.c
@@ -3275,5 +3275,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
NULL /* deinit_ap */,
NULL /* suspend */,
NULL /* resume */,
- NULL /* signal_monitor */
+ NULL /* signal_monitor */,
+ NULL /* send_frame */
};
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b1007fe..70a0d07 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5237,6 +5237,15 @@ nla_put_failure:
}
+static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
+ int encrypt)
+{
+ struct i802_bss *bss = priv;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+ return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt);
+}
+
+
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@@ -5297,4 +5306,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.resume = wpa_driver_nl80211_resume,
.send_ft_action = nl80211_send_ft_action,
.signal_monitor = nl80211_signal_monitor,
+ .send_frame = nl80211_send_frame,
};