IEEE 802.11w: Added association ping

This updates management frame protection to use the assocition ping process
from the latest draft (D6.0) to protect against unauthenticated
authenticate or (re)associate frames dropping association.
This commit is contained in:
Jouni Malinen 2008-08-31 11:04:47 +03:00
parent 1e858f69d9
commit 5d22a1d5aa
13 changed files with 353 additions and 15 deletions

View file

@ -1814,6 +1814,7 @@ static void ieee80211_rx_mgmt_probe_req(struct wpa_supplicant *wpa_s,
}
#ifdef CONFIG_IEEE80211R
static void ieee80211_rx_mgmt_ft_action(struct wpa_supplicant *wpa_s,
struct ieee80211_mgmt *mgmt,
size_t len,
@ -1873,6 +1874,78 @@ static void ieee80211_rx_mgmt_ft_action(struct wpa_supplicant *wpa_s,
os_memcpy(wpa_s->bssid, target_ap_addr, ETH_ALEN);
ieee80211_associate(wpa_s);
}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
/* MLME-PING.response */
static int ieee80211_sta_send_ping_resp(struct wpa_supplicant *wpa_s,
const u8 *addr, const u8 *trans_id)
{
struct ieee80211_mgmt *mgmt;
int res;
size_t len;
mgmt = os_zalloc(sizeof(*mgmt));
if (mgmt == NULL) {
wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for "
"ping action frame");
return -1;
}
len = 24;
os_memcpy(mgmt->da, addr, ETH_ALEN);
os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
WLAN_FC_STYPE_ACTION);
mgmt->u.action.category = WLAN_ACTION_PING;
mgmt->u.action.u.ping_resp.action = WLAN_PING_RESPONSE;
os_memcpy(mgmt->u.action.u.ping_resp.trans_id, trans_id,
WLAN_PING_TRANS_ID_LEN);
len += 1 + sizeof(mgmt->u.action.u.ping_resp);
res = ieee80211_sta_tx(wpa_s, (u8 *) mgmt, len);
os_free(mgmt);
return res;
}
static void ieee80211_rx_mgmt_ping_action(
struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
struct ieee80211_rx_status *rx_status)
{
if (len < 24 + 1 + sizeof(mgmt->u.action.u.ping_req)) {
wpa_printf(MSG_DEBUG, "MLME: Too short Ping Action frame");
return;
}
if (mgmt->u.action.u.ping_req.action != WLAN_PING_REQUEST) {
wpa_printf(MSG_DEBUG, "MLME: Unexpected Ping Action %d",
mgmt->u.action.u.ping_req.action);
return;
}
if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_DEBUG, "MLME: Ignore ping from unknown source "
MACSTR, MAC2STR(mgmt->sa));
return;
}
if (wpa_s->mlme.state == IEEE80211_ASSOCIATE) {
wpa_printf(MSG_DEBUG, "MLME: Ignore ping request during "
"association process");
return;
}
wpa_printf(MSG_DEBUG, "MLME: Replying to ping request");
ieee80211_sta_send_ping_resp(wpa_s, mgmt->sa,
mgmt->u.action.u.ping_req.trans_id);
}
#endif /* CONFIG_IEEE80211W */
static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s,
@ -1885,11 +1958,22 @@ static void ieee80211_rx_mgmt_action(struct wpa_supplicant *wpa_s,
if (len < 25)
return;
if (mgmt->u.action.category == WLAN_ACTION_FT)
switch (mgmt->u.action.category) {
#ifdef CONFIG_IEEE80211R
case WLAN_ACTION_FT:
ieee80211_rx_mgmt_ft_action(wpa_s, mgmt, len, rx_status);
else
break;
#endif /* CONFIG_IEEE80211R */
case WLAN_ACTION_PING:
ieee80211_rx_mgmt_ping_action(wpa_s, mgmt, len, rx_status);
break;
#ifdef CONFIG_IEEE80211W
#endif /* CONFIG_IEEE80211W */
default:
wpa_printf(MSG_DEBUG, "MLME: unknown Action Category %d",
mgmt->u.action.category);
break;
}
}