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