Coverage Report

Created: 2025-08-29 06:25

/src/hostap/wpa_supplicant/bssid_ignore.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * wpa_supplicant - List of temporarily ignored BSSIDs
3
 * Copyright (c) 2003-2021, 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 "wpa_supplicant_i.h"
13
#include "bssid_ignore.h"
14
15
/**
16
 * wpa_bssid_ignore_get - Get the ignore list entry for a BSSID
17
 * @wpa_s: Pointer to wpa_supplicant data
18
 * @bssid: BSSID
19
 * Returns: Matching entry for the BSSID or %NULL if not found
20
 */
21
struct wpa_bssid_ignore * wpa_bssid_ignore_get(struct wpa_supplicant *wpa_s,
22
                 const u8 *bssid)
23
0
{
24
0
  struct wpa_bssid_ignore *e;
25
26
0
  if (wpa_s == NULL || bssid == NULL)
27
0
    return NULL;
28
29
0
  if (wpa_s->current_ssid &&
30
0
      wpa_s->current_ssid->was_recently_reconfigured) {
31
0
    wpa_bssid_ignore_clear(wpa_s);
32
0
    wpa_s->current_ssid->was_recently_reconfigured = false;
33
0
    return NULL;
34
0
  }
35
36
0
  wpa_bssid_ignore_update(wpa_s);
37
38
0
  e = wpa_s->bssid_ignore;
39
0
  while (e) {
40
0
    if (ether_addr_equal(e->bssid, bssid))
41
0
      return e;
42
0
    e = e->next;
43
0
  }
44
45
0
  return NULL;
46
0
}
47
48
49
/**
50
 * wpa_bssid_ignore_add - Add an BSSID to the ignore list
51
 * @wpa_s: Pointer to wpa_supplicant data
52
 * @bssid: BSSID to be added to the ignore list
53
 * Returns: Current ignore list count on success, -1 on failure
54
 *
55
 * This function adds the specified BSSID to the ignore list or increases the
56
 * ignore count if the BSSID was already listed. It should be called when
57
 * an association attempt fails either due to the selected BSS rejecting
58
 * association or due to timeout.
59
 *
60
 * This ignore list is used to force %wpa_supplicant to go through all available
61
 * BSSes before retrying to associate with an BSS that rejected or timed out
62
 * association. It does not prevent the listed BSS from being used; it only
63
 * changes the order in which they are tried.
64
 */
65
int wpa_bssid_ignore_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
66
0
{
67
0
  struct wpa_bssid_ignore *e;
68
0
  struct os_reltime now;
69
70
0
  if (wpa_s == NULL || bssid == NULL)
71
0
    return -1;
72
73
0
  e = wpa_bssid_ignore_get(wpa_s, bssid);
74
0
  os_get_reltime(&now);
75
0
  if (e) {
76
0
    e->start = now;
77
0
    e->count++;
78
0
    if (e->count > 5)
79
0
      e->timeout_secs = 1800;
80
0
    else if (e->count == 5)
81
0
      e->timeout_secs = 600;
82
0
    else if (e->count == 4)
83
0
      e->timeout_secs = 120;
84
0
    else if (e->count == 3)
85
0
      e->timeout_secs = 60;
86
0
    else
87
0
      e->timeout_secs = 10;
88
0
    wpa_msg(wpa_s, MSG_INFO, "BSSID " MACSTR
89
0
      " ignore list count incremented to %d, ignoring for %d seconds",
90
0
      MAC2STR(bssid), e->count, e->timeout_secs);
91
0
    return e->count;
92
0
  }
93
94
0
  e = os_zalloc(sizeof(*e));
95
0
  if (e == NULL)
96
0
    return -1;
97
0
  os_memcpy(e->bssid, bssid, ETH_ALEN);
98
0
  e->count = 1;
99
0
  e->timeout_secs = 10;
100
0
  e->start = now;
101
0
  e->next = wpa_s->bssid_ignore;
102
0
  wpa_s->bssid_ignore = e;
103
0
  wpa_msg(wpa_s, MSG_INFO, "Added BSSID " MACSTR
104
0
    " into ignore list, ignoring for %d seconds",
105
0
    MAC2STR(bssid), e->timeout_secs);
106
107
0
  return e->count;
108
0
}
109
110
111
/**
112
 * wpa_bssid_ignore_del - Remove an BSSID from the ignore list
113
 * @wpa_s: Pointer to wpa_supplicant data
114
 * @bssid: BSSID to be removed from the ignore list
115
 * Returns: 0 on success, -1 on failure
116
 */
