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