Merged the hostap_2.6 updates, and the Leap of Faith work, from the hostap_update...
[mech_eap.git] / libeap / src / ap / neighbor_db.c
diff --git a/libeap/src/ap/neighbor_db.c b/libeap/src/ap/neighbor_db.c
new file mode 100644 (file)
index 0000000..a2efff6
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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));
+}
+
+
+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);
+       }
+}