xref: /freebsd/contrib/wpa/src/ap/utils.c (revision 325151a32e114f02699a301c1e74080e7c1f1a26)
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"
13*325151a3SRui 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;
46e28a4053SRui Paulo };
47e28a4053SRui Paulo 
48e28a4053SRui Paulo static int prune_associations(struct hostapd_iface *iface, void *ctx)
49e28a4053SRui Paulo {
50e28a4053SRui Paulo 	struct prune_data *data = ctx;
51e28a4053SRui Paulo 	struct sta_info *osta;
52e28a4053SRui Paulo 	struct hostapd_data *ohapd;
53e28a4053SRui Paulo 	size_t j;
54e28a4053SRui Paulo 
55e28a4053SRui Paulo 	for (j = 0; j < iface->num_bss; j++) {
56e28a4053SRui Paulo 		ohapd = iface->bss[j];
57e28a4053SRui Paulo 		if (ohapd == data->hapd)
58e28a4053SRui Paulo 			continue;
59*325151a3SRui Paulo #ifdef CONFIG_FST
60*325151a3SRui Paulo 		/* Don't prune STAs belong to same FST */
61*325151a3SRui Paulo 		if (ohapd->iface->fst &&
62*325151a3SRui Paulo 		    data->hapd->iface->fst &&
63*325151a3SRui Paulo 		    fst_are_ifaces_aggregated(ohapd->iface->fst,
64*325151a3SRui Paulo 					      data->hapd->iface->fst))
65*325151a3SRui Paulo 			continue;
66*325151a3SRui Paulo #endif /* CONFIG_FST */
67e28a4053SRui Paulo 		osta = ap_get_sta(ohapd, data->addr);
68e28a4053SRui Paulo 		if (!osta)
69e28a4053SRui Paulo 			continue;
70e28a4053SRui Paulo 
71*325151a3SRui Paulo 		wpa_printf(MSG_INFO, "%s: Prune association for " MACSTR,
72*325151a3SRui Paulo 			   ohapd->conf->iface, MAC2STR(osta->addr));
73e28a4053SRui Paulo 		ap_sta_disassociate(ohapd, osta, WLAN_REASON_UNSPECIFIED);
74e28a4053SRui Paulo 	}
75e28a4053SRui Paulo 
76e28a4053SRui Paulo 	return 0;
77e28a4053SRui Paulo }
78e28a4053SRui Paulo 
79e28a4053SRui Paulo /**
80e28a4053SRui Paulo  * hostapd_prune_associations - Remove extraneous associations
81e28a4053SRui Paulo  * @hapd: Pointer to BSS data for the most recent association
82e28a4053SRui Paulo  * @addr: Associated STA address
83e28a4053SRui Paulo  *
84e28a4053SRui Paulo  * This function looks through all radios and BSS's for previous
85e28a4053SRui Paulo  * (stale) associations of STA. If any are found they are removed.
86e28a4053SRui Paulo  */
87e28a4053SRui Paulo void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr)
88e28a4053SRui Paulo {
89e28a4053SRui Paulo 	struct prune_data data;
90e28a4053SRui Paulo 	data.hapd = hapd;
91e28a4053SRui Paulo 	data.addr = addr;
92f05cddf9SRui Paulo 	if (hapd->iface->interfaces &&
93f05cddf9SRui Paulo 	    hapd->iface->interfaces->for_each_interface)
94f05cddf9SRui Paulo 		hapd->iface->interfaces->for_each_interface(
95f05cddf9SRui Paulo 			hapd->iface->interfaces, prune_associations, &data);
96e28a4053SRui Paulo }
97