Example #1
0
static void hostapd_action_rx(struct hostapd_data *hapd,
			      struct rx_action *action)
{
	struct sta_info *sta;

        wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d",
		   action->category, (int) action->len);

	sta = ap_get_sta(hapd, action->sa);
	if (sta == NULL) {
		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
		return;
	}
#ifdef CONFIG_IEEE80211R
	if (action->category == WLAN_ACTION_FT) {
		wpa_printf(MSG_DEBUG, "%s: FT_ACTION length %d",
			   __func__, (int) action->len);
		wpa_ft_action_rx(sta->wpa_sm, action->data, action->len);
	}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
	if (action->category == WLAN_ACTION_SA_QUERY && action->len >= 4) {
		wpa_printf(MSG_DEBUG, "%s: SA_QUERY_ACTION length %d",
			   __func__, (int) action->len);
		ieee802_11_sa_query_action(hapd, action->sa,
					   *(action->data + 1),
					   action->data + 2);
	}
#endif /* CONFIG_IEEE80211W */
}
static void hostapd_action_rx(struct hostapd_data *hapd,
			      struct rx_mgmt *drv_mgmt)
{
	struct ieee80211_mgmt *mgmt;
	struct sta_info *sta;
	size_t plen __maybe_unused;
	u16 fc;

	if (drv_mgmt->frame_len < 24 + 1)
		return;

	plen = drv_mgmt->frame_len - 24 - 1;

	mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
	fc = le_to_host16(mgmt->frame_control);
	if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
		return; /* handled by the driver */

	wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d",
		   mgmt->u.action.category, (int) plen);

	sta = ap_get_sta(hapd, mgmt->sa);
	if (sta == NULL) {
		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
		return;
	}
#ifdef CONFIG_IEEE80211R
	if (mgmt->u.action.category == WLAN_ACTION_FT) {
		const u8 *payload = drv_mgmt->frame + 24 + 1;

		wpa_ft_action_rx(sta->wpa_sm, payload, plen);
	}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
	if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY && plen >= 4) {
		ieee802_11_sa_query_action(
			hapd, mgmt->sa,
			mgmt->u.action.u.sa_query_resp.action,
			mgmt->u.action.u.sa_query_resp.trans_id);
	}
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WNM
	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
		ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
	}
#endif /* CONFIG_WNM */
#ifdef CONFIG_FST
	if (mgmt->u.action.category == WLAN_ACTION_FST && hapd->iface->fst) {
		fst_rx_action(hapd->iface->fst, mgmt, drv_mgmt->frame_len);
		return;
	}
#endif /* CONFIG_FST */

}
Example #3
0
static void hostapd_action_rx(struct hostapd_data *hapd,
			      struct rx_action *action)
{
	struct sta_info *sta;

	sta = ap_get_sta(hapd, action->sa);
	if (sta == NULL) {
		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
		return;
	}
#ifdef CONFIG_IEEE80211R
	if (action->category == WLAN_ACTION_FT) {
		wpa_printf(MSG_DEBUG, "%s: FT_ACTION length %d",
			   __func__, action->len);
		wpa_ft_action_rx(sta->wpa_sm, action->data, action->len);
	}
#endif /* CONFIG_IEEE80211R */
}
static void hostapd_action_rx(struct hostapd_data *hapd,
			      struct rx_mgmt *drv_mgmt)
{
	struct ieee80211_mgmt *mgmt;
	struct sta_info *sta;
	size_t plen __maybe_unused;
	u16 fc;
	u8 *action __maybe_unused;

	if (drv_mgmt->frame_len < IEEE80211_HDRLEN + 2 + 1)
		return;

	plen = drv_mgmt->frame_len - IEEE80211_HDRLEN;

	mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
	fc = le_to_host16(mgmt->frame_control);
	if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
		return; /* handled by the driver */

	action = (u8 *) &mgmt->u.action.u;
	wpa_printf(MSG_DEBUG, "RX_ACTION category %u action %u sa " MACSTR
		   " da " MACSTR " plen %d",
		   mgmt->u.action.category, *action,
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), (int) plen);

	sta = ap_get_sta(hapd, mgmt->sa);
	if (sta == NULL) {
		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
		return;
	}
