1156aa2adb7d3f5fafa2ee8898d74f7e15747acc
[mech_eap.git] / src / ap / neighbor_db.c
1 /*
2  * hostapd / Neighboring APs DB
3  * Copyright(c) 2013 - 2016 Intel Mobile Communications GmbH.
4  * Copyright(c) 2011 - 2016 Intel Corporation. All rights reserved.
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9
10 #include "utils/includes.h"
11
12 #include "utils/common.h"
13 #include "hostapd.h"
14 #include "neighbor_db.h"
15
16
17 static struct hostapd_neighbor_entry *
18 hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
19                      const struct wpa_ssid_value *ssid)
20 {
21         struct hostapd_neighbor_entry *nr;
22
23         dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
24                          list) {
25                 if (os_memcmp(bssid, nr->bssid, ETH_ALEN) == 0 &&
26                     ssid->ssid_len == nr->ssid.ssid_len &&
27                     os_memcmp(ssid->ssid, nr->ssid.ssid, ssid->ssid_len) == 0)
28                         return nr;
29         }
30         return NULL;
31 }
32
33
34 static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
35 {
36         wpabuf_free(nr->nr);
37         nr->nr = NULL;
38         wpabuf_free(nr->lci);
39         nr->lci = NULL;
40         wpabuf_free(nr->civic);
41         nr->civic = NULL;
42         os_memset(nr->bssid, 0, sizeof(nr->bssid));
43         os_memset(&nr->ssid, 0, sizeof(nr->ssid));
44 }
45
46
47 static struct hostapd_neighbor_entry *
48 hostapd_neighbor_add(struct hostapd_data *hapd)
49 {
50         struct hostapd_neighbor_entry *nr;
51
52         nr = os_zalloc(sizeof(struct hostapd_neighbor_entry));
53         if (!nr)
54                 return NULL;
55
56         dl_list_add(&hapd->nr_db, &nr->list);
57
58         return nr;
59 }
60
61
62 int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
63                          const struct wpa_ssid_value *ssid,
64                          const struct wpabuf *nr, const struct wpabuf *lci,
65                          const struct wpabuf *civic)
66 {
67         struct hostapd_neighbor_entry *entry;
68
69         entry = hostapd_neighbor_get(hapd, bssid, ssid);
70         if (!entry)
71                 entry = hostapd_neighbor_add(hapd);
72         if (!entry)
73                 return -1;
74
75         hostapd_neighbor_clear_entry(entry);
76
77         os_memcpy(entry->bssid, bssid, ETH_ALEN);
78         os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid));
79
80         entry->nr = wpabuf_dup(nr);
81         if (!entry->nr)
82                 goto fail;
83
84         if (lci) {
85                 entry->lci = wpabuf_dup(lci);
86                 if (!entry->lci || os_get_time(&entry->lci_date))
87                         goto fail;
88         }
89
90         if (civic) {
91                 entry->civic = wpabuf_dup(civic);
92                 if (!entry->civic)
93                         goto fail;
94         }
95
96         return 0;
97
98 fail:
99         hostapd_neighbor_remove(hapd, bssid, ssid);
100         return -1;
101 }
102
103
104 int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
105                             const struct wpa_ssid_value *ssid)
106 {
107         struct hostapd_neighbor_entry *nr;
108
109         nr = hostapd_neighbor_get(hapd, bssid, ssid);
110         if (!nr)
111                 return -1;
112
113         hostapd_neighbor_clear_entry(nr);
114         dl_list_del(&nr->list);
115         os_free(nr);
116
117         return 0;
118 }
119
120
121 void hostpad_free_neighbor_db(struct hostapd_data *hapd)
122 {
123         struct hostapd_neighbor_entry *nr, *prev;
124
125         dl_list_for_each_safe(nr, prev, &hapd->nr_db,
126                               struct hostapd_neighbor_entry, list) {
127                 hostapd_neighbor_clear_entry(nr);
128                 dl_list_del(&nr->list);
129                 os_free(nr);
130         }
131 }