WNM: Add disassociation timeout processing for ESS_DISASSOC
The hostapd_cli ess_disassoc command now takes three arguments (STA MAC address, timeout in ms, URL) and the STA is disconnected after the specified timeout. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
f65f539d9a
commit
d5b559b641
4 changed files with 52 additions and 15 deletions
|
@ -537,14 +537,24 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
|
|||
const char *cmd)
|
||||
{
|
||||
u8 addr[ETH_ALEN];
|
||||
const char *url;
|
||||
const char *url, *timerstr;
|
||||
u8 buf[1000], *pos;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
size_t url_len;
|
||||
int disassoc_timer;
|
||||
|
||||
if (hwaddr_aton(cmd, addr))
|
||||
return -1;
|
||||
url = cmd + 17;
|
||||
|
||||
timerstr = cmd + 17;
|
||||
if (*timerstr != ' ')
|
||||
return -1;
|
||||
timerstr++;
|
||||
disassoc_timer = atoi(timerstr);
|
||||
if (disassoc_timer < 0 || disassoc_timer > 65535)
|
||||
return -1;
|
||||
|
||||
url = os_strchr(timerstr, ' ');
|
||||
if (*url != ' ')
|
||||
return -1;
|
||||
url++;
|
||||
|
@ -564,8 +574,9 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
|
|||
mgmt->u.action.u.bss_tm_req.dialog_token = 1;
|
||||
mgmt->u.action.u.bss_tm_req.req_mode =
|
||||
WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
|
||||
mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
|
||||
mgmt->u.action.u.bss_tm_req.validity_interval = 0;
|
||||
mgmt->u.action.u.bss_tm_req.disassoc_timer =
|
||||
host_to_le16(disassoc_timer);
|
||||
mgmt->u.action.u.bss_tm_req.validity_interval = 0x01;
|
||||
|
||||
pos = mgmt->u.action.u.bss_tm_req.variable;
|
||||
|
||||
|
@ -580,6 +591,25 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* send disassociation frame after time-out */
|
||||
if (disassoc_timer) {
|
||||
struct sta_info *sta;
|
||||
|
||||
sta = ap_get_sta(hapd, addr);
|
||||
if (sta == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "Station " MACSTR " not found "
|
||||
"for ESS disassociation imminent message",
|
||||
MAC2STR(addr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
sta->timeout_next = STA_DISASSOC_FROM_CLI;
|
||||
eloop_cancel_timeout(ap_handle_timer, hapd, sta);
|
||||
eloop_register_timeout(disassoc_timer / 1000,
|
||||
disassoc_timer % 1000 * 1000,
|
||||
ap_handle_timer, hapd, sta);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -588,14 +588,14 @@ static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc,
|
|||
char buf[300];
|
||||
int res;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Invalid 'ess_disassoc' command - two arguments (STA "
|
||||
"addr and URL) are needed\n");
|
||||
if (argc < 3) {
|
||||
printf("Invalid 'ess_disassoc' command - three arguments (STA "
|
||||
"addr, disassoc timer, and URL) are needed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s",
|
||||
argv[0], argv[1]);
|
||||
res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s %s",
|
||||
argv[0], argv[1], argv[2]);
|
||||
if (res < 0 || res >= (int) sizeof(buf))
|
||||
return -1;
|
||||
return wpa_ctrl_command(ctrl, buf);
|
||||
|
|
|
@ -283,6 +283,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
|||
struct hostapd_data *hapd = eloop_ctx;
|
||||
struct sta_info *sta = timeout_ctx;
|
||||
unsigned long next_time = 0;
|
||||
int reason;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: " MACSTR " flags=0x%x timeout_next=%d",
|
||||
__func__, MAC2STR(sta->addr), sta->flags,
|
||||
|
@ -378,9 +379,11 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
|||
hapd, sta->addr,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
} else {
|
||||
hostapd_drv_sta_disassoc(
|
||||
hapd, sta->addr,
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
|
||||
reason = (sta->timeout_next == STA_DISASSOC) ?
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY :
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID;
|
||||
|
||||
hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,6 +397,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
|||
hapd, sta);
|
||||
break;
|
||||
case STA_DISASSOC:
|
||||
case STA_DISASSOC_FROM_CLI:
|
||||
ap_sta_set_authorized(hapd, sta, 0);
|
||||
sta->flags &= ~WLAN_STA_ASSOC;
|
||||
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
|
||||
|
@ -405,14 +409,16 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
|
|||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO, "disassociated due to "
|
||||
"inactivity");
|
||||
reason = (sta->timeout_next == STA_DISASSOC) ?
|
||||
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY :
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID;
|
||||
sta->timeout_next = STA_DEAUTH;
|
||||
wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
|
||||
"for " MACSTR " (%d seconds - AP_DEAUTH_DELAY)",
|
||||
__func__, MAC2STR(sta->addr), AP_DEAUTH_DELAY);
|
||||
eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
|
||||
hapd, sta);
|
||||
mlme_disassociate_indication(
|
||||
hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
|
||||
mlme_disassociate_indication(hapd, sta, reason);
|
||||
break;
|
||||
case STA_DEAUTH:
|
||||
case STA_REMOVE:
|
||||
|
|
|
@ -62,7 +62,8 @@ struct sta_info {
|
|||
u8 previous_ap[6];
|
||||
|
||||
enum {
|
||||
STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH, STA_REMOVE
|
||||
STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH, STA_REMOVE,
|
||||
STA_DISASSOC_FROM_CLI
|
||||
} timeout_next;
|
||||
|
||||
u16 deauth_reason;
|
||||
|
|
Loading…
Reference in a new issue