#ifdef CONFIG_IEEE80211R_AP
	if (mgmt->u.action.category == WLAN_ACTION_FT) {
		wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, plen);
		return;
	}
#endif /* CONFIG_IEEE80211R_AP */
#ifdef CONFIG_IEEE80211W
	if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY) {
		ieee802_11_sa_query_action(hapd, mgmt, drv_mgmt->frame_len);
		return;
	}
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WNM_AP
	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
		ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
		return;
	}
#endif /* CONFIG_WNM_AP */
#ifdef CONFIG_FST
	if (mgmt->u.action.category == WLAN_ACTION_FST && hapd->iface->fst) {
		fst_rx_action(hapd->iface->fst, mgmt, drv_mgmt->frame_len);
		return;
	}
#endif /* CONFIG_FST */
#ifdef CONFIG_DPP
	if (plen >= 2 + 4 &&
	    mgmt->u.action.u.vs_public_action.action ==
	    WLAN_PA_VENDOR_SPECIFIC &&
	    WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
	    OUI_WFA &&
	    mgmt->u.action.u.vs_public_action.variable[0] ==
	    DPP_OUI_TYPE) {
		const u8 *pos, *end;

		pos = mgmt->u.action.u.vs_public_action.oui;
		end = drv_mgmt->frame + drv_mgmt->frame_len;
		hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
				      drv_mgmt->freq);
		return;
	}
#endif /* CONFIG_DPP */
}
Example #5
0
static void handle_action(struct hostapd_data *hapd,
			  const struct ieee80211_mgmt *mgmt, size_t len)
{
	struct sta_info *sta;

	if (len < IEEE80211_HDRLEN + 1) {
		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_DEBUG,
			       "handle_action - too short payload (len=%lu)",
			       (unsigned long) len);
		return;
	}

	sta = ap_get_sta(hapd, mgmt->sa);
#ifdef CONFIG_IEEE80211W
	if (sta && (sta->flags & WLAN_STA_MFP) &&
	    !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) &&
	      robust_action_frame(mgmt->u.action.category))) {
		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_DEBUG,
			       "Dropped unprotected Robust Action frame from "
			       "an MFP STA");
		return;
	}
#endif /* CONFIG_IEEE80211W */

	switch (mgmt->u.action.category) {
#ifdef CONFIG_IEEE80211R
	case WLAN_ACTION_FT:
	{
		if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
			wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action "
				   "frame from unassociated STA " MACSTR,
				   MAC2STR(mgmt->sa));
			return;
		}

		if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
				     len - IEEE80211_HDRLEN))
			break;

		return;
	}
#endif /* CONFIG_IEEE80211R */
	case WLAN_ACTION_WMM:
		hostapd_wmm_action(hapd, mgmt, len);
		return;
#ifdef CONFIG_IEEE80211W
	case WLAN_ACTION_SA_QUERY:
		hostapd_sa_query_action(hapd, mgmt, len);
		return;
#endif /* CONFIG_IEEE80211W */
	case WLAN_ACTION_PUBLIC:
		if (hapd->public_action_cb) {
			hapd->public_action_cb(hapd->public_action_cb_ctx,
					       (u8 *) mgmt, len,
					       hapd->iface->freq);
			return;
		}
		break;
	}

	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
		       HOSTAPD_LEVEL_DEBUG,
		       "handle_action - unknown action category %d or invalid "
		       "frame",
		       mgmt->u.action.category);
	if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
	    !(mgmt->sa[0] & 0x01)) {
		struct ieee80211_mgmt *resp;

		/*
		 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
		 * Return the Action frame to the source without change
		 * except that MSB of the Category set to 1.
		 */
		wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
			   "frame back to sender");
		resp = os_malloc(len);
		if (resp == NULL)
			return;
		os_memcpy(resp, mgmt, len);
		os_memcpy(resp->da, resp->sa, ETH_ALEN);
		os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
		os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
		resp->u.action.category |= 0x80;

		hapd->drv.send_mgmt_frame(hapd, resp, len);
		os_free(resp);
	}
}