Exemplo n.º 1
0
static void mbo_ap_wnm_notif_req_elem(struct sta_info *sta, u8 type,
				      const u8 *buf, size_t len,
				      int *first_non_pref_chan)
{
	switch (type) {
	case WFA_WNM_NOTIF_SUBELEM_NON_PREF_CHAN_REPORT:
		if (*first_non_pref_chan) {
			/*
			 * Need to free the previously stored entries now to
			 * allow the update to replace all entries.
			 */
			*first_non_pref_chan = 0;
			mbo_ap_sta_free(sta);
		}
		mbo_ap_parse_non_pref_chan(sta, buf, len);
		break;
	case WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA:
		mbo_ap_wnm_notif_req_cell_capa(sta, buf, len);
		break;
	default:
		wpa_printf(MSG_DEBUG,
			   "MBO: Ignore unknown WNM Notification WFA subelement %u",
			   type);
		break;
	}
}
Exemplo n.º 2
0
void mbo_ap_check_sta_assoc(struct hostapd_data *hapd, struct sta_info *sta,
			    struct ieee802_11_elems *elems)
{
	const u8 *pos, *attr, *end;
	size_t len;

	if (!hapd->conf->mbo_enabled || !elems->mbo)
		return;

	pos = elems->mbo + 4;
	len = elems->mbo_len - 4;
	wpa_hexdump(MSG_DEBUG, "MBO: Association Request attributes", pos, len);

	attr = get_ie(pos, len, MBO_ATTR_ID_CELL_DATA_CAPA);
	if (attr && attr[1] >= 1)
		sta->cell_capa = attr[2];

	mbo_ap_sta_free(sta);
	end = pos + len;
	while (end - pos > 1) {
		u8 ie_len = pos[1];

		if (2 + ie_len > end - pos)
			break;

		if (pos[0] == MBO_ATTR_ID_NON_PREF_CHAN_REPORT)
			mbo_ap_parse_non_pref_chan(sta, pos + 2, ie_len);
		pos += 2 + pos[1];
	}
}
Exemplo n.º 3
0
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
    int set_beacon = 0;

    accounting_sta_stop(hapd, sta);

    /* just in case */
    ap_sta_set_authorized(hapd, sta, 0);

    if (sta->flags & WLAN_STA_WDS)
        hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);

    if (sta->ipaddr)
        hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
    ap_sta_ip6addr_del(hapd, sta);

    if (!hapd->iface->driver_ap_teardown &&
            !(sta->flags & WLAN_STA_PREAUTH)) {
        hostapd_drv_sta_remove(hapd, sta->addr);
        sta->added_unassoc = 0;
    }

    ap_sta_hash_del(hapd, sta);
    ap_sta_list_del(hapd, sta);

    if (sta->aid > 0)
        hapd->sta_aid[(sta->aid - 1) / 32] &=
            ~BIT((sta->aid - 1) % 32);

    hapd->num_sta--;
    if (sta->nonerp_set) {
        sta->nonerp_set = 0;
        hapd->iface->num_sta_non_erp--;
        if (hapd->iface->num_sta_non_erp == 0)
            set_beacon++;
    }

    if (sta->no_short_slot_time_set) {
        sta->no_short_slot_time_set = 0;
        hapd->iface->num_sta_no_short_slot_time--;
        if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
                && hapd->iface->num_sta_no_short_slot_time == 0)
            set_beacon++;
    }

    if (sta->no_short_preamble_set) {
        sta->no_short_preamble_set = 0;
        hapd->iface->num_sta_no_short_preamble--;
        if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
                && hapd->iface->num_sta_no_short_preamble == 0)
            set_beacon++;
    }

    if (sta->no_ht_gf_set) {
        sta->no_ht_gf_set = 0;
        hapd->iface->num_sta_ht_no_gf--;
    }

    if (sta->no_ht_set) {
        sta->no_ht_set = 0;
        hapd->iface->num_sta_no_ht--;
    }

    if (sta->ht_20mhz_set) {
        sta->ht_20mhz_set = 0;
        hapd->iface->num_sta_ht_20mhz--;
    }

#ifdef CONFIG_TAXONOMY
    wpabuf_free(sta->probe_ie_taxonomy);
    sta->probe_ie_taxonomy = NULL;
    wpabuf_free(sta->assoc_ie_taxonomy);
    sta->assoc_ie_taxonomy = NULL;
