| /* |
| * 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 hostpad_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); |
| } |
| } |