]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/mlme.c
IEEE 802.11w: Added association ping
[thirdparty/hostap.git] / wpa_supplicant / mlme.c
index 6f0fdf1271ac7606a7f05656e29b5267ff1c2035..61fec6c8a23411e2ed994109fd96ee7d9fc04d25 100644 (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;
+       }
 }