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