Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
dhcpv6_client_service.c
00001 /* 00002 * Copyright (c) 2018-2019, 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 #include "nsconfig.h" 00019 #include <string.h> 00020 #include <ns_types.h> 00021 #include <ns_trace.h> 00022 #include "nsdynmemLIB.h" 00023 #include "ns_list.h" 00024 #include "common_functions.h" 00025 00026 #ifdef HAVE_DHCPV6 00027 #include "dhcp_service_api.h" 00028 #include "dhcpv6_client_api.h" 00029 #include "libDHCPv6/libDHCPv6.h" 00030 #include "NWK_INTERFACE/Include/protocol.h" 00031 00032 #define TRACE_GROUP "DHP" 00033 00034 typedef struct { 00035 dhcp_client_global_adress_cb *global_address_cb; 00036 uint16_t service_instance; 00037 uint16_t relay_instance; 00038 uint16_t sol_timeout; 00039 uint16_t sol_max_rt; 00040 uint8_t sol_max_rc; 00041 uint8_t libDhcp_instance; 00042 dhcp_duid_options_params_t duid; 00043 int8_t interface; 00044 bool renew_uses_solicit: 1; 00045 bool one_instance_interface: 1; 00046 bool no_address_hint: 1; 00047 ns_list_link_t link; /*!< List link entry */ 00048 } dhcp_client_class_t; 00049 00050 static NS_LARGE NS_LIST_DEFINE(dhcp_client_list, dhcp_client_class_t, link); 00051 00052 static bool dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_data_t *srv_data_ptr); 00053 void dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_entry_t *addr, if_address_callback_t reason); 00054 00055 00056 00057 static dhcp_client_class_t *dhcpv6_client_entry_allocate(int8_t interface, uint8_t duid_length) 00058 { 00059 dhcp_client_class_t *entry = ns_dyn_mem_alloc(sizeof(dhcp_client_class_t)); 00060 uint8_t *duid = ns_dyn_mem_alloc(duid_length); 00061 if (!entry || !duid) { 00062 ns_dyn_mem_free(entry); 00063 ns_dyn_mem_free(duid); 00064 return NULL; 00065 00066 } 00067 memset(entry, 0, sizeof(dhcp_client_class_t)); 00068 entry->interface = interface; 00069 entry->service_instance = dhcp_service_init(interface, DHCP_INSTANCE_CLIENT, NULL); 00070 entry->libDhcp_instance = libdhcpv6_nonTemporal_entry_get_unique_instance_id(); 00071 entry->duid.duid = duid; 00072 entry->duid.duid_length = duid_length; 00073 entry->duid.type = DHCPV6_DUID_LINK_LAYER_TYPE; 00074 ns_list_add_to_end(&dhcp_client_list, entry); 00075 return entry; 00076 } 00077 00078 //Discover DHCPv6 client 00079 static dhcp_client_class_t *dhcpv6_client_entry_discover(int8_t interface) 00080 { 00081 ns_list_foreach(dhcp_client_class_t, cur, &dhcp_client_list) { 00082 //Check All allocated address in this module 00083 if (cur->interface == interface) { 00084 return cur; 00085 } 00086 } 00087 00088 return NULL; 00089 } 00090 00091 00092 void dhcp_client_init(int8_t interface, uint16_t link_type) 00093 { 00094 protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface); 00095 if (!interface_ptr) { 00096 return; 00097 } 00098 00099 00100 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface); 00101 00102 if (dhcp_client) { 00103 dhcp_client->sol_timeout = 0; 00104 dhcp_client->sol_max_rt = 0; 00105 dhcp_client->sol_max_rc = 0; 00106 dhcp_client->renew_uses_solicit = false; 00107 dhcp_client->one_instance_interface = false; 00108 dhcp_client->no_address_hint = false; 00109 dhcp_client->service_instance = dhcp_service_init(interface, DHCP_INSTANCE_CLIENT, NULL); 00110 dhcp_client->libDhcp_instance = libdhcpv6_nonTemporal_entry_get_unique_instance_id(); 00111 return; 00112 } 00113 //Allocate new 00114 //define DUID-LL length based on MAC64 or MAC48 00115 00116 dhcp_client = dhcpv6_client_entry_allocate(interface, libdhcpv6_duid_linktype_size(link_type) + 2); 00117 if (!dhcp_client) { 00118 return; 00119 } 00120 00121 uint8_t *ptr = dhcp_client->duid.duid; 00122 ptr = common_write_16_bit(link_type, ptr); 00123 memcpy(ptr, interface_ptr->mac, libdhcpv6_duid_linktype_size(link_type)); 00124 00125 //Define DUID 00126 00127 00128 } 00129 void dhcp_client_configure(int8_t interface, bool renew_uses_solicit, bool one_client_for_this_interface, bool no_address_hint) 00130 { 00131 // Set true if RENEW is not used and SOLICIT sent instead. 00132 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface); 00133 if (!dhcp_client) { 00134 return; 00135 } 00136 dhcp_client->renew_uses_solicit = renew_uses_solicit; 00137 dhcp_client->one_instance_interface = one_client_for_this_interface; 00138 dhcp_client->no_address_hint = no_address_hint; 00139 } 00140 00141 void dhcp_client_solicit_timeout_set(int8_t interface, uint16_t timeout, uint16_t max_rt, uint8_t max_rc) 00142 { 00143 // Set the default retry values for SOLICIT and RENEW messages. 00144 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface); 00145 if (!dhcp_client) { 00146 return; 00147 } 00148 dhcp_client->sol_timeout = timeout; 00149 dhcp_client->sol_max_rt = max_rt; 00150 dhcp_client->sol_max_rc = max_rc; 00151 00152 return; 00153 } 00154 00155 void dhcp_relay_agent_enable(int8_t interface, uint8_t border_router_address[static 16]) 00156 { 00157 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface); 00158 if (!dhcp_client) { 00159 return; 00160 } 00161 00162 dhcp_client->relay_instance = dhcp_service_init(interface, DHCP_INTANCE_RELAY_AGENT, NULL); 00163 dhcp_service_relay_instance_enable(dhcp_client->relay_instance, border_router_address); 00164 } 00165 00166 void dhcp_client_delete(int8_t interface) 00167 { 00168 protocol_interface_info_entry_t *cur = NULL; 00169 dhcpv6_client_server_data_t *srv_data_ptr; 00170 uint8_t temporary_address[16]; 00171 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface); 00172 if (!dhcp_client) { 00173 return; 00174 } 00175 00176 00177 dhcp_service_delete(dhcp_client->service_instance); 00178 00179 00180 cur = protocol_stack_interface_info_get_by_id(interface); 00181 00182 if (!cur) { 00183 return; 00184 } 00185 00186 do { 00187 srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_instance(dhcp_client->libDhcp_instance); 00188 if (srv_data_ptr != NULL) { 00189 tr_debug("Free DHCPv6 Client\n"); 00190 memcpy(temporary_address, srv_data_ptr->iaNontemporalAddress.addressPrefix, 16); 00191 dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions 00192 libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr); 00193 addr_delete(cur, temporary_address); 00194 00195 } 00196 } while (srv_data_ptr != NULL); 00197 dhcp_client->service_instance = 0; 00198 return; 00199 } 00200 00201 00202 void dhcpv6_client_send_error_cb(dhcpv6_client_server_data_t *srv_data_ptr) 00203 { 00204 if (srv_data_ptr != NULL) { 00205 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(srv_data_ptr->interfaceId); 00206 if (!dhcp_client) { 00207 return; 00208 } 00209 00210 // error for Global address 00211 if (dhcp_client->global_address_cb != NULL) { 00212 dhcp_client->global_address_cb(dhcp_client->interface, srv_data_ptr->server_address, srv_data_ptr->iaNontemporalAddress.addressPrefix, false); 00213 } 00214 } 00215 } 00216 00217 00218 /* solication responce received for either global address or routter id assignment */ 00219 int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uint8_t *msg_ptr, uint16_t msg_len) 00220 { 00221 dhcp_ia_non_temporal_params_t dhcp_ia_non_temporal_params; 00222 dhcp_duid_options_params_t clientId; 00223 dhcp_duid_options_params_t serverId; 00224 dhcpv6_client_server_data_t *srv_data_ptr = NULL; 00225 (void)instance_id; 00226 00227 //Validate that started TR ID class is still at list 00228 srv_data_ptr = libdhcpv6_nonTemporal_validate_class_pointer(ptr); 00229 00230 00231 if (srv_data_ptr == NULL) { 00232 tr_error("server data not found"); 00233 goto error_exit; 00234 } 00235 00236 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(srv_data_ptr->interfaceId); 00237 if (!dhcp_client) { 00238 tr_error("No DHCPv6 client avilabale"); 00239 goto error_exit; 00240 } 00241 00242 00243 //Clear Active Transaction state 00244 srv_data_ptr->transActionId = 0; 00245 00246 // Validate message 00247 if (msg_name != DHCPV6_REPLY_TYPE) { 00248 tr_error("invalid response"); 00249 goto error_exit; 00250 } 00251 00252 if (libdhcpv6_reply_message_option_validate(&clientId, &serverId, &dhcp_ia_non_temporal_params, msg_ptr, msg_len) != 0) { 00253 tr_error("Reply Not include all Options"); 00254 goto error_exit; 00255 } 00256 00257 if (libdhcpv6_nonTemporal_entry_get_by_iaid(dhcp_ia_non_temporal_params.iaId) != srv_data_ptr) { 00258 /* Validate server data availability */ 00259 tr_error("Valid instance not found"); 00260 goto error_exit; 00261 } 00262 00263 if (srv_data_ptr->IAID != dhcp_ia_non_temporal_params.iaId) { 00264 tr_error("Wrong IAID"); 00265 goto error_exit; 00266 } 00267 00268 if (libdhcpv6_compare_DUID(&srv_data_ptr->clientDUID, &clientId) != 0) { 00269 tr_error("Not Valid Client Id"); 00270 goto error_exit; 00271 } 00272 00273 //Allocate dynamically new Server DUID if needed 00274 if (!srv_data_ptr->serverDynamic_DUID || serverId.duid_length > srv_data_ptr->dyn_server_duid_length) { 00275 //Allocate dynamic new bigger 00276 srv_data_ptr->dyn_server_duid_length = 0; 00277 ns_dyn_mem_free(srv_data_ptr->serverDynamic_DUID); 00278 srv_data_ptr->serverDynamic_DUID = ns_dyn_mem_alloc(serverId.duid_length); 00279 if (!srv_data_ptr->serverDynamic_DUID) { 00280 tr_error("Dynamic DUID alloc fail"); 00281 goto error_exit; 00282 } 00283 srv_data_ptr->dyn_server_duid_length = serverId.duid_length; 00284 } 00285 00286 //Copy Server DUID 00287 srv_data_ptr->serverDUID.duid = srv_data_ptr->serverDynamic_DUID; 00288 srv_data_ptr->serverDUID.type = serverId.type; 00289 srv_data_ptr->serverDUID.duid_length = serverId.duid_length; 00290 memcpy(srv_data_ptr->serverDUID.duid, serverId.duid, serverId.duid_length); 00291 00292 if (dhcp_client->one_instance_interface && memcmp(srv_data_ptr->iaNontemporalAddress.addressPrefix, dhcp_ia_non_temporal_params.nonTemporalAddress, 16)) { 00293 00294 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(dhcp_client->interface); 00295 if (cur) { 00296 addr_deprecate(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix); 00297 } 00298 } 00299 00300 memcpy(srv_data_ptr->iaNontemporalAddress.addressPrefix, dhcp_ia_non_temporal_params.nonTemporalAddress, 16); 00301 srv_data_ptr->iaNontemporalAddress.preferredTime = dhcp_ia_non_temporal_params.preferredValidLifeTime; 00302 srv_data_ptr->iaNontemporalAddress.validLifetime = dhcp_ia_non_temporal_params.validLifeTime; 00303 srv_data_ptr->T0 = dhcp_ia_non_temporal_params.T0; 00304 srv_data_ptr->T1 = dhcp_ia_non_temporal_params.T1; 00305 00306 00307 bool status = dhcpv6_client_set_address(dhcp_client->interface, srv_data_ptr); 00308 00309 00310 if (dhcp_client->global_address_cb) { 00311 dhcp_client->global_address_cb(dhcp_client->interface, srv_data_ptr->server_address, srv_data_ptr->iaNontemporalAddress.addressPrefix, status); 00312 } 00313 return RET_MSG_ACCEPTED; 00314 error_exit: 00315 dhcpv6_client_send_error_cb(srv_data_ptr); 00316 return RET_MSG_ACCEPTED; 00317 } 00318 00319 int dhcp_client_get_global_address(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], dhcp_client_global_adress_cb *error_cb) 00320 { 00321 dhcpv6_solication_base_packet_s solPacket = {0}; 00322 00323 uint8_t *payload_ptr; 00324 uint32_t payload_len; 00325 dhcpv6_client_server_data_t *srv_data_ptr; 00326 bool add_prefix; 00327 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface); 00328 00329 if (dhcp_addr == NULL || !dhcp_client) { 00330 tr_error("Invalid parameters"); 00331 return -1; 00332 } 00333 00334 if (!prefix || dhcp_client->one_instance_interface) { 00335 //NULL Definition will only check That Interface is not generated 00336 srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_instance(dhcp_client->libDhcp_instance); 00337 if (srv_data_ptr) { 00338 //Already Created to same interface 00339 if (dhcp_client->one_instance_interface && prefix) { 00340 if (srv_data_ptr->iaNonTemporalStructValid) { 00341 if (memcmp(srv_data_ptr->iaNontemporalAddress.addressPrefix, prefix, 8) == 0) { 00342 return 0; 00343 } 00344 00345 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface); 00346 if (!cur) { 00347 return -1; 00348 } 00349 00350 dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions 00351 addr_deprecate(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix); 00352 srv_data_ptr->iaNonTemporalStructValid = false; 00353 memcpy(srv_data_ptr->iaNontemporalAddress.addressPrefix, prefix, 8); 00354 goto dhcp_address_get; 00355 00356 } else if (dhcp_client_server_address_update(interface, prefix, dhcp_addr) == 0) { 00357 //DHCP server address OK 00358 return 0; 00359 } 00360 } 00361 return -1; 00362 00363 } 00364 } else if (dhcp_client_server_address_update(interface, prefix, dhcp_addr) == 0) { 00365 //No need for allocate new 00366 return 0; 00367 } 00368 00369 tr_debug("GEN new Dhcpv6 client %u", dhcp_client->libDhcp_instance); 00370 srv_data_ptr = libdhcvp6_nontemporalAddress_server_data_allocate(interface, dhcp_client->libDhcp_instance, prefix, dhcp_addr); 00371 00372 if (!srv_data_ptr) { 00373 tr_error("OOM srv_data_ptr"); 00374 return -1; 00375 } 00376 //SET DUID 00377 srv_data_ptr->clientDUID = dhcp_client->duid; 00378 00379 dhcp_address_get: 00380 00381 if (!prefix || dhcp_client->no_address_hint) { 00382 add_prefix = false; 00383 } else { 00384 add_prefix = prefix != NULL; 00385 } 00386 00387 payload_len = libdhcpv6_solication_message_length(srv_data_ptr->clientDUID.duid_length, add_prefix, 0); 00388 00389 00390 payload_ptr = ns_dyn_mem_temporary_alloc(payload_len); 00391 if (!payload_ptr) { 00392 libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr); 00393 tr_error("OOM payload_ptr"); 00394 return -1; 00395 } 00396 00397 dhcp_client->global_address_cb = error_cb; //TODO Only supporting one instance globaly if we need more for different instances needs code. 00398 srv_data_ptr->GlobalAddress = true; 00399 // Build solicit 00400 solPacket.clientDUID = srv_data_ptr->clientDUID; 00401 solPacket.iaID = srv_data_ptr->IAID; 00402 solPacket.messageType = DHCPV6_SOLICATION_TYPE; 00403 solPacket.transActionId = libdhcpv6_txid_get(); 00404 /*Non Temporal Address */ 00405 00406 if (prefix && !dhcp_client->no_address_hint) { 00407 dhcpv6_ia_non_temporal_address_s nonTemporalAddress = {0}; 00408 nonTemporalAddress.requestedAddress = prefix; 00409 libdhcpv6_generic_nontemporal_address_message_write(payload_ptr, &solPacket, &nonTemporalAddress, NULL); 00410 } else { 00411 libdhcpv6_generic_nontemporal_address_message_write(payload_ptr, &solPacket, NULL, NULL); 00412 } 00413 00414 // send solicit 00415 srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client->service_instance, 0, srv_data_ptr, dhcp_addr, payload_ptr, payload_len, dhcp_solicit_resp_cb); 00416 if (srv_data_ptr->transActionId == 0) { 00417 ns_dyn_mem_free(payload_ptr); 00418 libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr); 00419 return -1; 00420 } 00421 srv_data_ptr->iaNonTemporalStructValid = false; 00422 if (dhcp_client->sol_timeout != 0) { 00423 // Default retry values are modified from specification update to message 00424 dhcp_service_set_retry_timers(srv_data_ptr->transActionId, dhcp_client->sol_timeout, dhcp_client->sol_max_rt, dhcp_client->sol_max_rc); 00425 } 00426 00427 return 0; 00428 } 00429 00430 int dhcp_client_server_address_update(int8_t interface, uint8_t *prefix, uint8_t server_address[static 16]) 00431 { 00432 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface); 00433 if (!dhcp_client) { 00434 tr_debug("Interface not match"); 00435 return -1; 00436 } 00437 00438 dhcpv6_client_server_data_t *srv_data_ptr = NULL; 00439 00440 if (prefix) { 00441 srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_prefix(interface, prefix); 00442 } else if (dhcp_client->one_instance_interface) { 00443 srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_instance(dhcp_client->libDhcp_instance); 00444 } 00445 if (!srv_data_ptr) { 00446 return -1; 00447 } 00448 00449 if (memcmp(srv_data_ptr->server_address, server_address, 16) == 0) { 00450 return 0; 00451 } 00452 00453 memcpy(srv_data_ptr->server_address, server_address, 16); 00454 if (srv_data_ptr->transActionId) { 00455 dhcp_service_update_server_address(srv_data_ptr->transActionId, server_address); 00456 } 00457 return 0; 00458 } 00459 00460 00461 00462 void dhcp_client_global_address_renew(int8_t interface) 00463 { 00464 (void)interface; 00465 return; 00466 } 00467 00468 void dhcp_client_global_address_delete(int8_t interface, uint8_t *dhcp_addr, uint8_t prefix[static 16]) 00469 { 00470 protocol_interface_info_entry_t *cur; 00471 dhcpv6_client_server_data_t *srv_data_ptr; 00472 dhcp_client_class_t *dhcp_client; 00473 (void) dhcp_addr; 00474 00475 srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_prefix(interface, prefix); 00476 cur = protocol_stack_interface_info_get_by_id(interface); 00477 dhcp_client = dhcpv6_client_entry_discover(interface); 00478 00479 if (cur == NULL || srv_data_ptr == NULL || !dhcp_client) { 00480 return; 00481 } 00482 00483 dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions 00484 if (dhcp_client->one_instance_interface) { 00485 addr_deprecate(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix); 00486 } else { 00487 addr_delete(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix); 00488 } 00489 00490 libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr); 00491 } 00492 00493 void dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_entry_t *addr, if_address_callback_t reason) 00494 { 00495 00496 uint8_t *payload_ptr; 00497 uint32_t payload_len; 00498 dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface->id); 00499 if (!dhcp_client) { 00500 return; 00501 } 00502 00503 dhcpv6_client_server_data_t *srv_data_ptr; 00504 if (addr) { 00505 srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_prefix(interface->id, addr->address); 00506 } else { 00507 srv_data_ptr = libdhcpv6_nonTemporal_entry_get_by_instance(dhcp_client->libDhcp_instance); 00508 } 00509 00510 if (srv_data_ptr == NULL) { 00511 return; 00512 } 00513 if (reason == ADDR_CALLBACK_INVALIDATED) { 00514 dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions 00515 libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr); 00516 tr_warn("Dhcp address lost"); 00517 return; 00518 } 00519 00520 if (reason != ADDR_CALLBACK_TIMER) { 00521 return; 00522 } 00523 00524 if (srv_data_ptr->transActionId) { 00525 //Do not trig new Renew process 00526 tr_warn("Do not trig new pending renew request"); 00527 return; 00528 } 00529 00530 payload_len = libdhcpv6_address_request_message_len(srv_data_ptr->clientDUID.duid_length, srv_data_ptr->serverDUID.duid_length, 0, !dhcp_client->no_address_hint); 00531 payload_ptr = ns_dyn_mem_temporary_alloc(payload_len); 00532 if (payload_ptr == NULL) { 00533 if (addr) { 00534 addr->state_timer = 200; //Retry after 20 seconds 00535 } 00536 tr_error("Out of memory"); 00537 return ; 00538 } 00539 dhcpv6_solication_base_packet_s packetReq = { 00540 .messageType = DHCPV6_RENEW_TYPE, 00541 .clientDUID = srv_data_ptr->clientDUID, 00542 .requestedOptionCnt = 0, 00543 .iaID = srv_data_ptr->IAID, 00544 .timerT0 = srv_data_ptr->T0, 00545 .timerT1 = srv_data_ptr->T1, 00546 .requestedOptionList = NULL, 00547 }; 00548 00549 if (dhcp_client->renew_uses_solicit) { 00550 packetReq.messageType = DHCPV6_SOLICATION_TYPE; 00551 } 00552 00553 00554 00555 if (dhcp_client->no_address_hint && dhcp_client->renew_uses_solicit) { 00556 packetReq.timerT0 = 0; 00557 packetReq.timerT1 = 0; 00558 libdhcpv6_generic_nontemporal_address_message_write(payload_ptr, &packetReq, NULL, &srv_data_ptr->serverDUID); 00559 } else { 00560 // Set Address information 00561 dhcpv6_ia_non_temporal_address_s nonTemporalAddress = {0}; 00562 nonTemporalAddress.requestedAddress = srv_data_ptr->iaNontemporalAddress.addressPrefix; 00563 nonTemporalAddress.preferredLifeTime = srv_data_ptr->iaNontemporalAddress.preferredTime; 00564 nonTemporalAddress.validLifeTime = srv_data_ptr->iaNontemporalAddress.validLifetime; 00565 libdhcpv6_generic_nontemporal_address_message_write(payload_ptr, &packetReq, &nonTemporalAddress, &srv_data_ptr->serverDUID); 00566 } 00567 // send solicit 00568 uint8_t *server_address = dhcp_service_relay_global_addres_get(dhcp_client->relay_instance); 00569 if (!server_address) { 00570 server_address = srv_data_ptr->server_address; 00571 } 00572 00573 srv_data_ptr->transActionId = dhcp_service_send_req(dhcp_client->service_instance, 0, srv_data_ptr, server_address, payload_ptr, payload_len, dhcp_solicit_resp_cb); 00574 if (srv_data_ptr->transActionId == 0) { 00575 ns_dyn_mem_free(payload_ptr); 00576 if (addr) { 00577 addr->state_timer = 200; //Retry after 20 seconds 00578 } 00579 tr_error("DHCP renew send failed"); 00580 } 00581 if (packetReq.messageType == DHCPV6_SOLICATION_TYPE && dhcp_client->sol_timeout != 0) { 00582 // Default retry values are modified from specification update to message 00583 dhcp_service_set_retry_timers(srv_data_ptr->transActionId, dhcp_client->sol_timeout, dhcp_client->sol_max_rt, dhcp_client->sol_max_rc); 00584 } 00585 tr_info("DHCP renew send OK"); 00586 } 00587 00588 static bool dhcpv6_client_set_address(int8_t interface_id, dhcpv6_client_server_data_t *srv_data_ptr) 00589 { 00590 protocol_interface_info_entry_t *cur = NULL; 00591 if_address_entry_t *address_entry = NULL; 00592 uint32_t renewTimer; 00593 cur = protocol_stack_interface_info_get_by_id(interface_id); 00594 if (!cur) { 00595 return false; 00596 } 00597 renewTimer = libdhcpv6_renew_time_define(srv_data_ptr); 00598 00599 srv_data_ptr->iaNonTemporalStructValid = true; 00600 address_entry = addr_get_entry(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix); 00601 if (address_entry == NULL) { 00602 // create new 00603 address_entry = addr_add(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix, 64, ADDR_SOURCE_DHCP, srv_data_ptr->iaNontemporalAddress.validLifetime, srv_data_ptr->iaNontemporalAddress.preferredTime, false); 00604 } else { 00605 addr_set_valid_lifetime(cur, address_entry, srv_data_ptr->iaNontemporalAddress.validLifetime); 00606 addr_set_preferred_lifetime(cur, address_entry, srv_data_ptr->iaNontemporalAddress.preferredTime); 00607 } 00608 00609 if (address_entry == NULL) { 00610 tr_error("Address add failed"); 00611 srv_data_ptr->iaNonTemporalStructValid = false; 00612 return false; 00613 } 00614 00615 if (renewTimer) { 00616 // translate seconds to 100ms ticks 00617 if (renewTimer < 0xffffffff / 10) { 00618 renewTimer *= 10; 00619 } else { 00620 renewTimer = 0xfffffffe; 00621 } 00622 } 00623 address_entry->state_timer = renewTimer; 00624 address_entry->cb = dhcpv6_renew; 00625 return true; 00626 } 00627 00628 #endif
Generated on Tue Jul 12 2022 13:54:16 by
