xref: /freebsd/contrib/wpa/src/ap/neighbor_db.c (revision 85732ac8bccbc0adcf5a261ea1ffec8ca7b3a92d)
1780fb4a2SCy Schubert /*
2780fb4a2SCy Schubert  * hostapd / Neighboring APs DB
3780fb4a2SCy Schubert  * Copyright(c) 2013 - 2016 Intel Mobile Communications GmbH.
4780fb4a2SCy Schubert  * Copyright(c) 2011 - 2016 Intel Corporation. All rights reserved.
5780fb4a2SCy Schubert  *
6780fb4a2SCy Schubert  * This software may be distributed under the terms of the BSD license.
7780fb4a2SCy Schubert  * See README for more details.
8780fb4a2SCy Schubert  */
9780fb4a2SCy Schubert 
10780fb4a2SCy Schubert #include "utils/includes.h"
11780fb4a2SCy Schubert 
12780fb4a2SCy Schubert #include "utils/common.h"
13780fb4a2SCy Schubert #include "hostapd.h"
14780fb4a2SCy Schubert #include "neighbor_db.h"
15780fb4a2SCy Schubert 
16780fb4a2SCy Schubert 
17780fb4a2SCy Schubert struct hostapd_neighbor_entry *
18780fb4a2SCy Schubert hostapd_neighbor_get(struct hostapd_data *hapd, const u8 *bssid,
19780fb4a2SCy Schubert 		     const struct wpa_ssid_value *ssid)
20780fb4a2SCy Schubert {
21780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr;
22780fb4a2SCy Schubert 
23780fb4a2SCy Schubert 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
24780fb4a2SCy Schubert 			 list) {
25780fb4a2SCy Schubert 		if (os_memcmp(bssid, nr->bssid, ETH_ALEN) == 0 &&
26780fb4a2SCy Schubert 		    (!ssid ||
27780fb4a2SCy Schubert 		     (ssid->ssid_len == nr->ssid.ssid_len &&
28780fb4a2SCy Schubert 		      os_memcmp(ssid->ssid, nr->ssid.ssid,
29780fb4a2SCy Schubert 				ssid->ssid_len) == 0)))
30780fb4a2SCy Schubert 			return nr;
31780fb4a2SCy Schubert 	}
32780fb4a2SCy Schubert 	return NULL;
33780fb4a2SCy Schubert }
34780fb4a2SCy Schubert 
35780fb4a2SCy Schubert 
36780fb4a2SCy Schubert static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
37780fb4a2SCy Schubert {
38780fb4a2SCy Schubert 	wpabuf_free(nr->nr);
39780fb4a2SCy Schubert 	nr->nr = NULL;
40780fb4a2SCy Schubert 	wpabuf_free(nr->lci);
41780fb4a2SCy Schubert 	nr->lci = NULL;
42780fb4a2SCy Schubert 	wpabuf_free(nr->civic);
43780fb4a2SCy Schubert 	nr->civic = NULL;
44780fb4a2SCy Schubert 	os_memset(nr->bssid, 0, sizeof(nr->bssid));
45780fb4a2SCy Schubert 	os_memset(&nr->ssid, 0, sizeof(nr->ssid));
46*85732ac8SCy Schubert 	nr->stationary = 0;
47780fb4a2SCy Schubert }
48780fb4a2SCy Schubert 
49780fb4a2SCy Schubert 
50780fb4a2SCy Schubert static struct hostapd_neighbor_entry *
51780fb4a2SCy Schubert hostapd_neighbor_add(struct hostapd_data *hapd)
52780fb4a2SCy Schubert {
53780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr;
54780fb4a2SCy Schubert 
55780fb4a2SCy Schubert 	nr = os_zalloc(sizeof(struct hostapd_neighbor_entry));
56780fb4a2SCy Schubert 	if (!nr)
57780fb4a2SCy Schubert 		return NULL;
58780fb4a2SCy Schubert 
59780fb4a2SCy Schubert 	dl_list_add(&hapd->nr_db, &nr->list);
60780fb4a2SCy Schubert 
61780fb4a2SCy Schubert 	return nr;
62780fb4a2SCy Schubert }
63780fb4a2SCy Schubert 
64780fb4a2SCy Schubert 
65780fb4a2SCy Schubert int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
66780fb4a2SCy Schubert 			 const struct wpa_ssid_value *ssid,
67780fb4a2SCy Schubert 			 const struct wpabuf *nr, const struct wpabuf *lci,
68*85732ac8SCy Schubert 			 const struct wpabuf *civic, int stationary)
69780fb4a2SCy Schubert {
70780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *entry;
71780fb4a2SCy Schubert 
72780fb4a2SCy Schubert 	entry = hostapd_neighbor_get(hapd, bssid, ssid);
73780fb4a2SCy Schubert 	if (!entry)
74780fb4a2SCy Schubert 		entry = hostapd_neighbor_add(hapd);
75780fb4a2SCy Schubert 	if (!entry)
76780fb4a2SCy Schubert 		return -1;
77780fb4a2SCy Schubert 
78780fb4a2SCy Schubert 	hostapd_neighbor_clear_entry(entry);
79780fb4a2SCy Schubert 
80780fb4a2SCy Schubert 	os_memcpy(entry->bssid, bssid, ETH_ALEN);
81780fb4a2SCy Schubert 	os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid));
82780fb4a2SCy Schubert 
83780fb4a2SCy Schubert 	entry->nr = wpabuf_dup(nr);
84780fb4a2SCy Schubert 	if (!entry->nr)
85780fb4a2SCy Schubert 		goto fail;
86780fb4a2SCy Schubert 
87*85732ac8SCy Schubert 	if (lci && wpabuf_len(lci)) {
88780fb4a2SCy Schubert 		entry->lci = wpabuf_dup(lci);
89780fb4a2SCy Schubert 		if (!entry->lci || os_get_time(&entry->lci_date))
90780fb4a2SCy Schubert 			goto fail;
91780fb4a2SCy Schubert 	}
92780fb4a2SCy Schubert 
93*85732ac8SCy Schubert 	if (civic && wpabuf_len(civic)) {
94780fb4a2SCy Schubert 		entry->civic = wpabuf_dup(civic);
95780fb4a2SCy Schubert 		if (!entry->civic)
96780fb4a2SCy Schubert 			goto fail;
97780fb4a2SCy Schubert 	}
98780fb4a2SCy Schubert 
99*85732ac8SCy Schubert 	entry->stationary = stationary;
100*85732ac8SCy Schubert 
101780fb4a2SCy Schubert 	return 0;
102780fb4a2SCy Schubert 
103780fb4a2SCy Schubert fail:
104780fb4a2SCy Schubert 	hostapd_neighbor_remove(hapd, bssid, ssid);
105780fb4a2SCy Schubert 	return -1;
106780fb4a2SCy Schubert }
107780fb4a2SCy Schubert 
108780fb4a2SCy Schubert 
109780fb4a2SCy Schubert int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
110780fb4a2SCy Schubert 			    const struct wpa_ssid_value *ssid)
111780fb4a2SCy Schubert {
112780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr;
113780fb4a2SCy Schubert 
114780fb4a2SCy Schubert 	nr = hostapd_neighbor_get(hapd, bssid, ssid);
115780fb4a2SCy Schubert 	if (!nr)
116780fb4a2SCy Schubert 		return -1;
117780fb4a2SCy Schubert 
118780fb4a2SCy Schubert 	hostapd_neighbor_clear_entry(nr);
119780fb4a2SCy Schubert 	dl_list_del(&nr->list);
120780fb4a2SCy Schubert 	os_free(nr);
121780fb4a2SCy Schubert 
122780fb4a2SCy Schubert 	return 0;
123780fb4a2SCy Schubert }
124780fb4a2SCy Schubert 
125780fb4a2SCy Schubert 
126780fb4a2SCy Schubert void hostpad_free_neighbor_db(struct hostapd_data *hapd)
127780fb4a2SCy Schubert {
128780fb4a2SCy Schubert 	struct hostapd_neighbor_entry *nr, *prev;
129780fb4a2SCy Schubert 
130780fb4a2SCy Schubert 	dl_list_for_each_safe(nr, prev, &hapd->nr_db,
131780fb4a2SCy Schubert 			      struct hostapd_neighbor_entry, list) {
132780fb4a2SCy Schubert 		hostapd_neighbor_clear_entry(nr);
133780fb4a2SCy Schubert 		dl_list_del(&nr->list);
134780fb4a2SCy Schubert 		os_free(nr);
135780fb4a2SCy Schubert 	}
136780fb4a2SCy Schubert }
137