}
+void sta_track_expire(struct hostapd_iface *iface, int force)
+{
+ struct os_reltime now;
+ struct hostapd_sta_info *info;
+
+ if (!iface->num_sta_seen)
+ return;
+
+ os_get_reltime(&now);
+ while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
+ list))) {
+ if (!force &&
+ !os_reltime_expired(&now, &info->last_seen,
+ iface->conf->track_sta_max_age))
+ break;
+ force = 0;
+
+ wpa_printf(MSG_MSGDUMP, "%s: Expire STA tracking entry for "
+ MACSTR, iface->bss[0]->conf->iface,
+ MAC2STR(info->addr));
+ dl_list_del(&info->list);
+ iface->num_sta_seen--;
+ os_free(info);
+ }
+}
+
+
+static struct hostapd_sta_info * sta_track_get(struct hostapd_iface *iface,
+ const u8 *addr)
+{
+ struct hostapd_sta_info *info;
+
+ dl_list_for_each(info, &iface->sta_seen, struct hostapd_sta_info, list)
+ if (os_memcmp(addr, info->addr, ETH_ALEN) == 0)
+ return info;
+
+ return NULL;
+}
+
+
+static void sta_track_add(struct hostapd_iface *iface, const u8 *addr)
+{
+ struct hostapd_sta_info *info;
+
+ info = sta_track_get(iface, addr);
+ if (info) {
+ /* Move the most recent entry to the end of the list */
+ dl_list_del(&info->list);
+ dl_list_add_tail(&iface->sta_seen, &info->list);
+ os_get_reltime(&info->last_seen);
+ return;
+ }
+
+ /* Add a new entry */
+ info = os_zalloc(sizeof(*info));
+ os_memcpy(info->addr, addr, ETH_ALEN);
+ os_get_reltime(&info->last_seen);
+
+ if (iface->num_sta_seen >= iface->conf->track_sta_max_num) {
+ /* Expire oldest entry to make room for a new one */
+ sta_track_expire(iface, 1);
+ }
+
+ wpa_printf(MSG_MSGDUMP, "%s: Add STA tracking entry for "
+ MACSTR, iface->bss[0]->conf->iface, MAC2STR(addr));
+ dl_list_add_tail(&iface->sta_seen, &info->list);
+ iface->num_sta_seen++;
+}
+
+
void handle_probe_req(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt, size_t len,
int ssi_signal)
ie = mgmt->u.probe_req.variable;
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
return;
+ if (hapd->iconf->track_sta_max_num)
+ sta_track_add(hapd->iface, mgmt->sa);
ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)