117
int wpa_bssid_ignore_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
118
0
{
119
0
  struct wpa_bssid_ignore *e, *prev = NULL;
120
121
0
  if (wpa_s == NULL || bssid == NULL)
122
0
    return -1;
123
124
0
  e = wpa_s->bssid_ignore;
125
0
  while (e) {
126
0
    if (ether_addr_equal(e->bssid, bssid)) {
127
0
      if (prev == NULL) {
128
0
        wpa_s->bssid_ignore = e->next;
129
0
      } else {
130
0
        prev->next = e->next;
131
0
      }
132
0
      wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
133
0
        " from ignore list", MAC2STR(bssid));
134
0
      os_free(e);
135
0
      return 0;
136
0
    }
137
0
    prev = e;
138
0
    e = e->next;
139
0
  }
140
0
  return -1;
141
0
}
142
143
144
/**
145
 * wpa_bssid_ignore_is_listed - Check whether a BSSID is ignored temporarily
146
 * @wpa_s: Pointer to wpa_supplicant data
147
 * @bssid: BSSID to be checked
148
 * Returns: count if BSS is currently considered to be ignored, 0 otherwise
149
 */
150
int wpa_bssid_ignore_is_listed(struct wpa_supplicant *wpa_s, const u8 *bssid)
151
0
{
152
0
  struct wpa_bssid_ignore *e;
153
0
  struct os_reltime now;
154
155
0
  e = wpa_bssid_ignore_get(wpa_s, bssid);
156
0
  if (!e)
157
0
    return 0;
158
0
  os_get_reltime(&now);
159
0
  if (os_reltime_expired(&now, &e->start, e->timeout_secs))
160
0
    return 0;
161
0
  return e->count;
162
0
}
163
164
165
/**
166
 * wpa_bssid_ignore_clear - Clear the ignore list of all entries
167
 * @wpa_s: Pointer to wpa_supplicant data
168
 */
169
void wpa_bssid_ignore_clear(struct wpa_supplicant *wpa_s)
170
0
{
171
0
  struct wpa_bssid_ignore *e, *prev;
172
173
0
  e = wpa_s->bssid_ignore;
174
0
  wpa_s->bssid_ignore = NULL;
175
0
  while (e) {
176
0
    prev = e;
177
0
    e = e->next;
178
0
    wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
179
0
      " from ignore list (clear)", MAC2STR(prev->bssid));
180
0
    os_free(prev);
181
0
  }
182
0
}
183
184
185
/**
186
 * wpa_bssid_ignore_update - Update the entries in the ignore list,
187
 * deleting entries that have been expired for over an hour.
188
 * @wpa_s: Pointer to wpa_supplicant data
189
 */
190
void wpa_bssid_ignore_update(struct wpa_supplicant *wpa_s)
191
0
{
192
0
  struct wpa_bssid_ignore *e, *prev = NULL;
193
0
  struct os_reltime now;
194
195
0
  if (!wpa_s)
196
0
    return;
197
198
0
  e = wpa_s->bssid_ignore;
199
0
  os_get_reltime(&now);
200
0
  while (e) {
201
0
    if (os_reltime_expired(&now, &e->start,
202
0
               e->timeout_secs + 3600)) {
203
0
      struct wpa_bssid_ignore *to_delete = e;
204
205
0
      if (prev) {
206
0
        prev->next = e->next;
207
0
        e = prev->next;
208
0
      } else {
209
0
        wpa_s->bssid_ignore = e->next;
210
0
        e = wpa_s->bssid_ignore;
211
0
      }
212
0
      wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
213
0
        " from ignore list (expired)",
214
0
        MAC2STR(to_delete->bssid));
215
0
      os_free(to_delete);
216
0
    } else {
217
0
      prev = e;
218
0
      e = e->next;
219
0
    }
220
0
  }
221
0
}