]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WNM: Add disassociation timeout processing for ESS_DISASSOC
authorKyeyoon Park <kyeyoonp@qca.qualcomm.com>
Fri, 5 Apr 2013 15:41:26 +0000 (18:41 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 20 May 2013 08:13:40 +0000 (11:13 +0300)
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>

hostapd/ctrl_iface.c
hostapd/hostapd_cli.c
src/ap/sta_info.c
src/ap/sta_info.h

index 0d0183f6e0c181242d378da80110f2e183afea80..7fc520c4880cb4b3c3d03475c4d8c86a9a6f2867 100644 (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;
 }
 
index a8a8dfb68a171ec85d4d6b58a2fa76511586d1c0..661f709e33e07212b5d3d6d5967ae93e49ac55f6 100644 (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);
index 12ccaaa08620fcb4da10650ccef1ccd6b3e186c3..833f1b23a13b7ac1b337089913458e5ba2d93dc6 100644 (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:
index 32ea46e0474ca664200d00227cf5117b2f5ae7ef..f8f5a837632ddefea88204f41490a6dceca565df 100644 (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;