mirror of https://github.com/ARMmbed/mbed-os.git
Added ipv6 support to lwip dns adaptation and updated dchp functionality
parent
283ee52228
commit
95383dde32
|
@ -29,7 +29,9 @@
|
||||||
#include "lwip/tcpip.h"
|
#include "lwip/tcpip.h"
|
||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp.h"
|
||||||
#include "lwip/ip.h"
|
#include "lwip/ip.h"
|
||||||
|
#include "lwip/mld6.h"
|
||||||
|
#include "lwip/dns.h"
|
||||||
|
#include "lwip/udp.h"
|
||||||
|
|
||||||
/* Static arena of sockets */
|
/* Static arena of sockets */
|
||||||
static struct lwip_socket {
|
static struct lwip_socket {
|
||||||
|
@ -94,6 +96,7 @@ static struct netif lwip_netif;
|
||||||
static bool lwip_dhcp = false;
|
static bool lwip_dhcp = false;
|
||||||
static char lwip_mac_address[NSAPI_MAC_SIZE] = "\0";
|
static char lwip_mac_address[NSAPI_MAC_SIZE] = "\0";
|
||||||
|
|
||||||
|
#if !LWIP_IPV4 || !LWIP_IPV6
|
||||||
static bool all_zeros(const uint8_t *p, int len)
|
static bool all_zeros(const uint8_t *p, int len)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
|
@ -104,6 +107,7 @@ static bool all_zeros(const uint8_t *p, int len)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool convert_mbed_addr_to_lwip(ip_addr_t *out, const nsapi_addr_t *in)
|
static bool convert_mbed_addr_to_lwip(ip_addr_t *out, const nsapi_addr_t *in)
|
||||||
{
|
{
|
||||||
|
@ -196,8 +200,8 @@ static const ip_addr_t *lwip_get_ipv6_addr(const struct netif *netif)
|
||||||
|
|
||||||
const ip_addr_t *lwip_get_ip_addr(bool any_addr, const struct netif *netif)
|
const ip_addr_t *lwip_get_ip_addr(bool any_addr, const struct netif *netif)
|
||||||
{
|
{
|
||||||
const ip_addr_t *pref_ip_addr;
|
const ip_addr_t *pref_ip_addr = 0;
|
||||||
const ip_addr_t *npref_ip_addr;
|
const ip_addr_t *npref_ip_addr = 0;
|
||||||
|
|
||||||
#if IP_VERSION_PREF == PREF_IPV4
|
#if IP_VERSION_PREF == PREF_IPV4
|
||||||
pref_ip_addr = lwip_get_ipv4_addr(netif);
|
pref_ip_addr = lwip_get_ipv4_addr(netif);
|
||||||
|
@ -216,6 +220,37 @@ const ip_addr_t *lwip_get_ip_addr(bool any_addr, const struct netif *netif)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LWIP_IPV6
|
||||||
|
void add_dns_addr(struct netif *lwip_netif)
|
||||||
|
{
|
||||||
|
const ip_addr_t *ip_addr = lwip_get_ip_addr(true, lwip_netif);
|
||||||
|
if (ip_addr) {
|
||||||
|
if (IP_IS_V6(ip_addr)) {
|
||||||
|
const ip_addr_t *dns_ip_addr;
|
||||||
|
bool dns_addr_exists = false;
|
||||||
|
|
||||||
|
for (char numdns = 0; numdns < DNS_MAX_SERVERS; numdns++) {
|
||||||
|
dns_ip_addr = dns_getserver(numdns);
|
||||||
|
if (!ip_addr_isany(dns_ip_addr)) {
|
||||||
|
dns_addr_exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dns_addr_exists) {
|
||||||
|
/* 2001:4860:4860::8888 google */
|
||||||
|
ip_addr_t ipv6_dns_addr = IPADDR6_INIT(
|
||||||
|
PP_HTONL(0x20014860UL),
|
||||||
|
PP_HTONL(0x48600000UL),
|
||||||
|
PP_HTONL(0x00000000UL),
|
||||||
|
PP_HTONL(0x00008888UL));
|
||||||
|
dns_setserver(0, &ipv6_dns_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static sys_sem_t lwip_tcpip_inited;
|
static sys_sem_t lwip_tcpip_inited;
|
||||||
static void lwip_tcpip_init_irq(void *eh)
|
static void lwip_tcpip_init_irq(void *eh)
|
||||||
{
|
{
|
||||||
|
@ -353,28 +388,6 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw)
|
||||||
// Zero out socket set
|
// Zero out socket set
|
||||||
lwip_arena_init();
|
lwip_arena_init();
|
||||||
|
|
||||||
// Connect to the network
|
|
||||||
lwip_dhcp = dhcp;
|
|
||||||
if (lwip_dhcp) {
|
|
||||||
err_t err = dhcp_start(&lwip_netif);
|
|
||||||
if (err) {
|
|
||||||
return NSAPI_ERROR_DHCP_FAILURE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ip_addr_t ip_addr;
|
|
||||||
ip_addr_t netmask_addr;
|
|
||||||
ip_addr_t gw_addr;
|
|
||||||
|
|
||||||
if (!inet_aton(ip, &ip_addr) ||
|
|
||||||
!inet_aton(netmask, &netmask_addr) ||
|
|
||||||
!inet_aton(gw, &gw_addr)) {
|
|
||||||
return NSAPI_ERROR_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
netif_set_addr(&lwip_netif, &ip_addr, &netmask_addr, &gw_addr);
|
|
||||||
netif_set_up(&lwip_netif);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LWIP_IPV6
|
#if LWIP_IPV6
|
||||||
netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/);
|
netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/);
|
||||||
#if LWIP_IPV6_MLD
|
#if LWIP_IPV6_MLD
|
||||||
|
@ -386,7 +399,7 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw)
|
||||||
if (lwip_netif.mld_mac_filter != NULL) {
|
if (lwip_netif.mld_mac_filter != NULL) {
|
||||||
ip6_addr_t ip6_allnodes_ll;
|
ip6_addr_t ip6_allnodes_ll;
|
||||||
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
|
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
|
||||||
lwip_netif.mld_mac_filter(&lwip_netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
|
lwip_netif.mld_mac_filter(&lwip_netif, &ip6_allnodes_ll, MLD6_ADD_MAC_FILTER);
|
||||||
}
|
}
|
||||||
#endif /* LWIP_IPV6_MLD */
|
#endif /* LWIP_IPV6_MLD */
|
||||||
|
|
||||||
|
@ -407,13 +420,40 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
if (!dhcp) {
|
||||||
|
ip4_addr_t ip_addr;
|
||||||
|
ip4_addr_t netmask_addr;
|
||||||
|
ip4_addr_t gw_addr;
|
||||||
|
|
||||||
|
if (!inet_aton(ip, &ip_addr) ||
|
||||||
|
!inet_aton(netmask, &netmask_addr) ||
|
||||||
|
!inet_aton(gw, &gw_addr)) {
|
||||||
|
return NSAPI_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
netif_set_addr(&lwip_netif, &ip_addr, &netmask_addr, &gw_addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
netif_set_up(&lwip_netif);
|
netif_set_up(&lwip_netif);
|
||||||
|
|
||||||
|
#if LWIP_IPV4
|
||||||
|
// Connect to the network
|
||||||
|
lwip_dhcp = dhcp;
|
||||||
|
|
||||||
|
if (lwip_dhcp) {
|
||||||
|
err_t err = dhcp_start(&lwip_netif);
|
||||||
|
if (err) {
|
||||||
|
return NSAPI_ERROR_DHCP_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// If doesn't have address
|
// If doesn't have address
|
||||||
if (!lwip_get_ip_addr(true, &lwip_netif)) {
|
if (!lwip_get_ip_addr(true, &lwip_netif)) {
|
||||||
//ret = sys_arch_sem_wait(&lwip_netif_has_addr, 15000);
|
//ret = sys_arch_sem_wait(&lwip_netif_has_addr, 15000);
|
||||||
ret = sys_arch_sem_wait(&lwip_netif_has_addr, 30000);
|
ret = sys_arch_sem_wait(&lwip_netif_has_addr, 30000);
|
||||||
|
|
||||||
if (ret == SYS_ARCH_TIMEOUT) {
|
if (ret == SYS_ARCH_TIMEOUT) {
|
||||||
return NSAPI_ERROR_DHCP_FAILURE;
|
return NSAPI_ERROR_DHCP_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -428,6 +468,10 @@ int lwip_bringup(bool dhcp, const char *ip, const char *netmask, const char *gw)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_IPV6
|
||||||
|
add_dns_addr(&lwip_netif);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +498,6 @@ int lwip_bringdown(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* LWIP error remapping */
|
/* LWIP error remapping */
|
||||||
static int lwip_err_remap(err_t err) {
|
static int lwip_err_remap(err_t err) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
|
@ -484,12 +527,27 @@ static int lwip_err_remap(err_t err) {
|
||||||
/* LWIP network stack implementation */
|
/* LWIP network stack implementation */
|
||||||
static int lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr)
|
static int lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr)
|
||||||
{
|
{
|
||||||
err_t err = netconn_gethostbyname(host, (ip_addr_t *)addr->bytes);
|
ip_addr_t lwip_addr;
|
||||||
|
|
||||||
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
|
u8_t addr_type;
|
||||||
|
const ip_addr_t *ip_addr;
|
||||||
|
ip_addr = lwip_get_ip_addr(true, &lwip_netif);
|
||||||
|
if (IP_IS_V6(ip_addr)) {
|
||||||
|
addr_type = NETCONN_DNS_IPV6;
|
||||||
|
} else {
|
||||||
|
addr_type = NETCONN_DNS_IPV4;
|
||||||
|
}
|
||||||
|
err_t err = netconn_gethostbyname_addrtype(host, &lwip_addr, addr_type);
|
||||||
|
#else
|
||||||
|
err_t err = netconn_gethostbyname(host, &lwip_addr);
|
||||||
|
#endif
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
return NSAPI_ERROR_DNS_FAILURE;
|
return NSAPI_ERROR_DNS_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr->version = NSAPI_IPv4;
|
convert_lwip_addr_to_mbed(addr, &lwip_addr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +567,7 @@ static int lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t *handle, nsapi_
|
||||||
u8_t lwip_proto = proto == NSAPI_TCP ? NETCONN_TCP : NETCONN_UDP;
|
u8_t lwip_proto = proto == NSAPI_TCP ? NETCONN_TCP : NETCONN_UDP;
|
||||||
|
|
||||||
#if LWIP_IPV6 && LWIP_IPV4
|
#if LWIP_IPV6 && LWIP_IPV4
|
||||||
ip_addr_t *ip_addr;
|
const ip_addr_t *ip_addr;
|
||||||
ip_addr = lwip_get_ip_addr(true, &lwip_netif);
|
ip_addr = lwip_get_ip_addr(true, &lwip_netif);
|
||||||
|
|
||||||
if (IP_IS_V6(ip_addr)) {
|
if (IP_IS_V6(ip_addr)) {
|
||||||
|
|
|
@ -289,17 +289,7 @@ void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16
|
||||||
{
|
{
|
||||||
_ip_address[0] = '\0';
|
_ip_address[0] = '\0';
|
||||||
|
|
||||||
// Check for valid IP addresses
|
// gethostbyname must check for literals, so can call it directly
|
||||||
if (host && ipv4_is_valid(host)) {
|
|
||||||
_addr.version = NSAPI_IPv4;
|
|
||||||
ipv4_from_address(_addr.bytes, host);
|
|
||||||
_port = port;
|
|
||||||
} else if (host && ipv6_is_valid(host)) {
|
|
||||||
_addr.version = NSAPI_IPv6;
|
|
||||||
ipv6_from_address(_addr.bytes, host);
|
|
||||||
_port = port;
|
|
||||||
} else {
|
|
||||||
// DNS lookup
|
|
||||||
int err = iface->gethostbyname(host, this);
|
int err = iface->gethostbyname(host, this);
|
||||||
_port = port;
|
_port = port;
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -307,4 +297,3 @@ void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16
|
||||||
_port = 0;
|
_port = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define CLASS_IN 1
|
||||||
|
|
||||||
|
#define RR_A 1
|
||||||
|
#define RR_AAAA 28
|
||||||
|
|
||||||
// DNS options
|
// DNS options
|
||||||
#define DNS_BUFFER_SIZE 512
|
#define DNS_BUFFER_SIZE 512
|
||||||
|
@ -34,7 +38,6 @@ nsapi_addr_t dns_servers[DNS_SERVERS_SIZE] = {
|
||||||
{NSAPI_IPv4, {208, 67, 222, 222}},
|
{NSAPI_IPv4, {208, 67, 222, 222}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// DNS server configuration
|
// DNS server configuration
|
||||||
extern "C" int nsapi_dns_add_server(nsapi_addr_t addr)
|
extern "C" int nsapi_dns_add_server(nsapi_addr_t addr)
|
||||||
{
|
{
|
||||||
|
@ -100,11 +103,11 @@ static void dns_append_question(uint8_t **p, const char *host, nsapi_version_t v
|
||||||
|
|
||||||
// fill out question footer
|
// fill out question footer
|
||||||
if (version == NSAPI_IPv4) {
|
if (version == NSAPI_IPv4) {
|
||||||
dns_append_word(p, 1); // qtype = ipv4
|
dns_append_word(p, RR_A); // qtype = ipv4
|
||||||
} else {
|
} else {
|
||||||
dns_append_word(p, 28); // qtype = ipv6
|
dns_append_word(p, RR_AAAA); // qtype = ipv6
|
||||||
}
|
}
|
||||||
dns_append_word(p, 1); // qclass = 1
|
dns_append_word(p, CLASS_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dns_scan_response(const uint8_t **p, nsapi_addr_t *addr, unsigned addr_count)
|
static int dns_scan_response(const uint8_t **p, nsapi_addr_t *addr, unsigned addr_count)
|
||||||
|
@ -162,7 +165,7 @@ static int dns_scan_response(const uint8_t **p, nsapi_addr_t *addr, unsigned add
|
||||||
*p += 4; // ttl
|
*p += 4; // ttl
|
||||||
uint16_t rdlength = dns_scan_word(p); // rdlength
|
uint16_t rdlength = dns_scan_word(p); // rdlength
|
||||||
|
|
||||||
if (rtype == 1 && rclass == 1 && rdlength == NSAPI_IPv4_BYTES) {
|
if (rtype == RR_A && rclass == CLASS_IN && rdlength == NSAPI_IPv4_BYTES) {
|
||||||
// accept A record
|
// accept A record
|
||||||
addr->version = NSAPI_IPv4;
|
addr->version = NSAPI_IPv4;
|
||||||
for (int i = 0; i < NSAPI_IPv4_BYTES; i++) {
|
for (int i = 0; i < NSAPI_IPv4_BYTES; i++) {
|
||||||
|
@ -171,7 +174,7 @@ static int dns_scan_response(const uint8_t **p, nsapi_addr_t *addr, unsigned add
|
||||||
|
|
||||||
addr += 1;
|
addr += 1;
|
||||||
count += 1;
|
count += 1;
|
||||||
} else if (rtype == 28 && rclass == 1 && rdlength == NSAPI_IPv6_BYTES) {
|
} else if (rtype == RR_AAAA && rclass == CLASS_IN && rdlength == NSAPI_IPv6_BYTES) {
|
||||||
// accept AAAA record
|
// accept AAAA record
|
||||||
addr->version = NSAPI_IPv6;
|
addr->version = NSAPI_IPv6;
|
||||||
for (int i = 0; i < NSAPI_IPv6_BYTES; i++) {
|
for (int i = 0; i < NSAPI_IPv6_BYTES; i++) {
|
||||||
|
@ -219,8 +222,8 @@ static int nsapi_dns_query_multiple(NetworkStack *stack, const char *host,
|
||||||
// check against each dns server
|
// check against each dns server
|
||||||
for (unsigned i = 0; i < DNS_SERVERS_SIZE; i++) {
|
for (unsigned i = 0; i < DNS_SERVERS_SIZE; i++) {
|
||||||
// send the question
|
// send the question
|
||||||
uint8_t *p = packet;
|
uint8_t *question = packet;
|
||||||
dns_append_question(&p, host, version);
|
dns_append_question(&question, host, version);
|
||||||
|
|
||||||
err = socket.sendto(SocketAddress(dns_servers[i], 53), packet, DNS_BUFFER_SIZE);
|
err = socket.sendto(SocketAddress(dns_servers[i], 53), packet, DNS_BUFFER_SIZE);
|
||||||
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
||||||
|
@ -239,13 +242,10 @@ static int nsapi_dns_query_multiple(NetworkStack *stack, const char *host,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = packet;
|
const uint8_t *response = packet;
|
||||||
int found = dns_scan_response((const uint8_t **)&p, addr, addr_count);
|
dns_scan_response(&response, addr, addr_count);
|
||||||
if (found) {
|
|
||||||
result = found;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// clean up packet
|
// clean up packet
|
||||||
free(packet);
|
free(packet);
|
||||||
|
|
Loading…
Reference in New Issue