#endif /* CONFIG_TAXONOMY */

#ifdef CONFIG_IEEE80211N
    ht40_intolerant_remove(hapd->iface, sta);
#endif /* CONFIG_IEEE80211N */

#ifdef CONFIG_P2P
    if (sta->no_p2p_set) {
        sta->no_p2p_set = 0;
        hapd->num_sta_no_p2p--;
        if (hapd->num_sta_no_p2p == 0)
            hostapd_p2p_non_p2p_sta_disconnected(hapd);
    }
#endif /* CONFIG_P2P */

#if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
    if (hostapd_ht_operation_update(hapd->iface) > 0)
        set_beacon++;
#endif /* NEED_AP_MLME && CONFIG_IEEE80211N */

#ifdef CONFIG_MESH
    if (hapd->mesh_sta_free_cb)
        hapd->mesh_sta_free_cb(hapd, sta);
#endif /* CONFIG_MESH */

    if (set_beacon)
        ieee802_11_set_beacons(hapd->iface);

    wpa_printf(MSG_DEBUG, "%s: cancel ap_handle_timer for " MACSTR,
               __func__, MAC2STR(sta->addr));
    eloop_cancel_timeout(ap_handle_timer, hapd, sta);
    eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
    eloop_cancel_timeout(ap_handle_session_warning_timer, hapd, sta);
    ap_sta_clear_disconnect_timeouts(hapd, sta);
    sae_clear_retransmit_timer(hapd, sta);

    ieee802_1x_free_station(hapd, sta);
    wpa_auth_sta_deinit(sta->wpa_sm);
    rsn_preauth_free_station(hapd, sta);
#ifndef CONFIG_NO_RADIUS
    if (hapd->radius)
        radius_client_flush_auth(hapd->radius, sta->addr);
#endif /* CONFIG_NO_RADIUS */

#ifndef CONFIG_NO_VLAN
    /*
     * sta->wpa_sm->group needs to be released before so that
     * vlan_remove_dynamic() can check that no stations are left on the
     * AP_VLAN netdev.
     */
    if (sta->vlan_id)
        vlan_remove_dynamic(hapd, sta->vlan_id);
    if (sta->vlan_id_bound) {
        /*
         * Need to remove the STA entry before potentially removing the
         * VLAN.
         */
        if (hapd->iface->driver_ap_teardown &&
                !(sta->flags & WLAN_STA_PREAUTH)) {
            hostapd_drv_sta_remove(hapd, sta->addr);
            sta->added_unassoc = 0;
        }
        vlan_remove_dynamic(hapd, sta->vlan_id_bound);
    }
#endif /* CONFIG_NO_VLAN */

    os_free(sta->challenge);

#ifdef CONFIG_IEEE80211W
    os_free(sta->sa_query_trans_id);
    eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
#endif /* CONFIG_IEEE80211W */

#ifdef CONFIG_P2P
    p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
#endif /* CONFIG_P2P */

#ifdef CONFIG_INTERWORKING
    if (sta->gas_dialog) {
        int i;
        for (i = 0; i < GAS_DIALOG_MAX; i++)
            gas_serv_dialog_clear(&sta->gas_dialog[i]);
        os_free(sta->gas_dialog);
    }
#endif /* CONFIG_INTERWORKING */

    wpabuf_free(sta->wps_ie);
    wpabuf_free(sta->p2p_ie);
    wpabuf_free(sta->hs20_ie);
#ifdef CONFIG_FST
    wpabuf_free(sta->mb_ies);
#endif /* CONFIG_FST */

    os_free(sta->ht_capabilities);
    os_free(sta->vht_capabilities);
    hostapd_free_psk_list(sta->psk);
    os_free(sta->identity);
    os_free(sta->radius_cui);
    os_free(sta->remediation_url);
    wpabuf_free(sta->hs20_deauth_req);
    os_free(sta->hs20_session_info_url);

#ifdef CONFIG_SAE
    sae_clear_data(sta->sae);
    os_free(sta->sae);
#endif /* CONFIG_SAE */

    mbo_ap_sta_free(sta);
    os_free(sta->supp_op_classes);

    os_free(sta);
}