1e28a4053SRui Paulo /* 2e28a4053SRui Paulo * AP mode helper functions 3e28a4053SRui Paulo * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 4e28a4053SRui Paulo * 5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6f05cddf9SRui Paulo * See README for more details. 7e28a4053SRui Paulo */ 8e28a4053SRui Paulo 9e28a4053SRui Paulo #include "includes.h" 10e28a4053SRui Paulo 11e28a4053SRui Paulo #include "common.h" 12e28a4053SRui Paulo #include "common/ieee802_11_defs.h" 13325151a3SRui Paulo #include "fst/fst.h" 14e28a4053SRui Paulo #include "sta_info.h" 15e28a4053SRui Paulo #include "hostapd.h" 16e28a4053SRui Paulo 17e28a4053SRui Paulo 18e28a4053SRui Paulo int hostapd_register_probereq_cb(struct hostapd_data *hapd, 19e28a4053SRui Paulo int (*cb)(void *ctx, const u8 *sa, 20f05cddf9SRui Paulo const u8 *da, const u8 *bssid, 21f05cddf9SRui Paulo const u8 *ie, size_t ie_len, 22f05cddf9SRui Paulo int ssi_signal), 23e28a4053SRui Paulo void *ctx) 24e28a4053SRui Paulo { 25e28a4053SRui Paulo struct hostapd_probereq_cb *n; 26e28a4053SRui Paulo 27f05cddf9SRui Paulo n = os_realloc_array(hapd->probereq_cb, hapd->num_probereq_cb + 1, 28e28a4053SRui Paulo sizeof(struct hostapd_probereq_cb)); 29e28a4053SRui Paulo if (n == NULL) 30e28a4053SRui Paulo return -1; 31e28a4053SRui Paulo 32e28a4053SRui Paulo hapd->probereq_cb = n; 33e28a4053SRui Paulo n = &hapd->probereq_cb[hapd->num_probereq_cb]; 34e28a4053SRui Paulo hapd->num_probereq_cb++; 35e28a4053SRui Paulo 36e28a4053SRui Paulo n->cb = cb; 37e28a4053SRui Paulo n->ctx = ctx; 38e28a4053SRui Paulo 39e28a4053SRui Paulo return 0; 40e28a4053SRui Paulo } 41e28a4053SRui Paulo 42e28a4053SRui Paulo 43e28a4053SRui Paulo struct prune_data { 44e28a4053SRui Paulo struct hostapd_data *hapd; 45e28a4053SRui Paulo const u8 *addr; 46*a90b9d01SCy Schubert int mld_assoc_link_id; 47e28a4053SRui Paulo }; 48e28a4053SRui Paulo 49e28a4053SRui Paulo static int prune_associations(struct hostapd_iface *iface, void *ctx) 50e28a4053SRui Paulo { 51e28a4053SRui Paulo struct prune_data *data = ctx; 52e28a4053SRui Paulo struct sta_info *osta; 53e28a4053SRui Paulo struct hostapd_data *ohapd; 54e28a4053SRui Paulo size_t j; 55e28a4053SRui Paulo 56e28a4053SRui Paulo for (j = 0; j < iface->num_bss; j++) { 57e28a4053SRui Paulo ohapd = iface->bss[j]; 58e28a4053SRui Paulo if (ohapd == data->hapd) 59e28a4053SRui Paulo continue; 60c1d255d3SCy Schubert #ifdef CONFIG_TESTING_OPTIONS 61c1d255d3SCy Schubert if (ohapd->conf->skip_prune_assoc) 62c1d255d3SCy Schubert continue; 63c1d255d3SCy Schubert #endif /* CONFIG_TESTING_OPTIONS */ 64325151a3SRui Paulo #ifdef CONFIG_FST 65325151a3SRui Paulo /* Don't prune STAs belong to same FST */ 66325151a3SRui Paulo if (ohapd->iface->fst && 67325151a3SRui Paulo data->hapd->iface->fst && 68325151a3SRui Paulo fst_are_ifaces_aggregated(ohapd->iface->fst, 69325151a3SRui Paulo data->hapd->iface->fst)) 70325151a3SRui Paulo continue; 71325151a3SRui Paulo #endif /* CONFIG_FST */ 72e28a4053SRui Paulo osta = ap_get_sta(ohapd, data->addr); 73e28a4053SRui Paulo if (!osta) 74e28a4053SRui Paulo continue; 75e28a4053SRui Paulo 76*a90b9d01SCy Schubert #ifdef CONFIG_IEEE80211BE 77*a90b9d01SCy Schubert if (data->mld_assoc_link_id >= 0 && 78*a90b9d01SCy Schubert osta->mld_assoc_link_id == data->mld_assoc_link_id) 79*a90b9d01SCy Schubert continue; 80*a90b9d01SCy Schubert #endif /* CONFIG_IEEE80211BE */ 81*a90b9d01SCy Schubert 82325151a3SRui Paulo wpa_printf(MSG_INFO, "%s: Prune association for " MACSTR, 83325151a3SRui Paulo ohapd->conf->iface, MAC2STR(osta->addr)); 84e28a4053SRui Paulo ap_sta_disassociate(ohapd, osta, WLAN_REASON_UNSPECIFIED); 85e28a4053SRui Paulo } 86e28a4053SRui Paulo 87e28a4053SRui Paulo return 0; 88e28a4053SRui Paulo } 89e28a4053SRui Paulo 90e28a4053SRui Paulo /** 91e28a4053SRui Paulo * hostapd_prune_associations - Remove extraneous associations 92e28a4053SRui Paulo * @hapd: Pointer to BSS data for the most recent association 93e28a4053SRui Paulo * @addr: Associated STA address 94*a90b9d01SCy Schubert * @mld_assoc_link_id: MLD link id used for association or -1 for non MLO 95e28a4053SRui Paulo * 96e28a4053SRui Paulo * This function looks through all radios and BSS's for previous 97e28a4053SRui Paulo * (stale) associations of STA. If any are found they are removed. 98e28a4053SRui Paulo */ 99*a90b9d01SCy Schubert void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr, 100*a90b9d01SCy Schubert int mld_assoc_link_id) 101e28a4053SRui Paulo { 102e28a4053SRui Paulo struct prune_data data; 103*a90b9d01SCy Schubert 104e28a4053SRui Paulo data.hapd = hapd; 105e28a4053SRui Paulo data.addr = addr; 106*a90b9d01SCy Schubert data.mld_assoc_link_id = mld_assoc_link_id; 107*a90b9d01SCy Schubert 108f05cddf9SRui Paulo if (hapd->iface->interfaces && 109f05cddf9SRui Paulo hapd->iface->interfaces->for_each_interface) 110f05cddf9SRui Paulo hapd->iface->interfaces->for_each_interface( 111f05cddf9SRui Paulo hapd->iface->interfaces, prune_associations, &data); 112e28a4053SRui Paulo } 113