mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '1ad46bb6f1fb40805aa9f72ccb50c87335febed7' into feature-wisun
* commit '1ad46bb6f1fb40805aa9f72ccb50c87335febed7': Squashed 'features/nanostack/sal-stack-nanostack/' changes from 91acececbd..d879e6db87pull/13550/head
commit
a43934c343
|
@ -490,7 +490,8 @@ int ws_bbr_radius_timing_validate(int8_t interface_id, bbr_radius_timing_t *timi
|
|||
*
|
||||
* This function can be called multiple times.
|
||||
* if domain name matches a existing entry address is updated.
|
||||
* If address and domain name is set to NULL entire list is cleared
|
||||
* If domain name is set to NULL entire list is cleared
|
||||
* if address is set to NULL the Domain name is removed from the list.
|
||||
*
|
||||
* \param interface_id Network interface ID.
|
||||
* \param address The address of the DNS query result.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "nsconfig.h"
|
||||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "net_interface.h"
|
||||
#include "socket_api.h"
|
||||
#include "eventOS_event.h"
|
||||
|
@ -41,6 +42,7 @@
|
|||
#include "6LoWPAN/ws/ws_pae_controller.h"
|
||||
#include "DHCPv6_Server/DHCPv6_server_service.h"
|
||||
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||
#include "libDHCPv6/libDHCPv6_vendordata.h"
|
||||
#include "libNET/src/net_dns_internal.h"
|
||||
|
||||
|
||||
|
@ -93,6 +95,17 @@ static rpl_dodag_conf_t rpl_conf = {
|
|||
.dio_redundancy_constant = WS_RPL_DIO_REDUNDANCY_SMALL
|
||||
};
|
||||
|
||||
typedef struct dns_resolution {
|
||||
/** Resolved address for the domain*/
|
||||
uint8_t address[16];
|
||||
/** Domain name string */
|
||||
char *domain_name;
|
||||
} dns_resolution_t;
|
||||
|
||||
#define MAX_DNS_RESOLUTIONS 4
|
||||
|
||||
static dns_resolution_t pre_resolved_dns_queries[MAX_DNS_RESOLUTIONS] = {0};
|
||||
|
||||
static void ws_bbr_rpl_version_timer_start(protocol_interface_info_entry_t *cur, uint8_t version)
|
||||
{
|
||||
// Set the next timeout value for version update
|
||||
|
@ -368,7 +381,8 @@ static bool wisun_dhcp_address_add_cb(int8_t interfaceId, dhcp_address_cache_upd
|
|||
wisun_bbr_na_send(backbone_interface_id, address_info->allocatedAddress);
|
||||
return true;
|
||||
}
|
||||
static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *cur)
|
||||
|
||||
static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *cur, uint8_t *global_id)
|
||||
{
|
||||
//add DNS server information to DHCP server that is learned from the backbone interface.
|
||||
uint8_t dns_server_address[16];
|
||||
|
@ -377,13 +391,37 @@ static void ws_bbr_dhcp_server_dns_info_update(protocol_interface_info_entry_t *
|
|||
(void)cur;
|
||||
if (net_dns_server_get(backbone_interface_id, dns_server_address, &dns_search_list_ptr, &dns_search_list_len, 0) == 0) {
|
||||
/*Only supporting one DNS server address*/
|
||||
//DHCPv6_server_service_set_dns_server(cur->id, dns_server_address, dns_search_list_ptr, dns_search_list_len);
|
||||
DHCPv6_server_service_set_dns_server(cur->id, global_id, dns_server_address, dns_search_list_ptr, dns_search_list_len);
|
||||
}
|
||||
|
||||
//TODO Generate vendor data in Wi-SUN network include the cached DNS query results in some sort of TLV format
|
||||
(void)dhcp_vendor_data_ptr;
|
||||
(void)dhcp_vendor_data_len;
|
||||
//DHCPv6_server_service_set_vendor_data(cur->id, dhcp_vendor_data_ptr, dhcp_vendor_data_len);
|
||||
int vendor_data_len = 0;
|
||||
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
|
||||
if (pre_resolved_dns_queries[n].domain_name != NULL) {
|
||||
vendor_data_len += net_dns_option_vendor_option_data_dns_query_length(pre_resolved_dns_queries[n].domain_name);
|
||||
}
|
||||
}
|
||||
if (vendor_data_len) {
|
||||
ns_dyn_mem_free(dhcp_vendor_data_ptr);
|
||||
dhcp_vendor_data_ptr = ns_dyn_mem_alloc(vendor_data_len);
|
||||
if (!dhcp_vendor_data_ptr) {
|
||||
tr_warn("Vendor info set fail");
|
||||
return;
|
||||
}
|
||||
dhcp_vendor_data_len = vendor_data_len;
|
||||
}
|
||||
if (dhcp_vendor_data_ptr) {
|
||||
// Write vendor data
|
||||
uint8_t *ptr = dhcp_vendor_data_ptr;
|
||||
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
|
||||
if (pre_resolved_dns_queries[n].domain_name != NULL) {
|
||||
ptr = net_dns_option_vendor_option_data_dns_query_write(ptr, pre_resolved_dns_queries[n].address, pre_resolved_dns_queries[n].domain_name);
|
||||
tr_info("set DNS query result for %s, addr: %s", pre_resolved_dns_queries[n].domain_name, tr_ipv6(pre_resolved_dns_queries[n].address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DHCPv6_server_service_set_vendor_data(cur->id, global_id, ARM_ENTERPRISE_NUMBER, dhcp_vendor_data_ptr, dhcp_vendor_data_len);
|
||||
}
|
||||
|
||||
static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8_t *global_id, uint32_t dhcp_address_lifetime)
|
||||
|
@ -406,7 +444,7 @@ static void ws_bbr_dhcp_server_start(protocol_interface_info_entry_t *cur, uint8
|
|||
//SEt max value for not limiting address allocation
|
||||
DHCPv6_server_service_set_max_clients_accepts_count(cur->id, global_id, MAX_SUPPORTED_ADDRESS_LIST_SIZE);
|
||||
|
||||
ws_bbr_dhcp_server_dns_info_update(cur);
|
||||
ws_bbr_dhcp_server_dns_info_update(cur, global_id);
|
||||
|
||||
ws_dhcp_client_address_request(cur, global_id, ll);
|
||||
}
|
||||
|
@ -594,7 +632,7 @@ static void ws_bbr_rpl_status_check(protocol_interface_info_entry_t *cur)
|
|||
// Add also global prefix and route to RPL
|
||||
rpl_control_update_dodag_route(protocol_6lowpan_rpl_root_dodag, current_global_prefix, 64, 0, WS_ROUTE_LIFETIME, false);
|
||||
}
|
||||
ws_bbr_dhcp_server_dns_info_update(cur);
|
||||
ws_bbr_dhcp_server_dns_info_update(cur, current_global_prefix);
|
||||
}
|
||||
}
|
||||
void ws_bbr_pan_version_increase(protocol_interface_info_entry_t *cur)
|
||||
|
@ -1200,7 +1238,7 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
|
|||
{
|
||||
#ifdef HAVE_WS_BORDER_ROUTER
|
||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
|
||||
if (!cur || !address || !domain_name_ptr) {
|
||||
if (!cur) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1210,10 +1248,62 @@ int ws_bbr_dns_query_result_set(int8_t interface_id, const uint8_t address[16],
|
|||
*
|
||||
* This is included in the vendor extension where the format is decided by the vendor
|
||||
*/
|
||||
// TODO search if entry exists replace if address is NULL delete the entry
|
||||
// TODO This information should expire if not updated by client
|
||||
|
||||
ws_bbr_dhcp_server_dns_info_update(cur);
|
||||
// Delete all entries
|
||||
if (!domain_name_ptr) {
|
||||
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
|
||||
// Delete all entries
|
||||
memset(pre_resolved_dns_queries[n].address, 0, 16);
|
||||
ns_dyn_mem_free(pre_resolved_dns_queries[n].domain_name);
|
||||
pre_resolved_dns_queries[n].domain_name = NULL;
|
||||
}
|
||||
goto update_information;
|
||||
}
|
||||
|
||||
// Update existing entries or delete
|
||||
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
|
||||
if (pre_resolved_dns_queries[n].domain_name != NULL &&
|
||||
strcasecmp(pre_resolved_dns_queries[n].domain_name, domain_name_ptr) == 0) {
|
||||
// Matching query updated
|
||||
if (address) {
|
||||
// Update address
|
||||
memcpy(pre_resolved_dns_queries[n].address, address, 16);
|
||||
} else {
|
||||
// delete entry
|
||||
memset(pre_resolved_dns_queries[n].address, 0, 16);
|
||||
ns_dyn_mem_free(pre_resolved_dns_queries[n].domain_name);
|
||||
pre_resolved_dns_queries[n].domain_name = NULL;
|
||||
}
|
||||
goto update_information;
|
||||
}
|
||||
}
|
||||
|
||||
if (address && domain_name_ptr) {
|
||||
// Store new entry to the list
|
||||
for (int n = 0; n < MAX_DNS_RESOLUTIONS; n++) {
|
||||
if (pre_resolved_dns_queries[n].domain_name == NULL) {
|
||||
// Free entry found
|
||||
pre_resolved_dns_queries[n].domain_name = ns_dyn_mem_alloc(strlen(domain_name_ptr) + 1);
|
||||
if (!pre_resolved_dns_queries[n].domain_name) {
|
||||
// Out of memory
|
||||
return -2;
|
||||
}
|
||||
memcpy(pre_resolved_dns_queries[n].address, address, 16);
|
||||
strcpy(pre_resolved_dns_queries[n].domain_name, domain_name_ptr);
|
||||
goto update_information;
|
||||
}
|
||||
}
|
||||
// No room to store new field
|
||||
return -3;
|
||||
}
|
||||
|
||||
update_information:
|
||||
if (memcmp(current_global_prefix, ADDR_UNSPECIFIED, 8) == 0) {
|
||||
// Not in active state so changes are activated after start
|
||||
return 0;
|
||||
}
|
||||
|
||||
ws_bbr_dhcp_server_dns_info_update(cur, current_global_prefix);
|
||||
return 0;
|
||||
#else
|
||||
(void) interface_id;
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "platform/topo_trace.h"
|
||||
#include "dhcp_service_api.h"
|
||||
#include "libDHCPv6/libDHCPv6.h"
|
||||
#include "libDHCPv6/libDHCPv6_vendordata.h"
|
||||
#include "DHCPv6_client/dhcpv6_client_api.h"
|
||||
#include "ws_management_api.h"
|
||||
#include "net_rpl.h"
|
||||
|
@ -73,6 +74,7 @@
|
|||
#include "6LoWPAN/ws/ws_eapol_pdu.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_auth_relay.h"
|
||||
#include "6LoWPAN/ws/ws_eapol_relay.h"
|
||||
#include "libNET/src/net_dns_internal.h"
|
||||
|
||||
#define TRACE_GROUP "wsbs"
|
||||
|
||||
|
@ -872,6 +874,80 @@ static void ws_bootstrap_dhcp_neighbour_update_cb(int8_t interface_id, uint8_t l
|
|||
ws_bootstrap_mac_neighbor_short_time_set(cur, mac64, WS_NEIGHBOUR_DHCP_ENTRY_LIFETIME);
|
||||
}
|
||||
|
||||
static void ws_bootstrap_dhcp_info_notify_cb(int8_t interface, dhcp_option_notify_t *options, dhcp_server_notify_info_t *server_info)
|
||||
{
|
||||
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface);
|
||||
if (!cur) {
|
||||
return;
|
||||
}
|
||||
uint8_t server_ll64[16];
|
||||
memcpy(server_ll64, ADDR_LINK_LOCAL_PREFIX, 8);
|
||||
|
||||
if (server_info->duid_length == 8) {
|
||||
memcpy(server_ll64 + 8, server_info->duid, 8);
|
||||
} else {
|
||||
server_ll64[8] = server_info->duid[0];
|
||||
server_ll64[9] = server_info->duid[1];
|
||||
server_ll64[10] = server_info->duid[2];
|
||||
server_ll64[11] = 0xff;
|
||||
server_ll64[12] = 0xfe;
|
||||
server_ll64[13] = server_info->duid[3];
|
||||
server_ll64[14] = server_info->duid[4];
|
||||
server_ll64[15] = server_info->duid[5];
|
||||
}
|
||||
server_ll64[8] ^= 2;
|
||||
|
||||
switch (options->option_type) {
|
||||
case DHCPV6_OPTION_VENDOR_SPECIFIC_INFO:
|
||||
if (options->option.vendor_spesific.enterprise_number != ARM_ENTERPRISE_NUMBER) {
|
||||
break;
|
||||
}
|
||||
while (options->option.vendor_spesific.data_length) {
|
||||
uint16_t option_type;
|
||||
char *domain;
|
||||
uint8_t *address;
|
||||
uint16_t option_len;
|
||||
option_len = net_dns_option_vendor_option_data_get_next(options->option.vendor_spesific.data, options->option.vendor_spesific.data_length, &option_type);
|
||||
tr_debug("DHCP vendor specific data type:%u length %d", option_type, option_len);
|
||||
//tr_debug("DHCP vendor specific data %s", trace_array(options->option.vendor_spesific.data, options->option.vendor_spesific.data_length));
|
||||
|
||||
if (option_len == 0) {
|
||||
// Option fields were corrupted
|
||||
break;
|
||||
}
|
||||
if (option_type == ARM_DHCP_VENDOR_DATA_DNS_QUERY_RESULT) {
|
||||
// Process ARM DNS query result
|
||||
domain = NULL;
|
||||
address = NULL;
|
||||
if (net_dns_option_vendor_option_data_dns_query_read(options->option.vendor_spesific.data, options->option.vendor_spesific.data_length, &address, &domain) > 0 ||
|
||||
domain || address) {
|
||||
// Valid ARM DNS query entry
|
||||
net_dns_query_result_set(interface, address, domain, server_info->life_time);
|
||||
}
|
||||
}
|
||||
|
||||
options->option.vendor_spesific.data_length -= option_len;
|
||||
options->option.vendor_spesific.data += option_len;
|
||||
}
|
||||
break;
|
||||
|
||||
case DHCPV6_OPTION_DNS_SERVERS:
|
||||
while (options->option.generic.data_length) {
|
||||
net_dns_server_address_set(interface, server_ll64, options->option.generic.data, server_info->life_time);
|
||||
options->option.generic.data_length -= 16;
|
||||
options->option.generic.data += 16;
|
||||
}
|
||||
break;
|
||||
case DHCPV6_OPTION_DOMAIN_LIST:
|
||||
net_dns_server_search_list_set(interface, server_ll64, options->option.generic.data, options->option.generic.data_length, server_info->life_time);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
int8_t ret_val = -1;
|
||||
|
@ -923,6 +999,7 @@ static int8_t ws_bootstrap_up(protocol_interface_info_entry_t *cur)
|
|||
dhcp_service_link_local_rx_cb_set(cur->id, ws_bootstrap_dhcp_neighbour_update_cb);
|
||||
dhcp_client_configure(cur->id, true, true, true); //RENEW uses SOLICIT, Interface will use 1 instance for address get, IAID address hint is not used.
|
||||
dhcp_client_solicit_timeout_set(cur->id, WS_DHCP_SOLICIT_TIMEOUT, WS_DHCP_SOLICIT_MAX_RT, WS_DHCP_SOLICIT_MAX_RC);
|
||||
dhcp_client_option_notification_cb_set(cur->id, ws_bootstrap_dhcp_info_notify_cb);
|
||||
|
||||
|
||||
ws_nud_table_reset(cur);
|
||||
|
@ -1520,7 +1597,11 @@ static void ws_bootstrap_pan_config_analyse(struct protocol_interface_info_entry
|
|||
tr_info("Updated PAN configuration own:%d, heard:%d", cur->ws_info->pan_information.pan_version, pan_version);
|
||||
|
||||
// restart PAN version timer
|
||||
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
|
||||
//Check Here Do we have a selected Primary parent
|
||||
if (!cur->ws_info->configuration_learned || cur->ws_info->rpl_state == RPL_EVENT_DAO_DONE) {
|
||||
cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout;
|
||||
}
|
||||
|
||||
cur->ws_info->pan_information.pan_version = pan_version;
|
||||
|
||||
ws_pae_controller_gtk_hash_update(cur, gtkhash_ptr);
|
||||
|
|
|
@ -273,4 +273,11 @@ extern uint8_t DEVICE_MIN_SENS;
|
|||
#define RADIUS_CLIENT_RETRY_IMAX 30 // First retry maximum 3 seconds
|
||||
#define RADIUS_CLIENT_TIMER_EXPIRATIONS 3 // Number of retries is three
|
||||
|
||||
/*
|
||||
* EAP-TLS fragment length
|
||||
*
|
||||
* Configures both EAP-TLS and the RADIUS client (Framed-MTU on RFC 2864)
|
||||
*/
|
||||
#define EAP_TLS_FRAGMENT_LEN_VALUE 600 // EAP-TLS fragment length
|
||||
|
||||
#endif /* WS_CONFIG_H_ */
|
||||
|
|
|
@ -66,11 +66,14 @@ int8_t ws_eapol_relay_start(protocol_interface_info_entry_t *interface_ptr, uint
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (ws_eapol_relay_get(interface_ptr)) {
|
||||
eapol_relay_t *eapol_relay = ws_eapol_relay_get(interface_ptr);
|
||||
|
||||
if (eapol_relay) {
|
||||
memcpy(&eapol_relay->remote_addr.address, remote_addr, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
eapol_relay_t *eapol_relay = ns_dyn_mem_alloc(sizeof(eapol_relay_t));
|
||||
eapol_relay = ns_dyn_mem_alloc(sizeof(eapol_relay_t));
|
||||
if (!eapol_relay) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1221,7 +1221,8 @@ int8_t ws_pae_controller_radius_address_set(int8_t interface_id, const uint8_t *
|
|||
}
|
||||
|
||||
if (ws_pae_auth_radius_address_set(controller->interface_ptr, radius_cfg->radius_addr) < 0) {
|
||||
return -1;
|
||||
// If not set here since authenticator not created, then set on authenticator initialization
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -639,6 +639,21 @@ if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cu
|
|||
}
|
||||
|
||||
#ifdef HAVE_IPV6_ND
|
||||
|
||||
static uint8_t icmpv6_dns_search_list_remove_pad(uint8_t *data_ptr, uint8_t length)
|
||||
{
|
||||
while (length) {
|
||||
|
||||
if (data_ptr[length - 2] && data_ptr[length - 1] == 0) {
|
||||
break;
|
||||
} else if (data_ptr[length - 2] == 0 && data_ptr[length - 1] == 0) {
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static buffer_t *icmpv6_ra_handler(buffer_t *buf)
|
||||
{
|
||||
protocol_interface_info_entry_t *cur;
|
||||
|
@ -869,7 +884,8 @@ static buffer_t *icmpv6_ra_handler(buffer_t *buf)
|
|||
uint32_t dns_lifetime = common_read_32_bit(dptr + 2); // 2 x reserved
|
||||
uint8_t *dns_search_list = dptr + 6;
|
||||
uint8_t dns_search_list_len = length - 8; // Length includes type and length
|
||||
|
||||
//Cut Padding
|
||||
dns_search_list_len = icmpv6_dns_search_list_remove_pad(dns_search_list, dns_search_list_len);
|
||||
//tr_info("DNS Search List: %s Lifetime: %lu", trace_array(dns_search_list, dns_search_list_len), (unsigned long) dns_lifetime);
|
||||
// Add DNS server to DNS information storage.
|
||||
net_dns_server_search_list_set(cur->id, buf->src_sa.address, dns_search_list, dns_search_list_len, dns_lifetime);
|
||||
|
|
|
@ -115,12 +115,29 @@ int DHCPv6_server_respond_client(dhcpv6_gua_server_entry_s *serverBase, dhcpv6_r
|
|||
}
|
||||
|
||||
response->responseLength = libdhcpv6_address_reply_message_len(replyPacket->clientDUID.duid_length, replyPacket->serverDUID.duid_length, 0, replyPacket->rapidCommit, address_allocated);
|
||||
//Calculate DNS LIST and Vendor data lengths here
|
||||
response->responseLength += libdhcpv6_dns_server_message_sizes(serverBase);
|
||||
response->responseLength += libdhcpv6_vendor_data_message_sizes(serverBase);
|
||||
|
||||
response->responsePtr = ns_dyn_mem_temporary_alloc(response->responseLength);
|
||||
if (response->responsePtr) {
|
||||
uint8_t *ptr = response->responsePtr;
|
||||
//Write Generic data at beginning
|
||||
ptr = libdhcpv6_header_write(ptr, DHCPV6_REPLY_TYPE, replyPacket->transaction_ID);
|
||||
ptr = libdhcpv6_duid_option_write(ptr, DHCPV6_SERVER_ID_OPTION, &replyPacket->serverDUID); //16
|
||||
ptr = libdhcpv6_duid_option_write(ptr, DHCPV6_CLIENT_ID_OPTION, &replyPacket->clientDUID); //16
|
||||
if (address_allocated) {
|
||||
libdhcpv6_reply_message_write(response->responsePtr, replyPacket, &nonTemporalAddress, NULL);
|
||||
ptr = libdhcpv6_identity_association_option_write(ptr, replyPacket->iaId, replyPacket->T0, replyPacket->T1, true);
|
||||
ptr = libdhcpv6_ia_address_option_write(ptr, nonTemporalAddress.requestedAddress, nonTemporalAddress.preferredLifeTime, nonTemporalAddress.validLifeTime);
|
||||
//Write DNS LIST and Vendor data here
|
||||
ptr = libdhcpv6_dns_server_message_writes(serverBase, ptr);
|
||||
ptr = libdhcpv6_vendor_data_message_writes(serverBase, ptr);
|
||||
} else {
|
||||
libdhcpv6_reply_message_write(response->responsePtr, replyPacket, NULL, NULL);
|
||||
ptr = libdhcpv6_identity_association_option_write_with_status(ptr, replyPacket->iaId, replyPacket->T0, replyPacket->T1, DHCPV6_STATUS_NO_ADDR_AVAILABLE_CODE);
|
||||
}
|
||||
|
||||
if (replyPacket->rapidCommit) {
|
||||
ptr = libdhcpv6_rapid_commit_option_write(ptr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -407,6 +424,71 @@ int DHCPv6_server_service_set_address_validlifetime(int8_t interface, uint8_t gu
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DHCPv6_server_service_set_dns_server(int8_t interface, uint8_t guaPrefix[static 16], uint8_t dns_server_address[static 16], uint8_t *dns_search_list_ptr, uint8_t dns_search_list_len)
|
||||
{
|
||||
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interface, guaPrefix);
|
||||
if (!serverInfo) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dhcpv6_dns_server_data_t *dns_entry = libdhcpv6_dns_server_allocate(serverInfo, dns_server_address);
|
||||
if (!dns_entry) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dns_entry->search_list_length != dns_search_list_len) {
|
||||
ns_dyn_mem_free(dns_entry->search_list);
|
||||
dns_entry->search_list = NULL;
|
||||
dns_entry->search_list_length = 0;
|
||||
if (dns_search_list_len) {
|
||||
dns_entry->search_list = ns_dyn_mem_alloc(dns_search_list_len);
|
||||
if (dns_entry->search_list) {
|
||||
dns_entry->search_list_length = dns_search_list_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dns_entry->search_list_length) {
|
||||
//Copy Search List to allocated buffer
|
||||
memcpy(dns_entry->search_list, dns_search_list_ptr, dns_entry->search_list_length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DHCPv6_server_service_set_vendor_data(int8_t interface, uint8_t guaPrefix[static 16], uint32_t enterprise_number, uint8_t *dhcp_vendor_data_ptr, uint8_t dhcp_vendor_data_len)
|
||||
{
|
||||
dhcpv6_gua_server_entry_s *serverInfo = libdhcpv6_server_data_get_by_prefix_and_interfaceid(interface, guaPrefix);
|
||||
if (!serverInfo) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dhcpv6_vendor_data_t *vendor_data_entry = libdhcpv6_vendor_data_allocate(serverInfo, enterprise_number);
|
||||
|
||||
if (!vendor_data_entry) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vendor_data_entry->vendor_data_length != dhcp_vendor_data_len) {
|
||||
ns_dyn_mem_free(vendor_data_entry->vendor_data);
|
||||
vendor_data_entry->vendor_data = NULL;
|
||||
vendor_data_entry->vendor_data_length = 0;
|
||||
if (dhcp_vendor_data_len) {
|
||||
vendor_data_entry->vendor_data = ns_dyn_mem_alloc(dhcp_vendor_data_len);
|
||||
if (vendor_data_entry->vendor_data) {
|
||||
vendor_data_entry->vendor_data_length = dhcp_vendor_data_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vendor_data_entry->vendor_data_length) {
|
||||
//Copy Venfor Data to allocated buffer
|
||||
memcpy(vendor_data_entry->vendor_data, dhcp_vendor_data_ptr, vendor_data_entry->vendor_data_length);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int DHCPv6_server_service_init(int8_t interface, uint8_t guaPrefix[static 16], uint8_t serverDUID[static 8], uint16_t serverDUIDType)
|
||||
|
|
|
@ -89,6 +89,11 @@ int DHCPv6_server_service_set_max_clients_accepts_count(int8_t interface, uint8_
|
|||
* /param validLifeTimne in seconds
|
||||
*/
|
||||
int DHCPv6_server_service_set_address_validlifetime(int8_t interface, uint8_t guaPrefix[static 16], uint32_t validLifeTimne);
|
||||
|
||||
int DHCPv6_server_service_set_dns_server(int8_t interface, uint8_t guaPrefix[static 16], uint8_t dns_server_address[static 16], uint8_t *dns_search_list_ptr, uint8_t dns_search_list_len);
|
||||
|
||||
int DHCPv6_server_service_set_vendor_data(int8_t interface, uint8_t guaPrefix[static 16], uint32_t enterprise_number, uint8_t *dhcp_vendor_data_ptr, uint8_t dhcp_vendor_data_len);
|
||||
|
||||
#else
|
||||
#define DHCPv6_server_service_delete(interface, guaPrefix, delete_gua_addresses)
|
||||
#endif
|
||||
|
|
|
@ -79,8 +79,48 @@ void dhcp_client_delete(int8_t interface);
|
|||
*/
|
||||
typedef void (dhcp_client_global_adress_cb)(int8_t interface, uint8_t dhcp_addr[static 16], uint8_t prefix[static 16], bool register_status);
|
||||
|
||||
typedef struct dhcp_server_notify_info {
|
||||
uint16_t duid_type;
|
||||
uint16_t duid_length;
|
||||
uint32_t life_time;
|
||||
uint8_t *duid;
|
||||
} dhcp_server_notify_info_t;
|
||||
|
||||
|
||||
typedef struct dhcp_gen_option {
|
||||
uint16_t data_length;
|
||||
uint8_t *data;
|
||||
} dhcp_gen_option_t;
|
||||
|
||||
typedef struct dhcp_vendor_spesific_option {
|
||||
uint32_t enterprise_number;
|
||||
uint16_t data_length;
|
||||
uint8_t *data;
|
||||
} dhcp_vendor_spesific_option_t;
|
||||
|
||||
typedef struct dhcp_option_notify_s {
|
||||
uint8_t option_type;
|
||||
union {
|
||||
dhcp_gen_option_t generic;
|
||||
dhcp_vendor_spesific_option_t vendor_spesific;
|
||||
} option;
|
||||
} dhcp_option_notify_t;
|
||||
|
||||
/* give dhcp Client server Optional options notication
|
||||
*
|
||||
* /param interface interface id
|
||||
* /param option_type Type of option
|
||||
* /param option_data data of options.
|
||||
* /param option_length length of option.
|
||||
* /param server_info info inclu DUID and Life-time for notify options
|
||||
*
|
||||
*/
|
||||
typedef void (dhcp_client_options_notify_cb)(int8_t interface, dhcp_option_notify_t *options, dhcp_server_notify_info_t *server_info);
|
||||
|
||||
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);
|
||||
|
||||
int dhcp_client_option_notification_cb_set(int8_t interface, dhcp_client_options_notify_cb *notify_cb);
|
||||
|
||||
/* Renew all leased adddresses might be used when short address changes
|
||||
*
|
||||
* /param interface interface where address is got
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
typedef struct {
|
||||
dhcp_client_global_adress_cb *global_address_cb;
|
||||
dhcp_client_options_notify_cb *option_information_cb;
|
||||
uint16_t service_instance;
|
||||
uint16_t relay_instance;
|
||||
uint16_t sol_timeout;
|
||||
|
@ -152,6 +153,17 @@ void dhcp_client_solicit_timeout_set(int8_t interface, uint16_t timeout, uint16_
|
|||
return;
|
||||
}
|
||||
|
||||
int dhcp_client_option_notification_cb_set(int8_t interface, dhcp_client_options_notify_cb *notify_cb)
|
||||
{
|
||||
dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface);
|
||||
if (!dhcp_client) {
|
||||
return -1;
|
||||
}
|
||||
dhcp_client->option_information_cb = notify_cb;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void dhcp_relay_agent_enable(int8_t interface, uint8_t border_router_address[static 16])
|
||||
{
|
||||
dhcp_client_class_t *dhcp_client = dhcpv6_client_entry_discover(interface);
|
||||
|
@ -215,6 +227,67 @@ void dhcpv6_client_send_error_cb(dhcpv6_client_server_data_t *srv_data_ptr)
|
|||
}
|
||||
|
||||
|
||||
static void dhcp_vendor_information_notify(uint8_t *ptr, uint16_t data_len, dhcp_client_class_t *dhcp_client, dhcpv6_client_server_data_t *srv_data_ptr)
|
||||
{
|
||||
if (!dhcp_client->option_information_cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!srv_data_ptr->iaNontemporalAddress.validLifetime) {
|
||||
return; //Valid Lifetime zero
|
||||
}
|
||||
|
||||
dhcp_option_notify_t dhcp_option;
|
||||
|
||||
uint16_t type, length;
|
||||
bool valid_optional_options;
|
||||
|
||||
dhcp_server_notify_info_t server_info;
|
||||
server_info.life_time = srv_data_ptr->iaNontemporalAddress.validLifetime;
|
||||
server_info.duid = srv_data_ptr->serverDUID.duid + 2; // Skip the type
|
||||
server_info.duid_type = srv_data_ptr->serverDUID.type;
|
||||
server_info.duid_length = srv_data_ptr->serverDUID.duid_length - 2;// remove the type
|
||||
|
||||
while (data_len >= 4) {
|
||||
type = common_read_16_bit(ptr);
|
||||
ptr += 2;
|
||||
length = common_read_16_bit(ptr);
|
||||
ptr += 2;
|
||||
data_len -= 4;
|
||||
if (data_len < length) {
|
||||
return;
|
||||
}
|
||||
valid_optional_options = false;
|
||||
//Accept only listed items below with validated lengths
|
||||
if ((type == DHCPV6_OPTION_VENDOR_SPECIFIC_INFO || type == DHCPV6_OPTION_VENDOR_CLASS) && data_len >= 4) {
|
||||
valid_optional_options = true;
|
||||
//Parse enterprise number
|
||||
dhcp_option.option.vendor_spesific.enterprise_number = common_read_32_bit(ptr);
|
||||
ptr += 4;
|
||||
data_len -= 4;
|
||||
length -= 4;
|
||||
dhcp_option.option.vendor_spesific.data = ptr;
|
||||
dhcp_option.option.vendor_spesific.data_length = length;
|
||||
|
||||
|
||||
} else if (type == DHCPV6_OPTION_DNS_SERVERS && (length >= 16 && ((length % 16) == 0))) {
|
||||
valid_optional_options = true;
|
||||
dhcp_option.option.generic.data = ptr;
|
||||
dhcp_option.option.generic.data_length = length;
|
||||
} else if (type == DHCPV6_OPTION_DOMAIN_LIST) {
|
||||
valid_optional_options = true;
|
||||
dhcp_option.option.generic.data = ptr;
|
||||
dhcp_option.option.generic.data_length = length;
|
||||
}
|
||||
if (valid_optional_options) {
|
||||
dhcp_option.option_type = type;
|
||||
dhcp_client->option_information_cb(dhcp_client->interface, &dhcp_option, &server_info);
|
||||
}
|
||||
data_len -= length;
|
||||
ptr += length;
|
||||
}
|
||||
}
|
||||
|
||||
/* solication responce received for either global address or routter id assignment */
|
||||
int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uint8_t *msg_ptr, uint16_t msg_len)
|
||||
{
|
||||
|
@ -310,6 +383,10 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
|
|||
if (dhcp_client->global_address_cb) {
|
||||
dhcp_client->global_address_cb(dhcp_client->interface, srv_data_ptr->server_address, srv_data_ptr->iaNontemporalAddress.addressPrefix, status);
|
||||
}
|
||||
|
||||
//Optional Options notify from Reply
|
||||
dhcp_vendor_information_notify(msg_ptr, msg_len, dhcp_client, srv_data_ptr);
|
||||
|
||||
return RET_MSG_ACCEPTED;
|
||||
error_exit:
|
||||
dhcpv6_client_send_error_cb(srv_data_ptr);
|
||||
|
|
|
@ -91,7 +91,7 @@ int8_t kmp_socket_if_register(kmp_service_t *service, uint8_t *instance_id, bool
|
|||
if (*instance_id == 0) {
|
||||
socket_if->instance_id = kmp_socket_if_instance_id++;
|
||||
if (socket_if->instance_id == 0) {
|
||||
socket_if->instance_id++;
|
||||
socket_if->instance_id = kmp_socket_if_instance_id++;
|
||||
}
|
||||
*instance_id = socket_if->instance_id;
|
||||
}
|
||||
|
|
|
@ -201,8 +201,8 @@ static int8_t eap_tls_sec_prot_lib_ack_update(tls_data_t *tls)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (tls->handled_len + TLS_FRAGMENT_LEN < tls->total_len) {
|
||||
tls->handled_len += TLS_FRAGMENT_LEN;
|
||||
if (tls->handled_len + EAP_TLS_FRAGMENT_LEN_VALUE < tls->total_len) {
|
||||
tls->handled_len += EAP_TLS_FRAGMENT_LEN_VALUE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -236,8 +236,8 @@ static uint8_t *eap_tls_sec_prot_lib_fragment_write(uint8_t *data, uint16_t tota
|
|||
data_begin[0] = *flags;
|
||||
}
|
||||
|
||||
if (total_len - handled_len > TLS_FRAGMENT_LEN) {
|
||||
*message_len += TLS_FRAGMENT_LEN;
|
||||
if (total_len - handled_len > EAP_TLS_FRAGMENT_LEN_VALUE) {
|
||||
*message_len += EAP_TLS_FRAGMENT_LEN_VALUE;
|
||||
|
||||
if (handled_len == 0) {
|
||||
data_begin -= 4; // length
|
||||
|
|
|
@ -54,7 +54,6 @@ typedef struct {
|
|||
uint16_t handled_len; /**< Handled length of the data buffer (e.g. acked by other end) */
|
||||
} tls_data_t;
|
||||
|
||||
#define TLS_FRAGMENT_LEN 600 //EAP-TLS fragment length
|
||||
#define TLS_HEAD_LEN 5 //EAP-TLS flags and EAP-TLS length
|
||||
|
||||
extern const uint8_t eap_msg_trace[4][10];
|
||||
|
|
|
@ -495,7 +495,7 @@ static void radius_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
|
||||
// On timeout
|
||||
if (sec_prot_result_timeout_check(&data->common)) {
|
||||
// Do nothing for now
|
||||
// Do nothing (trickle timer not running, so should not happen)
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
// EUI-64 in ascii string: 00-11-..-77
|
||||
#define STATION_ID_LEN 16 + 7
|
||||
|
||||
// MTU value TBD
|
||||
#define FRAMED_MTU 1400
|
||||
// MTU value is set by EAP-TLS fragment length
|
||||
#define FRAMED_MTU EAP_TLS_FRAGMENT_LEN_VALUE
|
||||
|
||||
#define NAS_PORT 1
|
||||
|
||||
|
|
|
@ -508,7 +508,9 @@ static int8_t radius_client_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16
|
|||
if (radius_client_sec_prot_ms_mppe_recv_key_pmk_decrypt(prot, recv_key,
|
||||
recv_key_len - AVP_FIXED_LEN, data->request_authenticator, data->new_pmk) >= 0) {
|
||||
data->new_pmk_set = true;
|
||||
#ifdef EXTRA_DEBUG_INFO
|
||||
tr_info("RADIUS PMK: %s %s", tr_array(data->new_pmk, 16), tr_array(data->new_pmk + 16, 16));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -859,13 +859,13 @@ static uint32_t fhss_ws_get_retry_period_callback(const fhss_api_t *api, uint8_t
|
|||
if (!fhss_structure) {
|
||||
return return_value;
|
||||
}
|
||||
// We don't know the broadcast schedule, use large backoff with MAC retries
|
||||
// We don't know the broadcast schedule, use randomised large backoff with MAC retries
|
||||
if (fhss_structure->ws->broadcast_timer_running == false) {
|
||||
return 100000;
|
||||
return (uint32_t) randLIB_get_random_in_range(20000, 45000);
|
||||
}
|
||||
// We don't know the TX/RX slots, use randomised large backoff with MAC retries
|
||||
if (fhss_structure->own_hop == 0xff) {
|
||||
return ((uint32_t) randLIB_get_random_in_range(50, 150) * 1000);
|
||||
return (uint32_t) randLIB_get_random_in_range(20000, 45000);
|
||||
}
|
||||
if (fhss_structure->ws->is_on_bc_channel == true) {
|
||||
return return_value;
|
||||
|
|
|
@ -234,6 +234,10 @@ dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_validate_class_pointer(void *
|
|||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t libdhcpv6_vendor_option_size(uint16_t vendor_data_length)
|
||||
{
|
||||
return vendor_data_length + 8; // ID Type 2, length 2 ,Enterpise number 4
|
||||
}
|
||||
|
||||
uint16_t libdhcpv6_duid_option_size(uint16_t duidLength)
|
||||
{
|
||||
|
@ -324,15 +328,6 @@ uint8_t *libdhcpv6_rapid_commit_option_write(uint8_t *ptr)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
uint8_t *libdhcvp6_vendor_specific_option_write(uint8_t *ptr, uint8_t *data, uint16_t dataLength)
|
||||
{
|
||||
ptr = common_write_16_bit(DHCPV6_OPTION_VENDOR_SPECIFIC_INFO, ptr);
|
||||
ptr = common_write_16_bit(dataLength, ptr);
|
||||
memcpy(ptr, data, dataLength);
|
||||
ptr += dataLength;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint8_t *libdhcvp6_request_option_write(uint8_t *ptr, uint8_t optionCnt, uint16_t *optionPtr)
|
||||
{
|
||||
uint16_t optionLength = libdhcvp6_request_option_size(optionCnt);
|
||||
|
@ -840,31 +835,6 @@ uint8_t *libdhcpv6_generic_nontemporal_address_message_write(uint8_t *ptr, dhcpv
|
|||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *libdhcpv6_reply_message_write(uint8_t *ptr, dhcpv6_reply_packet_s *replyPacket, dhcpv6_ia_non_temporal_address_s *nonTemporalAddress, dhcpv6_vendor_data_packet_s *vendorData)
|
||||
{
|
||||
ptr = libdhcpv6_header_write(ptr, DHCPV6_REPLY_TYPE, replyPacket->transaction_ID);
|
||||
ptr = libdhcpv6_duid_option_write(ptr, DHCPV6_SERVER_ID_OPTION, &replyPacket->serverDUID); //16
|
||||
ptr = libdhcpv6_duid_option_write(ptr, DHCPV6_CLIENT_ID_OPTION, &replyPacket->clientDUID); //16
|
||||
|
||||
if (nonTemporalAddress) {
|
||||
ptr = libdhcpv6_identity_association_option_write(ptr, replyPacket->iaId, replyPacket->T0, replyPacket->T1, true);
|
||||
ptr = libdhcpv6_ia_address_option_write(ptr, nonTemporalAddress->requestedAddress, nonTemporalAddress->preferredLifeTime, nonTemporalAddress->validLifeTime);
|
||||
} else {
|
||||
ptr = libdhcpv6_identity_association_option_write_with_status(ptr, replyPacket->iaId, replyPacket->T0, replyPacket->T1, DHCPV6_STATUS_NO_ADDR_AVAILABLE_CODE);
|
||||
}
|
||||
|
||||
if (vendorData) {
|
||||
ptr = libdhcvp6_vendor_specific_option_write(ptr, vendorData->vendorData, vendorData->vendorDataLength);
|
||||
}
|
||||
|
||||
if (replyPacket->rapidCommit) {
|
||||
ptr = libdhcpv6_rapid_commit_option_write(ptr);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint16_t libdhcpv6_solication_message_length(uint16_t clientDUIDLength, bool addressDefined, uint8_t requestOptionCount)
|
||||
{
|
||||
uint16_t length = 0;
|
||||
|
|
|
@ -217,9 +217,13 @@ typedef struct dhcpv6_relay_msg {
|
|||
#define DHCPV6_OPTION_IA_PREFIX_DELEGATION_MIN_LENGTH 0x000c
|
||||
/** Identity Association END */
|
||||
|
||||
#define DHCPV6_OPTION_VENDOR_CLASS 0x0010
|
||||
#define DHCPV6_OPTION_VENDOR_SPECIFIC_INFO 0x0011
|
||||
/** SEQUENCYID, RouterIDMask 32-bit*/
|
||||
|
||||
#define DHCPV6_OPTION_DNS_SERVERS 0x0017
|
||||
#define DHCPV6_OPTION_DOMAIN_LIST 0x0018
|
||||
|
||||
#define DHCPV6_STATUS_CODE_OPTION 0x000d
|
||||
#define DHCPV6_STATUS_CODE_OPTION_LEN 0x0002
|
||||
#define DHCPV6_STATUS_NO_ADDR_AVAILABLE_CODE 0x0002
|
||||
|
@ -277,6 +281,7 @@ uint16_t libdhcpv6_duid_option_size(uint16_t duidLength);
|
|||
uint8_t libdhcpv6_duid_linktype_size(uint16_t linkType);
|
||||
uint16_t libdhcvp6_request_option_size(uint8_t optionCnt);
|
||||
uint16_t libdhcpv6_non_temporal_address_size(bool addressDefined);
|
||||
uint16_t libdhcpv6_vendor_option_size(uint16_t vendor_data_length);
|
||||
|
||||
uint16_t libdhcpv6_solication_message_length(uint16_t clientDUIDLength, bool addressDefined, uint8_t requestOptionCount);
|
||||
uint16_t libdhcpv6_address_request_message_len(uint16_t clientDUIDLength, uint16_t serverDUIDLength, uint8_t requstOptionCnt, bool add_address);
|
||||
|
@ -287,7 +292,6 @@ uint16_t libdhcpv6_address_reply_message_len(uint16_t clientDUIDLength, uint16_t
|
|||
#endif
|
||||
|
||||
uint8_t *libdhcpv6_generic_nontemporal_address_message_write(uint8_t *ptr, dhcpv6_solication_base_packet_s *packet, dhcpv6_ia_non_temporal_address_s *nonTemporalAddress, dhcp_duid_options_params_t *serverLink);
|
||||
uint8_t *libdhcpv6_reply_message_write(uint8_t *ptr, dhcpv6_reply_packet_s *replyPacket, dhcpv6_ia_non_temporal_address_s *nonTemporalAddress, dhcpv6_vendor_data_packet_s *vendorData);
|
||||
uint8_t *libdhcpv6_dhcp_relay_msg_write(uint8_t *ptr, uint8_t type, uint8_t hop_limit, uint8_t *peer_addres, uint8_t *link_address);
|
||||
uint8_t *libdhcpv6_dhcp_option_header_write(uint8_t *ptr, uint16_t length);
|
||||
|
||||
|
@ -327,17 +331,6 @@ uint8_t *libdhcpv6_elapsed_time_option_write(uint8_t *ptr, uint16_t elapsedTime)
|
|||
*/
|
||||
uint8_t *libdhcpv6_rapid_commit_option_write(uint8_t *ptr);
|
||||
|
||||
/**
|
||||
* This Function write dhcpv6 thread requested vendor spesific data
|
||||
*
|
||||
* \param ptr pointer where option will be writed
|
||||
* \param data Vendor Data
|
||||
* \param dataLength Vendor Data length
|
||||
*
|
||||
* return incremented pointer after write
|
||||
*/
|
||||
uint8_t *libdhcvp6_vendor_specific_option_write(uint8_t *ptr, uint8_t *data, uint16_t dataLength);
|
||||
|
||||
/**
|
||||
* This Function write dhcpv6 request option write
|
||||
*
|
||||
|
@ -379,6 +372,6 @@ int libdhcpv6_solication_message_options_validate(uint8_t *ptr, uint16_t data_le
|
|||
int libdhcpv6_advertisment_message_option_validate(dhcp_duid_options_params_t *clientId, dhcp_duid_options_params_t *serverId, dhcp_ia_non_temporal_params_t *dhcp_ia_non_temporal_params, uint8_t *ptr, uint16_t data_length);
|
||||
bool libdhcpv6_rapid_commit_option_at_packet(uint8_t *ptr, uint16_t length);
|
||||
bool libdhcpv6_time_elapsed_option_at_packet(uint8_t *ptr, uint16_t length);
|
||||
bool libdhcpv6_relay_msg_read(uint8_t *ptr, uint16_t length, dhcpv6_relay_msg_t *relay_msg);
|
||||
|
||||
bool libdhcpv6_relay_msg_read(uint8_t *ptr, uint16_t length, dhcpv6_relay_msg_t *relay_msg);
|
||||
#endif /* LIBDHCPV6_H_ */
|
||||
|
|
|
@ -58,6 +58,8 @@ static dhcpv6_gua_server_entry_s *libdhcpv6_server_entry_allocate(void)
|
|||
entry->removeCb = NULL;
|
||||
entry->addCb = NULL;
|
||||
ns_list_init(&entry->allocatedAddressList);
|
||||
ns_list_init(&entry->dnsServerList);
|
||||
ns_list_init(&entry->vendorDataList);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
@ -338,6 +340,20 @@ void libdhcpv6_gua_server_free_by_prefix_and_interfaceid(uint8_t *prefix, int8_t
|
|||
ns_list_remove(&serverInfo->allocatedAddressList, cur);
|
||||
ns_dyn_mem_free(cur);
|
||||
}
|
||||
|
||||
ns_list_foreach_safe(dhcpv6_dns_server_data_t, cur, &serverInfo->dnsServerList) {
|
||||
//DNS Server Info Remove
|
||||
ns_list_remove(&serverInfo->dnsServerList, cur);
|
||||
ns_dyn_mem_free(cur->search_list);
|
||||
ns_dyn_mem_free(cur);
|
||||
}
|
||||
|
||||
ns_list_foreach_safe(dhcpv6_vendor_data_t, cur, &serverInfo->vendorDataList) {
|
||||
ns_list_remove(&serverInfo->vendorDataList, cur);
|
||||
ns_dyn_mem_free(cur->vendor_data);
|
||||
ns_dyn_mem_free(cur);
|
||||
}
|
||||
|
||||
ns_list_remove(&dhcpv6_gua_server_list, serverInfo);
|
||||
ns_dyn_mem_free(serverInfo->serverDynamic_DUID);
|
||||
ns_dyn_mem_free(serverInfo);
|
||||
|
@ -494,5 +510,119 @@ dhcpv6_allocated_address_t *libdhcpv6_address_allocated_list_scan(dhcpv6_gua_ser
|
|||
return newEntry;
|
||||
}
|
||||
|
||||
dhcpv6_dns_server_data_t *libdhcpv6_dns_server_discover(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address)
|
||||
{
|
||||
ns_list_foreach(dhcpv6_dns_server_data_t, cur, &serverInfo->dnsServerList) {
|
||||
if (memcmp(cur->server_address, address, 16) == 0) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dhcpv6_dns_server_data_t *libdhcpv6_dns_server_allocate(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address)
|
||||
{
|
||||
dhcpv6_dns_server_data_t *entry = libdhcpv6_dns_server_discover(serverInfo, address);
|
||||
if (entry) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
entry = ns_dyn_mem_alloc(sizeof(dhcpv6_dns_server_data_t));
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
ns_list_add_to_end(&serverInfo->dnsServerList, entry);
|
||||
memcpy(entry->server_address, address, 16);
|
||||
entry->search_list = NULL;
|
||||
entry->search_list_length = 0;
|
||||
return entry;
|
||||
}
|
||||
|
||||
dhcpv6_vendor_data_t *libdhcpv6_vendor_data_discover(dhcpv6_gua_server_entry_s *serverInfo, uint32_t enterprise_number)
|
||||
{
|
||||
ns_list_foreach(dhcpv6_vendor_data_t, cur, &serverInfo->vendorDataList) {
|
||||
if (cur->enterprise_number == enterprise_number) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dhcpv6_vendor_data_t *libdhcpv6_vendor_data_allocate(dhcpv6_gua_server_entry_s *serverInfo, uint32_t enterprise_number)
|
||||
{
|
||||
dhcpv6_vendor_data_t *entry = libdhcpv6_vendor_data_discover(serverInfo, enterprise_number);
|
||||
|
||||
if (entry) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
entry = ns_dyn_mem_alloc(sizeof(dhcpv6_vendor_data_t));
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
ns_list_add_to_end(&serverInfo->vendorDataList, entry);
|
||||
entry->enterprise_number = enterprise_number;
|
||||
entry->vendor_data = NULL;
|
||||
entry->vendor_data_length = 0;
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
uint16_t libdhcpv6_dns_server_message_sizes(dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
uint16_t message_size = 0;
|
||||
ns_list_foreach(dhcpv6_dns_server_data_t, cur, &serverInfo->dnsServerList) {
|
||||
message_size += 4 + 16; //Type Length + address //
|
||||
//Search List part
|
||||
message_size += 4 + cur->search_list_length; //Type Length + search_list_length
|
||||
}
|
||||
return message_size;
|
||||
}
|
||||
|
||||
uint16_t libdhcpv6_vendor_data_message_sizes(dhcpv6_gua_server_entry_s *serverInfo)
|
||||
{
|
||||
uint16_t message_size = 0;
|
||||
ns_list_foreach(dhcpv6_vendor_data_t, cur, &serverInfo->vendorDataList) {
|
||||
message_size += 4 + 4 + cur->vendor_data_length; //Type + Length + enterprise + vendor_data_length
|
||||
}
|
||||
return message_size;
|
||||
}
|
||||
|
||||
uint8_t *libdhcpv6_dns_server_message_writes(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *ptr)
|
||||
{
|
||||
ns_list_foreach(dhcpv6_dns_server_data_t, cur, &serverInfo->dnsServerList) {
|
||||
//Write first DNS Server info
|
||||
ptr = common_write_16_bit(DHCPV6_OPTION_DNS_SERVERS, ptr);
|
||||
ptr = common_write_16_bit(16, ptr); //Length
|
||||
memcpy(ptr, cur->server_address, 16);
|
||||
ptr += 16;
|
||||
|
||||
ptr = common_write_16_bit(DHCPV6_OPTION_DOMAIN_LIST, ptr);
|
||||
ptr = common_write_16_bit(cur->search_list_length, ptr); //Length
|
||||
if (cur->search_list_length) {
|
||||
memcpy(ptr, cur->search_list, cur->search_list_length);
|
||||
ptr += cur->search_list_length;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint8_t *libdhcpv6_vendor_data_message_writes(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *ptr)
|
||||
{
|
||||
ns_list_foreach(dhcpv6_vendor_data_t, cur, &serverInfo->vendorDataList) {
|
||||
|
||||
uint16_t length = cur->vendor_data_length + 4;
|
||||
ptr = common_write_16_bit(DHCPV6_OPTION_VENDOR_SPECIFIC_INFO, ptr);
|
||||
ptr = common_write_16_bit(length, ptr); //Length
|
||||
ptr = common_write_32_bit(cur->enterprise_number, ptr);
|
||||
if (cur->vendor_data_length) {
|
||||
memcpy(ptr, cur->vendor_data, cur->vendor_data_length);
|
||||
ptr += cur->vendor_data_length;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -45,6 +45,20 @@ typedef struct dhcpv6_allocated_address_entry_s {
|
|||
ns_list_link_t link; /*!< List link entry */
|
||||
} dhcpv6_allocated_address_entry_t;
|
||||
|
||||
typedef struct dhcpv6_dns_server_data_s {
|
||||
uint8_t server_address[16];
|
||||
uint8_t *search_list;
|
||||
uint8_t search_list_length;
|
||||
ns_list_link_t link; /*!< List link entry */
|
||||
} dhcpv6_dns_server_data_t;
|
||||
|
||||
typedef struct dhcpv6_vendor_data_s {
|
||||
uint32_t enterprise_number;
|
||||
uint8_t *vendor_data;
|
||||
uint8_t vendor_data_length;
|
||||
ns_list_link_t link; /*!< List link entry */
|
||||
} dhcpv6_vendor_data_t;
|
||||
|
||||
|
||||
typedef struct dhcpv6_allocated_address_s {
|
||||
uint8_t nonTemporalAddress[16];
|
||||
|
@ -58,6 +72,8 @@ typedef struct dhcpv6_allocated_address_s {
|
|||
} dhcpv6_allocated_address_t;
|
||||
|
||||
typedef NS_LIST_HEAD(dhcpv6_allocated_address_entry_t, link) dhcpv6_allocated_address_list_t;
|
||||
typedef NS_LIST_HEAD(dhcpv6_dns_server_data_t, link) dhcpv6_dns_server_list_t;
|
||||
typedef NS_LIST_HEAD(dhcpv6_vendor_data_t, link) dhcpv6_vendor_data_list_t;
|
||||
|
||||
typedef struct dhcp_address_cache_update {
|
||||
uint8_t *allocatedAddress;
|
||||
|
@ -84,6 +100,8 @@ typedef struct dhcpv6_gua_server_entry_s {
|
|||
dhcp_address_prefer_remove_cb *removeCb;
|
||||
dhcp_address_add_notify_cb *addCb;
|
||||
dhcpv6_allocated_address_list_t allocatedAddressList;
|
||||
dhcpv6_dns_server_list_t dnsServerList;
|
||||
dhcpv6_vendor_data_list_t vendorDataList;
|
||||
dhcpv6_allocated_address_t tempAddressEntry;
|
||||
ns_list_link_t link; /*!< List link entry */
|
||||
} dhcpv6_gua_server_entry_s;
|
||||
|
@ -99,6 +117,14 @@ dhcpv6_gua_server_entry_s *libdhcpv6_server_data_get_by_prefix_and_interfaceid(i
|
|||
dhcpv6_gua_server_entry_s *libdhcpv6_server_data_get_by_prefix_and_socketinstance(uint16_t socketInstance, uint8_t *prefixPtr);
|
||||
dhcpv6_allocated_address_t *libdhcpv6_address_allocated_list_scan(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *euid64, uint16_t linkType, uint32_t iaID, uint32_t T0, uint32_t T1, bool allocateNew);
|
||||
void libdhcpv6_allocated_address_write(uint8_t *ptr, dhcpv6_allocated_address_entry_t *address, dhcpv6_gua_server_entry_s *serverInfo);
|
||||
dhcpv6_dns_server_data_t *libdhcpv6_dns_server_discover(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||
dhcpv6_dns_server_data_t *libdhcpv6_dns_server_allocate(dhcpv6_gua_server_entry_s *serverInfo, const uint8_t *address);
|
||||
dhcpv6_vendor_data_t *libdhcpv6_vendor_data_discover(dhcpv6_gua_server_entry_s *serverInfo, uint32_t enterprise_number);
|
||||
dhcpv6_vendor_data_t *libdhcpv6_vendor_data_allocate(dhcpv6_gua_server_entry_s *serverInfo, uint32_t enterprise_number);
|
||||
uint16_t libdhcpv6_dns_server_message_sizes(dhcpv6_gua_server_entry_s *serverInfo);
|
||||
uint16_t libdhcpv6_vendor_data_message_sizes(dhcpv6_gua_server_entry_s *serverInfo);
|
||||
uint8_t *libdhcpv6_dns_server_message_writes(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *ptr);
|
||||
uint8_t *libdhcpv6_vendor_data_message_writes(dhcpv6_gua_server_entry_s *serverInfo, uint8_t *ptr);
|
||||
#else
|
||||
#define libdhcpv6_gua_server_list_empty() true
|
||||
#define libdhcpv6_server_data_get_by_prefix_and_interfaceid(interfaceId, prefixPtr) NULL
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nsconfig.h"
|
||||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include <string.h>
|
||||
#include "common_functions.h"
|
||||
#include "libDHCPv6.h"
|
||||
#include "libDHCPv6_vendordata.h"
|
||||
|
||||
#define TRACE_GROUP "vend"
|
||||
|
||||
|
||||
/* DHCPv6 vendor options to distribute ARM vendor data*/
|
||||
|
||||
uint16_t net_dns_option_vendor_option_data_dns_query_length(char *domain)
|
||||
{
|
||||
return 4 + 16 + strlen(domain) + 1;
|
||||
}
|
||||
|
||||
uint8_t *net_dns_option_vendor_option_data_dns_query_write(uint8_t *ptr, uint8_t *address, char *domain)
|
||||
{
|
||||
int domain_len = strlen(domain);
|
||||
int length = 16 + domain_len + 1;
|
||||
|
||||
ptr = common_write_16_bit(ARM_DHCP_VENDOR_DATA_DNS_QUERY_RESULT, ptr);
|
||||
ptr = common_write_16_bit(length, ptr);
|
||||
memcpy(ptr, address, 16);
|
||||
ptr += 16;
|
||||
memcpy(ptr, domain, domain_len + 1);
|
||||
ptr += domain_len + 1;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
uint16_t net_dns_option_vendor_option_data_get_next(uint8_t *ptr, uint16_t length, uint16_t *type)
|
||||
{
|
||||
uint16_t option_len;
|
||||
|
||||
if (length < 4) {
|
||||
// Corrupted
|
||||
return 0;
|
||||
}
|
||||
if (type) {
|
||||
*type = common_read_16_bit(ptr);
|
||||
}
|
||||
|
||||
option_len = common_read_16_bit(ptr + 2);
|
||||
if (option_len + 4 > length) {
|
||||
// Corrupted
|
||||
return 0;
|
||||
}
|
||||
|
||||
return option_len + 4;
|
||||
}
|
||||
|
||||
uint16_t net_dns_option_vendor_option_data_dns_query_read(uint8_t *ptr, uint16_t length, uint8_t **address, char **domain)
|
||||
{
|
||||
uint16_t option_len;
|
||||
option_len = common_read_16_bit(ptr + 2);
|
||||
|
||||
if (length < 4 + 16 + 1) {
|
||||
// Corrupted as there is no room for all fields
|
||||
return 0;
|
||||
}
|
||||
if (option_len < 17) {
|
||||
// Corrupted as not enough room in field
|
||||
return 0;
|
||||
}
|
||||
if (*(ptr + 4 + option_len - 1) != 0) {
|
||||
// Not nul terminated string for domain
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (common_read_16_bit(ptr) != ARM_DHCP_VENDOR_DATA_DNS_QUERY_RESULT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (address) {
|
||||
*address = ptr + 4;
|
||||
}
|
||||
if (domain) {
|
||||
*domain = (char *)(ptr + 4 + 16);
|
||||
}
|
||||
return option_len;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef LIBDHCPV6_VENDOR_DATA_H_
|
||||
#define LIBDHCPV6_VENDOR_DATA_H_
|
||||
|
||||
|
||||
/*ARM enterprise number used to identify ARM generated Vendor data options*/
|
||||
#define ARM_ENTERPRISE_NUMBER 4128
|
||||
|
||||
/* ARM Defined vendor data option to distribute DNS query results through DHCP server
|
||||
* Format
|
||||
*
|
||||
* uint8_t address[16]
|
||||
* domain string nul terminated.
|
||||
*
|
||||
* multiple results must be in separated vendor option data fields
|
||||
* */
|
||||
#define ARM_DHCP_VENDOR_DATA_DNS_QUERY_RESULT 297
|
||||
|
||||
/* DHCPv6 vendor options to distribute ARM vendor data*/
|
||||
|
||||
uint16_t net_dns_option_vendor_option_data_dns_query_length(char *domain);
|
||||
uint8_t *net_dns_option_vendor_option_data_dns_query_write(uint8_t *ptr, uint8_t *address, char *domain);
|
||||
|
||||
uint16_t net_dns_option_vendor_option_data_get_next(uint8_t *ptr, uint16_t length, uint16_t *type);
|
||||
uint16_t net_dns_option_vendor_option_data_dns_query_read(uint8_t *ptr, uint16_t length, uint8_t **address, char **domain);
|
||||
|
||||
|
||||
#endif /* LIBDHCPV6_VENDOR_DATA_H_ */
|
|
@ -115,7 +115,7 @@ int8_t net_dns_server_address_set(int8_t interface_id, const uint8_t address[16]
|
|||
}
|
||||
info_ptr->lifetime = lifetime;
|
||||
memcpy(info_ptr->dns_server_address, dns_server_address, 16);
|
||||
tr_info("DNS Server: %s Lifetime: %lu", trace_ipv6(info_ptr->dns_server_address), (unsigned long) info_ptr->lifetime);
|
||||
tr_info("DNS Server: %s from: %s Lifetime: %lu", trace_ipv6(info_ptr->dns_server_address), trace_ipv6(info_ptr->address), (unsigned long) info_ptr->lifetime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ static dns_query_t *dns_query_result_create(int8_t interface_id, const char *dom
|
|||
}
|
||||
this->interface_id = interface_id;
|
||||
strcpy(this->domain_str, domain_str);
|
||||
tr_debug("Create DNS query entry for %s", this->domain_str);
|
||||
//tr_debug("Create DNS query entry for %s", this->domain_str);
|
||||
ns_list_add_to_start(&dns_query_list, this);
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -205,6 +205,7 @@ SRCS += \
|
|||
source/DHCPv6_client/dhcpv6_client_service.c \
|
||||
source/libDHCPv6/dhcp_service_api.c \
|
||||
source/libDHCPv6/libDHCPv6.c \
|
||||
source/libDHCPv6/libDHCPv6_vendordata.c \
|
||||
source/libDHCPv6/libDHCPv6_server.c \
|
||||
source/Service_Libs/utils/ns_crc.c \
|
||||
source/Service_Libs/utils/isqrt.c \
|
||||
|
|
Loading…
Reference in New Issue