Merge commit '1ad46bb6f1fb40805aa9f72ccb50c87335febed7' into feature-wisun

* commit '1ad46bb6f1fb40805aa9f72ccb50c87335febed7':
  Squashed 'features/nanostack/sal-stack-nanostack/' changes from 91acececbd..d879e6db87
pull/13550/head
Arto Kinnunen 2020-09-04 13:53:21 +03:00
commit a43934c343
26 changed files with 748 additions and 80 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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];

View File

@ -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;
}

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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 \