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:
Kyeyoon Park 2013-04-05 18:41:26 +03:00 committed by Jouni Malinen
parent f65f539d9a
commit d5b559b641
4 changed files with 52 additions and 15 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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:

View file

@ -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;