/* * hostapd / Neighboring APs DB * Copyright(c) 2013 - 2016 Intel Mobile Communications GmbH. * Copyright(c) 2011 - 2016 Intel Corporation. All rights reserved. * * This software may be distributed under the terms of the BSD license. * See README for more details. */ #include "utils/includes.h" #include "utils/common.h" #include "hostapd.h" #include "neighbor_db.h" struct hostapd_neighbor_entry * hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid, const struct wpa_ssid_value *ssid) { struct hostapd_neighbor_entry *nr; dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry, list) { if (os_memcmp(bssid, nr->bssid, ETH_ALEN) == 0 && (!ssid || (ssid->ssid_len == nr->ssid.ssid_len && os_memcmp(ssid->ssid, nr->ssid.ssid, ssid->ssid_len) == 0))) return nr; } return NULL; } static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr) { wpabuf_free(nr->nr); nr->nr = NULL; wpabuf_free(nr->lci); nr->lci = NULL; wpabuf_free(nr->civic); nr->civic = NULL; os_memset(nr->bssid, 0, sizeof(nr->bssid)); os_memset(&nr->ssid, 0, sizeof(nr->ssid)); nr->stationary = 0; } static struct hostapd_neighbor_entry * hostapd_neighbor_add(struct hostapd_data *hapd) { struct hostapd_neighbor_entry *nr; nr = os_zalloc(sizeof(struct hostapd_neighbor_entry)); if (!nr) return NULL; dl_list_add(&hapd->nr_db, &nr->list); return nr; } int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid, const struct wpa_ssid_value *ssid, const struct wpabuf *nr, const struct wpabuf *lci, const struct wpabuf *civic, int stationary) { struct hostapd_neighbor_entry *entry; entry = hostapd_neighbor_get(hapd, bssid, ssid); if (!entry) entry = hostapd_neighbor_add(hapd); if (!entry) return -1; hostapd_neighbor_clear_entry(entry); os_memcpy(entry->bssid, bssid, ETH_ALEN); os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid)); entry->nr = wpabuf_dup(nr); if (!entry->nr) goto fail; if (lci && wpabuf_len(lci)) { entry->lci = wpabuf_dup(lci); if (!entry->lci || os_get_time(&entry->lci_date)) goto fail; } if (civic && wpabuf_len(civic)) { entry->civic = wpabuf_dup(civic); if (!entry->civic) goto fail; } entry->stationary = stationary; return 0; fail: hostapd_neighbor_remove(hapd, bssid, ssid); return -1; } int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid, const struct wpa_ssid_value *ssid) { struct hostapd_neighbor_entry *nr; nr = hostapd_neighbor_get(hapd, bssid, ssid); if (!nr) return -1; hostapd_neighbor_clear_entry(nr); dl_list_del(&nr->list); os_free(nr); return 0; } void hostapd_free_neighbor_db(struct hostapd_data *hapd) { struct hostapd_neighbor_entry *nr, *prev; dl_list_for_each_safe(nr, prev, &hapd->nr_db, struct hostapd_neighbor_entry, list) { hostapd_neighbor_clear_entry(nr); dl_list_del(&nr->list); os_free(nr); } }