From 5208160b4b836a65117b403bba77fbdbf246374e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 29 Jan 2017 14:09:51 +0200 Subject: [PATCH] FILS: Parse received FILS HLP requests This adds parsing of received FILS HLP requests from (Re)Association Request frames. The reassembled requests are verified to be in valid format and are printed in debug output. However, actual processing or forwarding of the packets is not yet implemented, i.e., the vendor specific frame filtering logic is for now practically dropping all HLP requests. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 92a7ec6db..cceeee044 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2407,6 +2407,85 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, } +#ifdef CONFIG_FILS + +static void fils_process_hlp_req(struct hostapd_data *hapd, + struct sta_info *sta, + const u8 *pos, size_t len) +{ + const u8 *pkt, *end; + + wpa_printf(MSG_DEBUG, "FILS: HLP request from " MACSTR " (dst=" MACSTR + " src=" MACSTR " len=%u)", + MAC2STR(sta->addr), MAC2STR(pos), MAC2STR(pos + ETH_ALEN), + (unsigned int) len); + if (os_memcmp(sta->addr, pos + ETH_ALEN, ETH_ALEN) != 0) { + wpa_printf(MSG_DEBUG, + "FILS: Ignore HLP request with unexpected source address" + MACSTR, MAC2STR(pos + ETH_ALEN)); + return; + } + + end = pos + len; + pkt = pos + 2 * ETH_ALEN; + if (end - pkt >= 6 && + os_memcmp(pkt, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) + pkt += 6; /* Remove SNAP/LLC header */ + wpa_hexdump(MSG_MSGDUMP, "FILS: HLP request packet", pkt, end - pkt); +} + + +static void fils_process_hlp(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *pos, int left) +{ + const u8 *end = pos + left; + u8 *tmp, *tmp_pos; + + /* Check if there are any FILS HLP Container elements */ + while (end - pos >= 2) { + if (2 + pos[1] > end - pos) + return; + if (pos[0] == WLAN_EID_EXTENSION && + pos[1] >= 1 + 2 * ETH_ALEN && + pos[2] == WLAN_EID_EXT_FILS_HLP_CONTAINER) + break; + pos += 2 + pos[1]; + } + if (end - pos < 2) + return; /* No FILS HLP Container elements */ + + tmp = os_malloc(end - pos); + if (!tmp) + return; + + while (end - pos >= 2) { + if (2 + pos[1] > end - pos || + pos[0] != WLAN_EID_EXTENSION || + pos[1] < 1 + 2 * ETH_ALEN || + pos[2] != WLAN_EID_EXT_FILS_HLP_CONTAINER) + break; + tmp_pos = tmp; + os_memcpy(tmp_pos, pos + 3, pos[1] - 1); + tmp_pos += pos[1] - 1; + pos += 2 + pos[1]; + + /* Add possible fragments */ + while (end - pos >= 2 && pos[0] == WLAN_EID_FRAGMENT && + 2 + pos[1] <= end - pos) { + os_memcpy(tmp_pos, pos + 2, pos[1]); + tmp_pos += pos[1]; + pos += 2 + pos[1]; + } + + fils_process_hlp_req(hapd, sta, tmp, tmp_pos - tmp); + } + + os_free(tmp); +} + +#endif /* CONFIG_FILS */ + + static void handle_assoc(struct hostapd_data *hapd, const struct ieee80211_mgmt *mgmt, size_t len, int reassoc) @@ -2678,6 +2757,13 @@ static void handle_assoc(struct hostapd_data *hapd, sta->pending_wds_enable = 0; +#ifdef CONFIG_FILS + if (sta->auth_alg == WLAN_AUTH_FILS_SK || + sta->auth_alg == WLAN_AUTH_FILS_SK_PFS || + sta->auth_alg == WLAN_AUTH_FILS_PK) + fils_process_hlp(hapd, sta, pos, left); +#endif /* CONFIG_FILS */ + fail: /* * In case of a successful response, add the station to the driver.