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