|
@@ -0,0 +1,131 @@
|
|
|
+/*
|
|
|
+ * 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"
|
|
|
+
|
|
|
+
|
|
|
+static 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_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));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+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)
|
|
|
+{
|
|
|
+ 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) {
|
|
|
+ entry->lci = wpabuf_dup(lci);
|
|
|
+ if (!entry->lci || os_get_time(&entry->lci_date))
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (civic) {
|
|
|
+ entry->civic = wpabuf_dup(civic);
|
|
|
+ if (!entry->civic)
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+}
|