aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJithu Jance <jithu@broadcom.com>2012-02-25 15:22:48 (GMT)
committerJouni Malinen <j@w1.fi>2012-02-25 15:22:48 (GMT)
commite60b295186f5a70ab066eb35c4cea0153f54976c (patch)
treec787251e7e6c864ad53cf436b96d355867b91bb3
parent93d1749fe09522892779151f0e22adb3e52efa20 (diff)
downloadhostap-e60b295186f5a70ab066eb35c4cea0153f54976c.zip
hostap-e60b295186f5a70ab066eb35c4cea0153f54976c.tar.gz
hostap-e60b295186f5a70ab066eb35c4cea0153f54976c.tar.bz2
Add wpa_supplicant AP mode STA deauthenticate/disassociate commands
Move disassociate and deauthenticate commands to ctrl_iface_ap.c, so that they ares accessible for wpa_supplicant AP mode and wpa_cli (with CONFIG_AP option enabled). Signed-hostap: Jithu Jance <jithu@broadcom.com>
-rw-r--r--hostapd/ctrl_iface.c167
-rw-r--r--src/ap/ctrl_iface_ap.c169
-rw-r--r--src/ap/ctrl_iface_ap.h4
-rw-r--r--wpa_supplicant/ap.c20
-rw-r--r--wpa_supplicant/ap.h4
-rw-r--r--wpa_supplicant/ctrl_iface.c6
-rw-r--r--wpa_supplicant/wpa_cli.c42
7 files changed, 245 insertions, 167 deletions
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index a2e7cc5..0fe761b 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -153,173 +153,6 @@ static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
}
-#ifdef CONFIG_P2P_MANAGER
-static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
- u8 minor_reason_code, const u8 *addr)
-{
- struct ieee80211_mgmt *mgmt;
- int ret;
- u8 *pos;
-
- if (hapd->driver->send_frame == NULL)
- return -1;
-
- mgmt = os_zalloc(sizeof(*mgmt) + 100);
- if (mgmt == NULL)
- return -1;
-
- wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "P2P: Disconnect STA " MACSTR
- " with minor reason code %u (stype=%u)",
- MAC2STR(addr), minor_reason_code, stype);
-
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
- 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);
- if (stype == WLAN_FC_STYPE_DEAUTH) {
- mgmt->u.deauth.reason_code =
- host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
- pos = (u8 *) (&mgmt->u.deauth.reason_code + 1);
- } else {
- mgmt->u.disassoc.reason_code =
- host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
- pos = (u8 *) (&mgmt->u.disassoc.reason_code + 1);
- }
-
- *pos++ = WLAN_EID_VENDOR_SPECIFIC;
- *pos++ = 4 + 3 + 1;
- WPA_PUT_BE24(pos, OUI_WFA);
- pos += 3;
- *pos++ = P2P_OUI_TYPE;
-
- *pos++ = P2P_ATTR_MINOR_REASON_CODE;
- WPA_PUT_LE16(pos, 1);
- pos += 2;
- *pos++ = minor_reason_code;
-
- ret = hapd->driver->send_frame(hapd->drv_priv, (u8 *) mgmt,
- pos - (u8 *) mgmt, 1);
- os_free(mgmt);
-
- return ret < 0 ? -1 : 0;
-}
-#endif /* CONFIG_P2P_MANAGER */
-
-
-static int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
- const char *txtaddr)
-{
- u8 addr[ETH_ALEN];
- struct sta_info *sta;
- const char *pos;
-
- wpa_dbg(hapd->msg_ctx, 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;
- }
-
-#ifdef CONFIG_P2P_MANAGER
- pos = os_strstr(txtaddr, " p2p=");
- if (pos) {
- return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DEAUTH,
- atoi(pos + 5), addr);
- }
-#endif /* CONFIG_P2P_MANAGER */
-
- hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
- sta = ap_get_sta(hapd, addr);
- if (sta)
- ap_sta_deauthenticate(hapd, sta,
- WLAN_REASON_PREV_AUTH_NOT_VALID);
- else if (addr[0] == 0xff)
- hostapd_free_stas(hapd);
-
- return 0;
-}
-
-
-static int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
- const char *txtaddr)
-{
- u8 addr[ETH_ALEN];
- struct sta_info *sta;
- const char *pos;
-
- wpa_dbg(hapd->msg_ctx, 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.disassoc.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;
- }
-
-#ifdef CONFIG_P2P_MANAGER
- pos = os_strstr(txtaddr, " p2p=");
- if (pos) {
- return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DISASSOC,
- atoi(pos + 5), addr);
- }
-#endif /* CONFIG_P2P_MANAGER */
-
- hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
- sta = ap_get_sta(hapd, addr);
- if (sta)
- ap_sta_disassociate(hapd, sta,
- WLAN_REASON_PREV_AUTH_NOT_VALID);
- else if (addr[0] == 0xff)
- hostapd_free_stas(hapd);
-
- return 0;
-}
-
-
#ifdef CONFIG_IEEE80211W
#ifdef NEED_AP_MLME
static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index d76b381..ab9c83e 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -9,6 +9,7 @@
#include "utils/includes.h"
#include "utils/common.h"
+#include "common/ieee802_11_defs.h"
#include "hostapd.h"
#include "ieee802_1x.h"
#include "wpa_auth.h"
@@ -17,6 +18,7 @@
#include "wps_hostapd.h"
#include "p2p_hostapd.h"
#include "ctrl_iface_ap.h"
+#include "ap_drv_ops.h"
static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
@@ -100,3 +102,170 @@ int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
}
return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
}
+
+
+#ifdef CONFIG_P2P_MANAGER
+static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
+ u8 minor_reason_code, const u8 *addr)
+{
+ struct ieee80211_mgmt *mgmt;
+ int ret;
+ u8 *pos;
+
+ if (hapd->driver->send_frame == NULL)
+ return -1;
+
+ mgmt = os_zalloc(sizeof(*mgmt) + 100);
+ if (mgmt == NULL)
+ return -1;
+
+ wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "P2P: Disconnect STA " MACSTR
+ " with minor reason code %u (stype=%u)",
+ MAC2STR(addr), minor_reason_code, stype);
+
+ mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
+ 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);
+ if (stype == WLAN_FC_STYPE_DEAUTH) {
+ mgmt->u.deauth.reason_code =
+ host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+ pos = (u8 *) (&mgmt->u.deauth.reason_code + 1);
+ } else {
+ mgmt->u.disassoc.reason_code =
+ host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+ pos = (u8 *) (&mgmt->u.disassoc.reason_code + 1);
+ }
+
+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
+ *pos++ = 4 + 3 + 1;
+ WPA_PUT_BE24(pos, OUI_WFA);
+ pos += 3;
+ *pos++ = P2P_OUI_TYPE;
+
+ *pos++ = P2P_ATTR_MINOR_REASON_CODE;
+ WPA_PUT_LE16(pos, 1);
+ pos += 2;
+ *pos++ = minor_reason_code;
+
+ ret = hapd->driver->send_frame(hapd->drv_priv, (u8 *) mgmt,
+ pos - (u8 *) mgmt, 1);
+ os_free(mgmt);
+
+ return ret < 0 ? -1 : 0;
+}
+#endif /* CONFIG_P2P_MANAGER */
+
+
+int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
+ const char *txtaddr)
+{
+ u8 addr[ETH_ALEN];
+ struct sta_info *sta;
+ const char *pos;
+
+ wpa_dbg(hapd->msg_ctx, 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;
+ }
+
+#ifdef CONFIG_P2P_MANAGER
+ pos = os_strstr(txtaddr, " p2p=");
+ if (pos) {
+ return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DEAUTH,
+ atoi(pos + 5), addr);
+ }
+#endif /* CONFIG_P2P_MANAGER */
+
+ hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+ sta = ap_get_sta(hapd, addr);
+ if (sta)
+ ap_sta_deauthenticate(hapd, sta,
+ WLAN_REASON_PREV_AUTH_NOT_VALID);
+ else if (addr[0] == 0xff)
+ hostapd_free_stas(hapd);
+
+ return 0;
+}
+
+
+int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
+ const char *txtaddr)
+{
+ u8 addr[ETH_ALEN];
+ struct sta_info *sta;
+ const char *pos;
+
+ wpa_dbg(hapd->msg_ctx, 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.disassoc.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;
+ }
+
+#ifdef CONFIG_P2P_MANAGER
+ pos = os_strstr(txtaddr, " p2p=");
+ if (pos) {
+ return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DISASSOC,
+ atoi(pos + 5), addr);
+ }
+#endif /* CONFIG_P2P_MANAGER */
+
+ hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+ sta = ap_get_sta(hapd, addr);
+ if (sta)
+ ap_sta_disassociate(hapd, sta,
+ WLAN_REASON_PREV_AUTH_NOT_VALID);
+ else if (addr[0] == 0xff)
+ hostapd_free_stas(hapd);
+
+ return 0;
+}
diff --git a/src/ap/ctrl_iface_ap.h b/src/ap/ctrl_iface_ap.h
index 0e4286d..e83f894 100644
--- a/src/ap/ctrl_iface_ap.h
+++ b/src/ap/ctrl_iface_ap.h
@@ -15,5 +15,9 @@ int hostapd_ctrl_iface_sta(struct hostapd_data *hapd, const char *txtaddr,
char *buf, size_t buflen);
int hostapd_ctrl_iface_sta_next(struct hostapd_data *hapd, const char *txtaddr,
char *buf, size_t buflen);
+int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
+ const char *txtaddr);
+int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
+ const char *txtaddr);
#endif /* CTRL_IFACE_AP_H */
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 6046249..52f421a 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -870,6 +870,26 @@ int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
}
+int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
+ const char *txtaddr)
+{
+ if (wpa_s->ap_iface == NULL)
+ return -1;
+ return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
+ txtaddr);
+}
+
+
+int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
+ const char *txtaddr)
+{
+ if (wpa_s->ap_iface == NULL)
+ return -1;
+ return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
+ txtaddr);
+}
+
+
int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
size_t buflen, int verbose)
{
diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h
index f0eb67d..91ab423 100644
--- a/wpa_supplicant/ap.h
+++ b/wpa_supplicant/ap.h
@@ -31,6 +31,10 @@ int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
char *buf, size_t buflen);
int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
char *buf, size_t buflen);
+int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
+ const char *txtaddr);
+int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
+ const char *txtaddr);
int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
size_t buflen, int verbose);
void ap_tx_status(void *ctx, const u8 *addr,
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index d623e91..11f4674 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -4026,6 +4026,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
reply_size);
+ } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
+ if (ap_ctrl_iface_sta_deauthenticate(wpa_s, buf + 15))
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
+ if (ap_ctrl_iface_sta_disassociate(wpa_s, buf + 13))
+ reply_len = -1;
#endif /* CONFIG_AP */
} else if (os_strcmp(buf, "SUSPEND") == 0) {
wpas_notify_suspend(wpa_s->global);
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index d28641b..1d59bcd 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1916,6 +1916,42 @@ static int wpa_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
return -1;
}
+
+
+static int wpa_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char buf[64];
+ if (argc < 1) {
+ printf("Invalid 'deauthenticate' command - exactly one "
+ "argument, STA address, is required.\n");
+ return -1;
+ }
+ 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);
+}
+
+
+static int wpa_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ char buf[64];
+ if (argc < 1) {
+ printf("Invalid 'disassociate' command - exactly one "
+ "argument, STA address, is required.\n");
+ return -1;
+ }
+ 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);
+}
#endif /* CONFIG_AP */
@@ -2963,6 +2999,12 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "all_sta", wpa_cli_cmd_all_sta,
cli_cmd_flag_none,
"= get information about all associated stations (AP)" },
+ { "deauthenticate", wpa_cli_cmd_deauthenticate,
+ cli_cmd_flag_none,
+ "<addr> = deauthenticate a station" },
+ { "disassociate", wpa_cli_cmd_disassociate,
+ cli_cmd_flag_none,
+ "<addr> = disassociate a station" },
#endif /* CONFIG_AP */
{ "suspend", wpa_cli_cmd_suspend, cli_cmd_flag_none,
"= notification of suspend/hibernate" },