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