aboutsummaryrefslogtreecommitdiffstats
path: root/wlantest/process.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-11-06 15:55:27 (GMT)
committerJouni Malinen <j@w1.fi>2010-11-07 21:29:00 (GMT)
commitd30edf54b8541f6450f7b83b68af6b8895dafafa (patch)
tree7191669d12958b5f91f6bebfa4c90d26d977ef8f /wlantest/process.c
parent422ef7d2056e982bbd83415f5a329e996b0c2608 (diff)
downloadhostap-d30edf54b8541f6450f7b83b68af6b8895dafafa.zip
hostap-d30edf54b8541f6450f7b83b68af6b8895dafafa.tar.gz
hostap-d30edf54b8541f6450f7b83b68af6b8895dafafa.tar.bz2
wlantest: Maintain STA state based on auth/assoc/deauth/disassoc
Diffstat (limited to 'wlantest/process.c')
-rw-r--r--wlantest/process.c281
1 files changed, 278 insertions, 3 deletions
diff --git a/wlantest/process.c b/wlantest/process.c
index d47b434..8a7c5fc 100644
--- a/wlantest/process.c
+++ b/wlantest/process.c
@@ -167,6 +167,7 @@ static void rx_mgmt_auth(struct wlantest *wt, const u8 *data, size_t len)
const struct ieee80211_mgmt *mgmt;
struct wlantest_bss *bss;
struct wlantest_sta *sta;
+ u16 alg, trans, status;
mgmt = (const struct ieee80211_mgmt *) data;
bss = bss_get(wt, mgmt->bssid);
@@ -185,12 +186,268 @@ static void rx_mgmt_auth(struct wlantest *wt, const u8 *data, size_t len)
return;
}
+ alg = le_to_host16(mgmt->u.auth.auth_alg);
+ trans = le_to_host16(mgmt->u.auth.auth_transaction);
+ status = le_to_host16(mgmt->u.auth.status_code);
+
wpa_printf(MSG_DEBUG, "AUTH " MACSTR " -> " MACSTR
" (alg=%u trans=%u status=%u)",
+ MAC2STR(mgmt->sa), MAC2STR(mgmt->da), alg, trans, status);
+
+ if (alg == 0 && trans == 2 && status == 0) {
+ if (sta->state == STATE1) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR
+ " moved to State 2 with " MACSTR,
+ MAC2STR(sta->addr), MAC2STR(bss->bssid));
+ sta->state = STATE2;
+ }
+ }
+}
+
+
+static void rx_mgmt_deauth(struct wlantest *wt, const u8 *data, size_t len)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+
+ mgmt = (const struct ieee80211_mgmt *) data;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
+ sta = sta_get(bss, mgmt->da);
+ else
+ sta = sta_get(bss, mgmt->sa);
+ if (sta == NULL)
+ return;
+
+ if (len < 24 + 2) {
+ wpa_printf(MSG_INFO, "Too short Deauthentication frame from "
+ MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "DEAUTH " MACSTR " -> " MACSTR
+ " (reason=%u)",
+ MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
+ le_to_host16(mgmt->u.deauth.reason_code));
+
+ if (sta->state != STATE1) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR
+ " moved to State 1 with " MACSTR,
+ MAC2STR(sta->addr), MAC2STR(bss->bssid));
+ sta->state = STATE1;
+ }
+}
+
+
+static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+
+ mgmt = (const struct ieee80211_mgmt *) data;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ sta = sta_get(bss, mgmt->sa);
+ if (sta == NULL)
+ return;
+
+ if (len < 24 + 4) {
+ wpa_printf(MSG_INFO, "Too short Association Request frame "
+ "from " MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "ASSOCREQ " MACSTR " -> " MACSTR
+ " (capab=0x%x listen_int=%u)",
+ MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
+ le_to_host16(mgmt->u.assoc_req.capab_info),
+ le_to_host16(mgmt->u.assoc_req.listen_interval));
+}
+
+
+static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+ u16 capab, status, aid;
+
+ mgmt = (const struct ieee80211_mgmt *) data;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ sta = sta_get(bss, mgmt->da);
+ if (sta == NULL)
+ return;
+
+ if (len < 24 + 6) {
+ wpa_printf(MSG_INFO, "Too short Association Response frame "
+ "from " MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ capab = le_to_host16(mgmt->u.assoc_resp.capab_info);
+ status = le_to_host16(mgmt->u.assoc_resp.status_code);
+ aid = le_to_host16(mgmt->u.assoc_resp.aid);
+
+ wpa_printf(MSG_DEBUG, "ASSOCRESP " MACSTR " -> " MACSTR
+ " (capab=0x%x status=%u aid=%u)",
+ MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
+ aid & 0x3fff);
+
+ if (status)
+ return;
+
+ if ((aid & 0xc000) != 0xc000) {
+ wpa_printf(MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
+ "in Association Response from " MACSTR,
+ MAC2STR(mgmt->sa));
+ }
+ sta->aid = aid & 0xc000;
+
+ if (sta->state < STATE2) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 when "
+ "getting associated", MAC2STR(sta->addr));
+ }
+
+ if (sta->state < STATE3) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR
+ " moved to State 3 with " MACSTR,
+ MAC2STR(sta->addr), MAC2STR(bss->bssid));
+ sta->state = STATE3;
+ }
+}
+
+
+static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
+ size_t len)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+
+ mgmt = (const struct ieee80211_mgmt *) data;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ sta = sta_get(bss, mgmt->sa);
+ if (sta == NULL)
+ return;
+
+ if (len < 24 + 4 + ETH_ALEN) {
+ wpa_printf(MSG_INFO, "Too short Reassociation Request frame "
+ "from " MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "REASSOCREQ " MACSTR " -> " MACSTR
+ " (capab=0x%x listen_int=%u current_ap=" MACSTR ")",
MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
- le_to_host16(mgmt->u.auth.auth_alg),
- le_to_host16(mgmt->u.auth.auth_transaction),
- le_to_host16(mgmt->u.auth.status_code));
+ le_to_host16(mgmt->u.reassoc_req.capab_info),
+ le_to_host16(mgmt->u.reassoc_req.listen_interval),
+ MAC2STR(mgmt->u.reassoc_req.current_ap));
+}
+
+
+static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
+ size_t len)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+ u16 capab, status, aid;
+
+ mgmt = (const struct ieee80211_mgmt *) data;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ sta = sta_get(bss, mgmt->da);
+ if (sta == NULL)
+ return;
+
+ if (len < 24 + 6) {
+ wpa_printf(MSG_INFO, "Too short Reassociation Response frame "
+ "from " MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ capab = le_to_host16(mgmt->u.reassoc_resp.capab_info);
+ status = le_to_host16(mgmt->u.reassoc_resp.status_code);
+ aid = le_to_host16(mgmt->u.reassoc_resp.aid);
+
+ wpa_printf(MSG_DEBUG, "REASSOCRESP " MACSTR " -> " MACSTR
+ " (capab=0x%x status=%u aid=%u)",
+ MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
+ aid & 0x3fff);
+
+ if (status)
+ return;
+
+ if ((aid & 0xc000) != 0xc000) {
+ wpa_printf(MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
+ "in Reassociation Response from " MACSTR,
+ MAC2STR(mgmt->sa));
+ }
+ sta->aid = aid & 0xc000;
+
+ if (sta->state < STATE2) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 when "
+ "getting associated", MAC2STR(sta->addr));
+ }
+
+ if (sta->state < STATE3) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR
+ " moved to State 3 with " MACSTR,
+ MAC2STR(sta->addr), MAC2STR(bss->bssid));
+ sta->state = STATE3;
+ }
+}
+
+
+static void rx_mgmt_disassoc(struct wlantest *wt, const u8 *data, size_t len)
+{
+ const struct ieee80211_mgmt *mgmt;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+
+ mgmt = (const struct ieee80211_mgmt *) data;
+ bss = bss_get(wt, mgmt->bssid);
+ if (bss == NULL)
+ return;
+ if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
+ sta = sta_get(bss, mgmt->da);
+ else
+ sta = sta_get(bss, mgmt->sa);
+ if (sta == NULL)
+ return;
+
+ if (len < 24 + 2) {
+ wpa_printf(MSG_INFO, "Too short Disassociation frame from "
+ MACSTR, MAC2STR(mgmt->sa));
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "DISASSOC " MACSTR " -> " MACSTR
+ " (reason=%u)",
+ MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
+ le_to_host16(mgmt->u.disassoc.reason_code));
+
+ if (sta->state < STATE2) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 or 3 "
+ "when getting disassociated", MAC2STR(sta->addr));
+ }
+
+ if (sta->state > STATE2) {
+ wpa_printf(MSG_DEBUG, "STA " MACSTR
+ " moved to State 2 with " MACSTR,
+ MAC2STR(sta->addr), MAC2STR(bss->bssid));
+ sta->state = STATE2;
+ }
}
@@ -228,6 +485,24 @@ static void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len)
case WLAN_FC_STYPE_AUTH:
rx_mgmt_auth(wt, data, len);
break;
+ case WLAN_FC_STYPE_DEAUTH:
+ rx_mgmt_deauth(wt, data, len);
+ break;
+ case WLAN_FC_STYPE_ASSOC_REQ:
+ rx_mgmt_assoc_req(wt, data, len);
+ break;
+ case WLAN_FC_STYPE_ASSOC_RESP:
+ rx_mgmt_assoc_resp(wt, data, len);
+ break;
+ case WLAN_FC_STYPE_REASSOC_REQ:
+ rx_mgmt_reassoc_req(wt, data, len);
+ break;
+ case WLAN_FC_STYPE_REASSOC_RESP:
+ rx_mgmt_reassoc_resp(wt, data, len);
+ break;
+ case WLAN_FC_STYPE_DISASSOC:
+ rx_mgmt_disassoc(wt, data, len);
+ break;
}
}