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 nr->stationary = 0; 47 } 48 49 50 static struct hostapd_neighbor_entry * 51 hostapd_neighbor_add(struct hostapd_data *hapd) 52 { 53 struct hostapd_neighbor_entry *nr; 54 55 nr = os_zalloc(sizeof(struct hostapd_neighbor_entry)); 56 if (!nr) 57 return NULL; 58 59 dl_list_add(&hapd->nr_db, &nr->list); 60 61 return nr; 62 } 63 64 65 int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid, 66 const struct wpa_ssid_value *ssid, 67 const struct wpabuf *nr, const struct wpabuf *lci, 68 const struct wpabuf *civic, int stationary) 69 { 70 struct hostapd_neighbor_entry *entry; 71 72 entry = hostapd_neighbor_get(hapd, bssid, ssid); 73 if (!entry) 74 entry = hostapd_neighbor_add(hapd); 75 if (!entry) 76 return -1; 77 78 hostapd_neighbor_clear_entry(entry); 79 80 os_memcpy(entry->bssid, bssid, ETH_ALEN); 81 os_memcpy(&entry->ssid, ssid, sizeof(entry->ssid)); 82 83 entry->nr = wpabuf_dup(nr); 84 if (!entry->nr) 85 goto fail; 86 87 if (lci && wpabuf_len(lci)) { 88 entry->lci = wpabuf_dup(lci); 89 if (!entry->lci || os_get_time(&entry->lci_date)) 90 goto fail; 91 } 92 93 if (civic && wpabuf_len(civic)) { 94 entry->civic = wpabuf_dup(civic); 95 if (!entry->civic) 96 goto fail; 97 } 98 99 entry->stationary = stationary; 100 101 return 0; 102 103 fail: 104 hostapd_neighbor_remove(hapd, bssid, ssid); 105 return -1; 106 } 107 108 109 int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid, 110 const struct wpa_ssid_value *ssid) 111 { 112 struct hostapd_neighbor_entry *nr; 113 114 nr = hostapd_neighbor_get(hapd, bssid, ssid); 115 if (!nr) 116 return -1; 117 118 hostapd_neighbor_clear_entry(nr); 119 dl_list_del(&nr->list); 120 os_free(nr); 121 122 return 0; 123 } 124 125 126 void hostpad_free_neighbor_db(struct hostapd_data *hapd) 127 { 128 struct hostapd_neighbor_entry *nr, *prev; 129 130 dl_list_for_each_safe(nr, prev, &hapd->nr_db, 131 struct hostapd_neighbor_entry, list) { 132 hostapd_neighbor_clear_entry(nr); 133 dl_list_del(&nr->list); 134 os_free(nr); 135 } 136 } 137