diff --git a/libc/netdb/Make.defs b/libc/netdb/Make.defs index dbddf836d5..b9347eb0fc 100644 --- a/libc/netdb/Make.defs +++ b/libc/netdb/Make.defs @@ -48,7 +48,7 @@ endif # Add DNS lookup support ifeq ($(CONFIG_NETDB_DNSCLIENT),y) -CSRCS += lib_dnsclient.c +CSRCS += lib_dnsclient.c lib_getdnsaddr.c endif # Add the net directory to the build diff --git a/libc/netdb/lib_dns.h b/libc/netdb/lib_dns.h index dee8985f99..e3e5d3bae5 100644 --- a/libc/netdb/lib_dns.h +++ b/libc/netdb/lib_dns.h @@ -57,11 +57,11 @@ /* DNS client configuration **************************************************/ #ifndef CONFIG_NETDB_DNSCLIENT_ENTRIES -# define RESOLV_ENTRIES 4 -#else -# define RESOLV_ENTRIES CONFIG_NETDB_DNSCLIENT_ENTRIES +# define CONFIG_NETDB_DNSCLIENT_ENTRIES 4 #endif +#define RESOLV_ENTRIES CONFIG_NETDB_DNSCLIENT_ENTRIES + #ifndef CONFIG_NETDB_DNSCLIENT_MAXRESPONSE # define CONFIG_NETDB_DNSCLIENT_MAXRESPONSE 96 #endif diff --git a/libc/netdb/lib_getdnsaddr.c b/libc/netdb/lib_getdnsaddr.c new file mode 100644 index 0000000000..a6e6c4335a --- /dev/null +++ b/libc/netdb/lib_getdnsaddr.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * libc/netdb/lib_dnsgetaddr.c + * + * Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include + +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NETDB_DNSCLIENT) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_getaddr + * + * Description: + * Get the DNS server IPv4 address + * + * Parameters: + * ipaddr The location to return the IPv4 address + * + * Return: + * Zero (OK) is returned on success; A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +int dns_getaddr(FAR struct in_addr *inaddr) +{ + struct sockaddr_in addr; + socklen_t addrlen; + int ret = -EINVAL; + + if (inaddr) + { + addrlen = sizeof(struct sockaddr_in); + ret = dns_getserver((FAR struct sockaddr *)&addr, &addrlen); + if (ret >= 0) + { + /* Sanity check */ + + DEBUGASSERT(addr.sin_family == AF_INET && + addrlen == sizeof(struct sockaddr_in)); + memcpy(inaddr, &addr.sin_addr, sizeof(struct in_addr)); + } + } + + return ret; +} + +#endif /* CONFIG_NET_IPv4 && CONFIG_NETDB_DNSCLIENT */ diff --git a/net/procfs/netdev_statistics.c b/net/procfs/netdev_statistics.c index b81741a409..61bc0f3573 100644 --- a/net/procfs/netdev_statistics.c +++ b/net/procfs/netdev_statistics.c @@ -47,8 +47,10 @@ #include #include +#include #include "netdev/netdev.h" +#include "utils/utils.h" #include "procfs/procfs.h" #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \ @@ -246,7 +248,7 @@ static int netprocfs_ipaddresses(FAR struct netprocfs_file_s *netfile) "Mask:%s\n", inet_ntoa(addr)); #if defined(CONFIG_NSH_DHCPC) || defined(CONFIG_NSH_DNS) - netlib_get_ipv4dnsaddr(&addr); + dns_getaddr(&addr); len += snprintf(&netfile->line[len], NET_LINELEN - len, "\tDNSaddr:%s\n", inet_ntoa(addr)); #endif @@ -255,7 +257,7 @@ static int netprocfs_ipaddresses(FAR struct netprocfs_file_s *netfile) #ifdef CONFIG_NET_IPv6 /* Convert the 128 network mask to a human friendly prefix length */ - preflen = netlib_ipv6netmask2prefix(dev->d_ipv6netmask); + preflen = net_ipv6_mask2pref(dev->d_ipv6netmask); /* Show the assigned IPv6 address */ diff --git a/net/utils/Make.defs b/net/utils/Make.defs index 6be4afdfc1..5abcb9226c 100644 --- a/net/utils/Make.defs +++ b/net/utils/Make.defs @@ -41,7 +41,7 @@ NET_CSRCS += net_chksum.c # IPv6 utilities ifeq ($(CONFIG_NET_IPv6),y) -NET_CSRCS += net_ipv6_maskcmp.c net_ipv6_pref2mask.c +NET_CSRCS += net_ipv6_maskcmp.c net_ipv6_mask2pref.c net_ipv6_pref2mask.c endif # Non-interrupt level support required? diff --git a/net/utils/net_ipv6_mask2pref.c b/net/utils/net_ipv6_mask2pref.c new file mode 100644 index 0000000000..dd9e00b6d8 --- /dev/null +++ b/net/utils/net_ipv6_mask2pref.c @@ -0,0 +1,188 @@ +/**************************************************************************** + * net/utils/net_ipv6_mask2pref.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "utils/utils.h" + +#ifdef CONFIG_NET_IPv6 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_nibblemap[16] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0: No bits, 1-7: Should not happen */ + 1, 1, 1, 1, /* 8: 1 bit, 9-b: Should not happen */ + 2, 2, 3, 4 /* c: 2 bits, d: Should not happen, e: 3 bits, f: 4 bits */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: net_msbits4 + * + * Description: + * Count the number of leading '1' bits in an 4-bit nibble + * + ****************************************************************************/ + +static inline uint8_t net_msbits4(uint8_t nibble) +{ + /* Return the number of leading zeroes: 0-4) */ + + return g_nibblemap[nibble]; +} + +/**************************************************************************** + * Name: net_msbits8 + * + * Description: + * Count the number of leading '1' bits in an 8-bit byte + * + ****************************************************************************/ + +static uint8_t net_msbits8(uint8_t byval) +{ + uint8_t ones; + + /* Check the MS nibble */ + + ones = net_msbits4(byval >> 4); + if (ones == 4) + { + /* All ones, try the LS nibble */ + + ones += net_msbits4(byval & 0x0f); + } + + /* Return the number of leading ones (0-8) */ + + return ones; +} + +/**************************************************************************** + * Name: net_msbits16 + * + * Description: + * Count the number of leading '1' bits in a 16-bit half-workd + * + ****************************************************************************/ + +static inline uint8_t net_msbits16(uint16_t hword) +{ + uint8_t ones; + + /* Look at the MS byte of the 16-bit value */ + + ones = net_msbits8((uint8_t)(hword >> 8)); + if (ones == 8) + { + /* All '1's, try the LS byte */ + + ones += net_msbits8((uint8_t)(hword & 0xff)); + } + + /* Return the number of leading ones (0-15) */ + + return ones; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: net_ipv6_mask2pref + * + * Description: + * Convert a 128-bit netmask to a prefix length. The Nuttx IPv6 + * networking uses 128-bit network masks internally. This function + * converts the IPv6 netmask to a prefix length. + * + * The prefix length is the number of MS '1' bits on in the netmask. + * This, of course, assumes that all MS bits are '1' and all LS bits are + * '0' with no intermixed 1's and 0's. This function searches from the MS + * bit until the first '0' is found (this does not necessary mean that + * there might not be additional '1' bits following the firs '0', but that + * will be a malformed netmask. + * + * Parameters: + * mask Points to an IPv6 netmask in the form of uint16_t[8] + * + * Return: + * The prefix length, range 0-128 on success; This function will not + * fail. + * + ****************************************************************************/ + +uint8_t net_ipv6_mask2pref(FAR const uint16_t *mask) +{ + uint8_t preflen; + int i; + + /* Count the leading all '1' 16-bit groups */ + + for (i = 0, preflen = 0; i < 8 && mask[i] == 0xffff; i++, preflen += 16); + + /* Now i either, (1) indexes past the end of the mask, or (2) is the index + * to the first half-word that is not equal to 0xffff. + */ + + if (i < 8) + { + preflen += net_msbits16(ntohs(mask[i])); + } + + /* Return the prefix length */ + + return preflen; +} + +#endif /* CONFIG_NET_IPv6 */ diff --git a/net/utils/utils.h b/net/utils/utils.h index d3644d446a..90592b2f7a 100644 --- a/net/utils/utils.h +++ b/net/utils/utils.h @@ -151,6 +151,34 @@ unsigned int net_dsec2tick(int dsec); unsigned int net_timeval2dsec(FAR struct timeval *tv, enum tv2ds_remainder_e remainder); +/**************************************************************************** + * Name: net_ipv6_mask2pref + * + * Description: + * Convert a 128-bit netmask to a prefix length. The Nuttx IPv6 + * networking uses 128-bit network masks internally. This function + * converts the IPv6 netmask to a prefix length. + * + * The prefix length is the number of MS '1' bits on in the netmask. + * This, of course, assumes that all MS bits are '1' and all LS bits are + * '0' with no intermixed 1's and 0's. This function searches from the MS + * bit until the first '0' is found (this does not necessary mean that + * there might not be additional '1' bits following the firs '0', but that + * will be a malformed netmask. + * + * Parameters: + * mask Points to an IPv6 netmask in the form of uint16_t[8] + * + * Return: + * The prefix length, range 0-128 on success; This function will not + * fail. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +uint8_t net_ipv6_mask2pref(FAR const uint16_t *mask); +#endif + /**************************************************************************** * Function: net_ipv6_pref2mask *