BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
libDHCPv6_server.c
00001 /* 00002 * Copyright (c) 2014-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * \file dhcpv6_server_api.c 00020 * \brief Add short description about this file!!! 00021 * 00022 */ 00023 #include "nsconfig.h" 00024 #include <string.h> 00025 #include <ns_types.h> 00026 #include <nsdynmemLIB.h> 00027 #include "libDHCPv6/libDHCPv6_server.h" 00028 #include "libDHCPv6/libDHCPv6.h" 00029 #include "common_functions.h" 00030 #include "ns_trace.h" 00031 00032 #ifdef HAVE_DHCPV6_SERVER 00033 00034 static NS_LARGE NS_LIST_DEFINE(dhcpv6_gua_server_list, dhcpv6_gua_server_entry_s, link); 00035 00036 bool libdhcpv6_gua_server_list_empty(void) 00037 { 00038 return ns_list_is_empty(&dhcpv6_gua_server_list); 00039 } 00040 00041 static dhcpv6_gua_server_entry_s *libdhcpv6_server_entry_allocate(void) 00042 { 00043 dhcpv6_gua_server_entry_s *entry = ns_dyn_mem_alloc(sizeof(dhcpv6_gua_server_entry_s)); 00044 if (entry) { 00045 entry->clientIdSequence = 0; 00046 entry->enableAddressMapping = false; 00047 entry->enableAddressAutonous = true; 00048 entry->clientIdDefaultSuffics = 0x0000000; 00049 entry->maxSuppertedClients = 200; 00050 entry->validLifetime = 7200; 00051 ns_list_init(&entry->allocatedAddressList); 00052 } 00053 return entry; 00054 } 00055 static void libdhcpv6_address_generate(dhcpv6_gua_server_entry_s *serverInfo, dhcpv6_alloacted_address_entry_t *entry) 00056 { 00057 //GENERATE ADDRESS 00058 uint8_t *ptr = entry->nonTemporalAddress; 00059 memcpy(ptr, serverInfo->guaPrefix, 8); 00060 ptr += 8; 00061 if (serverInfo->enableAddressAutonous) { 00062 if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE) { 00063 memcpy(ptr, entry->linkId, 8); 00064 *ptr ^= 2; 00065 } else if (entry->linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE) { 00066 *ptr++ = entry->linkId[0] ^ 2; 00067 *ptr++ = entry->linkId[1]; 00068 *ptr++ = entry->linkId[2]; 00069 *ptr++ = 0xff; 00070 *ptr++ = 0xfe; 00071 *ptr++ = entry->linkId[3]; 00072 *ptr++ = entry->linkId[4]; 00073 *ptr = entry->linkId[5]; 00074 } else { 00075 ptr = common_write_32_bit((serverInfo->clientIdDefaultSuffics | 02000000), ptr); 00076 ptr = common_write_32_bit((serverInfo->clientIdSequence + 2), ptr); 00077 } 00078 00079 } else { 00080 ptr = common_write_32_bit((serverInfo->clientIdDefaultSuffics | 02000000), ptr); 00081 ptr = common_write_32_bit((serverInfo->clientIdSequence + 2), ptr); 00082 } 00083 serverInfo->clientIdSequence++; 00084 } 00085 00086 00087 void libdhcpv6_gua_servers_time_update(uint32_t timeUpdateInSeconds) 00088 { 00089 //Check All allocated server inside this loop 00090 ns_list_foreach(dhcpv6_gua_server_entry_s, cur, &dhcpv6_gua_server_list) { 00091 //Check All allocated address in this module 00092 ns_list_foreach_safe(dhcpv6_alloacted_address_entry_t, address, &cur->allocatedAddressList) { 00093 //Update 00094 if (address->preferredLifetime) { 00095 if (address->preferredLifetime <= timeUpdateInSeconds) { 00096 //Stop use this address for leasequery and delete Route or address map 00097 00098 address->preferredLifetime = 0; 00099 cur->timeoutCb(cur->interfaceId, address->nonTemporalAddress); 00100 } else { 00101 address->preferredLifetime -= timeUpdateInSeconds; 00102 } 00103 } 00104 00105 if (address->lifetime <= timeUpdateInSeconds) { 00106 ns_list_remove(&cur->allocatedAddressList, address); 00107 ns_dyn_mem_free(address); 00108 } else { 00109 address->lifetime -= timeUpdateInSeconds; 00110 } 00111 } 00112 } 00113 } 00114 00115 dhcpv6_gua_server_entry_s *libdhcpv6_server_data_get_by_prefix_and_interfaceid(int8_t interfaceId, const uint8_t *prefixPtr) 00116 { 00117 ns_list_foreach(dhcpv6_gua_server_entry_s, cur, &dhcpv6_gua_server_list) { 00118 if (cur->interfaceId == interfaceId) { 00119 if (memcmp(cur->guaPrefix, prefixPtr, 8) == 0) { 00120 return cur; 00121 } 00122 } 00123 } 00124 return NULL; 00125 } 00126 00127 dhcpv6_gua_server_entry_s *libdhcpv6_server_data_get_by_prefix_and_socketinstance(uint16_t socketInstance, uint8_t *prefixPtr) 00128 { 00129 ns_list_foreach(dhcpv6_gua_server_entry_s, cur, &dhcpv6_gua_server_list) { 00130 if (cur->socketInstance_id == socketInstance) { 00131 if (memcmp(cur->guaPrefix, prefixPtr, 8) == 0) { 00132 return cur; 00133 } 00134 } 00135 } 00136 return NULL; 00137 } 00138 00139 00140 dhcpv6_gua_server_entry_s *libdhcpv6_gua_server_allocate(uint8_t *prefix, int8_t interfaceId, uint8_t *serverDUID, uint16_t serverDUIDType, dhcp_address_prefer_timeout_cb *prefered_timeout_cb) 00141 { 00142 dhcpv6_gua_server_entry_s *entry = NULL; 00143 if (libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefix) == NULL) { 00144 entry = libdhcpv6_server_entry_allocate(); 00145 if (entry) { 00146 memcpy(entry->guaPrefix, prefix, 8); 00147 memcpy(entry->serverDUID, serverDUID, 8); 00148 entry->serverLinkType = serverDUIDType; 00149 entry->interfaceId = interfaceId; 00150 entry->timeoutCb = prefered_timeout_cb; 00151 ns_list_add_to_end(&dhcpv6_gua_server_list, entry); 00152 } 00153 } 00154 return entry; 00155 } 00156 00157 void libdhcpv6_gua_server_free_by_prefix_and_interfaceid(uint8_t *prefix, int8_t interfaceId) 00158 { 00159 dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefix); 00160 if (serverInfo) { 00161 if ((serverInfo->interfaceId == interfaceId) && (memcmp(serverInfo->guaPrefix, prefix, 8) == 0)) { 00162 ns_list_foreach_safe(dhcpv6_alloacted_address_entry_t, cur, &serverInfo->allocatedAddressList) { 00163 ns_list_remove(&serverInfo->allocatedAddressList, cur); 00164 ns_dyn_mem_free(cur); 00165 } 00166 ns_list_remove(&dhcpv6_gua_server_list, serverInfo); 00167 ns_dyn_mem_free(serverInfo); 00168 } 00169 } 00170 } 00171 00172 static dhcpv6_alloacted_address_entry_t *libdhcpv6_address_entry_allocate(uint32_t validLifetime) 00173 { 00174 dhcpv6_alloacted_address_entry_t *entry = ns_dyn_mem_alloc(sizeof(dhcpv6_alloacted_address_entry_t)); 00175 if (entry) { 00176 if (validLifetime != 0xffffffff) { 00177 entry->lifetime = validLifetime; 00178 entry->preferredLifetime = (validLifetime >> 1); 00179 } else { 00180 entry->lifetime = 0xffffffff; 00181 entry->preferredLifetime = 0xffffffff; 00182 } 00183 } 00184 return entry; 00185 } 00186 00187 dhcpv6_alloacted_address_entry_t *libdhcpv6_address_get_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address) 00188 { 00189 ns_list_foreach(dhcpv6_alloacted_address_entry_t, cur, &serverInfo->allocatedAddressList) { 00190 if (memcmp(cur->nonTemporalAddress, address, 16) == 0) { 00191 return cur; 00192 } 00193 } 00194 return NULL; 00195 } 00196 00197 void libdhcpv6_address_rm_from_allocated_list(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address) 00198 { 00199 ns_list_foreach_safe(dhcpv6_alloacted_address_entry_t, cur, &serverInfo->allocatedAddressList) { 00200 if (memcmp(cur->nonTemporalAddress, address, 16) == 0) { 00201 ns_list_remove(&serverInfo->allocatedAddressList, cur); 00202 ns_dyn_mem_free(cur); 00203 return; 00204 } 00205 } 00206 } 00207 00208 dhcpv6_alloacted_address_entry_t *libdhcpv6_address_allocated_list_scan(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *linkId, uint16_t linkType, uint32_t iaID, uint32_t T0, uint32_t T1, bool allocateNew) 00209 { 00210 dhcpv6_alloacted_address_entry_t *newEntry = NULL; 00211 uint16_t duiLength = 6; 00212 if (linkType == DHCPV6_DUID_HARDWARE_EUI64_TYPE) { 00213 duiLength = 8; 00214 } 00215 ns_list_foreach(dhcpv6_alloacted_address_entry_t, cur, &serverInfo->allocatedAddressList) { 00216 if (cur->linkType == linkType) { 00217 if (memcmp(cur->linkId, linkId, duiLength) == 0) { 00218 cur->iaID = iaID; 00219 if (serverInfo->validLifetime != 0xffffffff) { 00220 cur->lifetime = serverInfo->validLifetime ; 00221 cur->preferredLifetime = (serverInfo->validLifetime >> 1); 00222 } else { 00223 cur->lifetime = 0xffffffff; 00224 cur->preferredLifetime = 0xffffffff; 00225 } 00226 return cur; 00227 } 00228 } 00229 } 00230 if (allocateNew) { 00231 if (ns_list_count(&serverInfo->allocatedAddressList) < serverInfo->maxSuppertedClients) { 00232 newEntry = libdhcpv6_address_entry_allocate(serverInfo->validLifetime); 00233 if (newEntry) { 00234 memcpy(newEntry->linkId, linkId, duiLength); 00235 newEntry->linkType = linkType; 00236 newEntry->iaID = iaID; 00237 newEntry->T0 = T0; 00238 newEntry->T1 = T1; 00239 libdhcpv6_address_generate(serverInfo, newEntry); 00240 ns_list_add_to_end(&serverInfo->allocatedAddressList, newEntry); 00241 } 00242 } 00243 } 00244 00245 return newEntry; 00246 } 00247 00248 #endif 00249
Generated on Tue Jul 12 2022 12:21:58 by
