Line data Source code
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 : struct hostapd_neighbor_entry *
18 21 : 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 46 : dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
24 : list) {
25 32 : if (os_memcmp(bssid, nr->bssid, ETH_ALEN) == 0 &&
26 10 : (!ssid ||
27 20 : (ssid->ssid_len == nr->ssid.ssid_len &&
28 10 : os_memcmp(ssid->ssid, nr->ssid.ssid,
29 : ssid->ssid_len) == 0)))
30 7 : return nr;
31 : }
32 14 : return NULL;
33 : }
34 :
35 :
36 26 : static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
37 : {
38 26 : wpabuf_free(nr->nr);
39 26 : nr->nr = NULL;
40 26 : wpabuf_free(nr->lci);
41 26 : nr->lci = NULL;
42 26 : wpabuf_free(nr->civic);
43 26 : nr->civic = NULL;
44 26 : os_memset(nr->bssid, 0, sizeof(nr->bssid));
45 26 : os_memset(&nr->ssid, 0, sizeof(nr->ssid));
46 26 : }
47 :
48 :
49 : static struct hostapd_neighbor_entry *
50 11 : hostapd_neighbor_add(struct hostapd_data *hapd)
51 : {
52 : struct hostapd_neighbor_entry *nr;
53 :
54 11 : nr = os_zalloc(sizeof(struct hostapd_neighbor_entry));
55 11 : if (!nr)
56 0 : return NULL;
57 :
58 11 : dl_list_add(&hapd->nr_db, &nr->list);
59 :
60 11 : return nr;
61 : }
62 :
63 :
64 15 : int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
65 : const struct wpa_ssid_value *ssid,
66 : const struct wpabuf *nr, const struct wpabuf *lci,
67 : const struct wpabuf *civic)
68 : {
69 : struct hostapd_neighbor_entry *entry;
70 :
71 15 : entry = hostapd_neighbor_get(hapd, bssid, ssid);
72 15 : if (!entry)
73 11 : entry = hostapd_neighbor_add(hapd);
74 15 : if (!entry)
75 0 : return -1;
76 :
77 15 : hostapd_neighbor_clear_entry(entry);
78 :
79 15 : os_memcpy(entry->bssid, bssid, ETH_ALEN);
80 15 : os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid));
81 :
82 15 : entry->nr = wpabuf_dup(nr);
83 15 : if (!entry->nr)
84 0 : goto fail;
85 :
86 15 : if (lci) {
87 8 : entry->lci = wpabuf_dup(lci);
88 8 : if (!entry->lci || os_get_time(&entry->lci_date))
89 : goto fail;
90 : }
91 :
92 15 : if (civic) {
93 7 : entry->civic = wpabuf_dup(civic);
94 7 : if (!entry->civic)
95 0 : goto fail;
96 : }
97 :
98 15 : return 0;
99 :
100 : fail:
101 0 : hostapd_neighbor_remove(hapd, bssid, ssid);
102 0 : return -1;
103 : }
104 :
105 :
106 6 : int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
107 : const struct wpa_ssid_value *ssid)
108 : {
109 : struct hostapd_neighbor_entry *nr;
110 :
111 6 : nr = hostapd_neighbor_get(hapd, bssid, ssid);
112 6 : if (!nr)
113 3 : return -1;
114 :
115 3 : hostapd_neighbor_clear_entry(nr);
116 3 : dl_list_del(&nr->list);
117 3 : os_free(nr);
118 :
119 3 : return 0;
120 : }
121 :
122 :
123 2659 : void hostpad_free_neighbor_db(struct hostapd_data *hapd)
124 : {
125 : struct hostapd_neighbor_entry *nr, *prev;
126 :
127 2667 : dl_list_for_each_safe(nr, prev, &hapd->nr_db,
128 : struct hostapd_neighbor_entry, list) {
129 8 : hostapd_neighbor_clear_entry(nr);
130 8 : dl_list_del(&nr->list);
131 8 : os_free(nr);
132 : }
133 2659 : }
|