hostapd/wpa_supplicant/bssid_ignore.c
Jouni Malinen 2d83d224ff Use ether_addr_equal() to compare whether two MAC addresses are equal
This was done with spatch using the following semantic patch and minor
manual edits to clean up coding style and avoid compiler warnings in
driver_wext.c:

@@
expression a,b;
@@
-	os_memcmp(a, b, ETH_ALEN) == 0
+	ether_addr_equal(a, b)

@@
expression a,b;
@@
-	os_memcmp(a, b, ETH_ALEN) != 0
+	!ether_addr_equal(a, b)

@@
expression a,b;
@@
-	!os_memcmp(a, b, ETH_ALEN)
+	ether_addr_equal(a, b)

Signed-off-by: Jouni Malinen <j@w1.fi>
2024-01-13 23:47:21 +02:00

221 lines
5.3 KiB
C

/*
* wpa_supplicant - List of temporarily ignored BSSIDs
* Copyright (c) 2003-2021, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "common.h"
#include "wpa_supplicant_i.h"
#include "bssid_ignore.h"
/**
* wpa_bssid_ignore_get - Get the ignore list entry for a BSSID
* @wpa_s: Pointer to wpa_supplicant data
* @bssid: BSSID
* Returns: Matching entry for the BSSID or %NULL if not found
*/
struct wpa_bssid_ignore * wpa_bssid_ignore_get(struct wpa_supplicant *wpa_s,
const u8 *bssid)
{
struct wpa_bssid_ignore *e;
if (wpa_s == NULL || bssid == NULL)
return NULL;
if (wpa_s->current_ssid &&
wpa_s->current_ssid->was_recently_reconfigured) {
wpa_bssid_ignore_clear(wpa_s);
wpa_s->current_ssid->was_recently_reconfigured = false;
return NULL;
}
wpa_bssid_ignore_update(wpa_s);
e = wpa_s->bssid_ignore;
while (e) {
if (ether_addr_equal(e->bssid, bssid))
return e;
e = e->next;
}
return NULL;
}
/**
* wpa_bssid_ignore_add - Add an BSSID to the ignore list
* @wpa_s: Pointer to wpa_supplicant data
* @bssid: BSSID to be added to the ignore list
* Returns: Current ignore list count on success, -1 on failure
*
* This function adds the specified BSSID to the ignore list or increases the
* ignore count if the BSSID was already listed. It should be called when
* an association attempt fails either due to the selected BSS rejecting
* association or due to timeout.
*
* This ignore list is used to force %wpa_supplicant to go through all available
* BSSes before retrying to associate with an BSS that rejected or timed out
* association. It does not prevent the listed BSS from being used; it only
* changes the order in which they are tried.
*/
int wpa_bssid_ignore_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_bssid_ignore *e;
struct os_reltime now;
if (wpa_s == NULL || bssid == NULL)
return -1;
e = wpa_bssid_ignore_get(wpa_s, bssid);
os_get_reltime(&now);
if (e) {
e->start = now;
e->count++;
if (e->count > 5)
e->timeout_secs = 1800;
else if (e->count == 5)
e->timeout_secs = 600;
else if (e->count == 4)
e->timeout_secs = 120;
else if (e->count == 3)
e->timeout_secs = 60;
else
e->timeout_secs = 10;
wpa_msg(wpa_s, MSG_INFO, "BSSID " MACSTR
" ignore list count incremented to %d, ignoring for %d seconds",
MAC2STR(bssid), e->count, e->timeout_secs);
return e->count;
}
e = os_zalloc(sizeof(*e));
if (e == NULL)
return -1;
os_memcpy(e->bssid, bssid, ETH_ALEN);
e->count = 1;
e->timeout_secs = 10;
e->start = now;
e->next = wpa_s->bssid_ignore;
wpa_s->bssid_ignore = e;
wpa_msg(wpa_s, MSG_INFO, "Added BSSID " MACSTR
" into ignore list, ignoring for %d seconds",
MAC2STR(bssid), e->timeout_secs);
return e->count;
}
/**
* wpa_bssid_ignore_del - Remove an BSSID from the ignore list
* @wpa_s: Pointer to wpa_supplicant data
* @bssid: BSSID to be removed from the ignore list
* Returns: 0 on success, -1 on failure
*/
int wpa_bssid_ignore_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_bssid_ignore *e, *prev = NULL;
if (wpa_s == NULL || bssid == NULL)
return -1;
e = wpa_s->bssid_ignore;
while (e) {
if (ether_addr_equal(e->bssid, bssid)) {
if (prev == NULL) {
wpa_s->bssid_ignore = e->next;
} else {
prev->next = e->next;
}
wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
" from ignore list", MAC2STR(bssid));
os_free(e);
return 0;
}
prev = e;
e = e->next;
}
return -1;
}
/**
* wpa_bssid_ignore_is_listed - Check whether a BSSID is ignored temporarily
* @wpa_s: Pointer to wpa_supplicant data
* @bssid: BSSID to be checked
* Returns: count if BSS is currently considered to be ignored, 0 otherwise
*/
int wpa_bssid_ignore_is_listed(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_bssid_ignore *e;
struct os_reltime now;
e = wpa_bssid_ignore_get(wpa_s, bssid);
if (!e)
return 0;
os_get_reltime(&now);
if (os_reltime_expired(&now, &e->start, e->timeout_secs))
return 0;
return e->count;
}
/**
* wpa_bssid_ignore_clear - Clear the ignore list of all entries
* @wpa_s: Pointer to wpa_supplicant data
*/
void wpa_bssid_ignore_clear(struct wpa_supplicant *wpa_s)
{
struct wpa_bssid_ignore *e, *prev;
e = wpa_s->bssid_ignore;
wpa_s->bssid_ignore = NULL;
while (e) {
prev = e;
e = e->next;
wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
" from ignore list (clear)", MAC2STR(prev->bssid));
os_free(prev);
}
}
/**
* wpa_bssid_ignore_update - Update the entries in the ignore list,
* deleting entries that have been expired for over an hour.
* @wpa_s: Pointer to wpa_supplicant data
*/
void wpa_bssid_ignore_update(struct wpa_supplicant *wpa_s)
{
struct wpa_bssid_ignore *e, *prev = NULL;
struct os_reltime now;
if (!wpa_s)
return;
e = wpa_s->bssid_ignore;
os_get_reltime(&now);
while (e) {
if (os_reltime_expired(&now, &e->start,
e->timeout_secs + 3600)) {
struct wpa_bssid_ignore *to_delete = e;
if (prev) {
prev->next = e->next;
e = prev->next;
} else {
wpa_s->bssid_ignore = e->next;
e = wpa_s->bssid_ignore;
}
wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
" from ignore list (expired)",
MAC2STR(to_delete->bssid));
os_free(to_delete);
} else {
prev = e;
e = e->next;
}
}
}