Move the DNS server from apps/netutils/dnsclient to nuttx/libc/netdb. Move netdb functions from libc/net to libc/netdb. Fix up naming to reflect the repartitioning

This commit is contained in:
Gregory Nutt 2015-07-10 12:11:40 -06:00
parent 9c9b6162d8
commit 4102470bdd
20 changed files with 1200 additions and 35 deletions

@ -1 +1 @@
Subproject commit 8e27cf333e78b19ade6dff857e865cdf65056253
Subproject commit 0e83a96479ca75165308d5d8d84510e0d2f3b7ec

View File

@ -263,7 +263,7 @@ EXTERN int h_errno;
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_LIBC_NETDB
#if 0 /* None of these are yet supported */
void endhostent(void);
@ -311,7 +311,7 @@ int gethostbyaddr_r(FAR const void *addr, socklen_t len, int type,
int gethostbyname_r(FAR const char *name, FAR struct hostent *host,
FAR char *buf, size_t buflen, int *h_errnop);
#endif /* CONFIG_LIB_NETDB */
#endif /* CONFIG_LIBC_NETDB */
#undef EXTERN
#ifdef __cplusplus

View File

@ -0,0 +1,216 @@
/****************************************************************************
* include/nuttx/net/dnsclient.h
* DNS resolver code header file.
*
* Copyright (C) 2007-2009, 2011-2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Inspired by/based on uIP logic by Adam Dunkels:
*
* Copyright (c) 2002-2003, Adam Dunkels. All rights reserved.
* Author Adam Dunkels <adam@dunkels.com>
*
* 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_NET_DNSCLIENT_H
#define __INCLUDE_NUTTX_NET_DNSCLIENT_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <netinet/in.h>
#include <nuttx/net/netconfig.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* If both IPv4 and IPv6 are enabled, the DNS client can support only one or
* the other.
*/
#if !defined(CONFIG_NETDB_DNSCLIENT_IPv4) && \
!defined(CONFIG_NETDB_DNSCLIENT_IPv6)
# ifdef CONFIG_NET_IPv6
# define CONFIG_NETDB_DNSCLIENT_IPv6 1
# else
# define CONFIG_NETDB_DNSCLIENT_IPv4 1
# endif
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: dns_bind_sock
*
* Description:
* Initialize the DNS resolver using the caller provided socket.
*
****************************************************************************/
int dns_bind_sock(FAR int *sockfd);
/****************************************************************************
* Name: dns_bind
*
* Description:
* Initialize the DNS resolver using an internal, share-able socket.
*
****************************************************************************/
int dns_bind(void);
/****************************************************************************
* Name: dns_free_sock
*
* Description:
* Release the DNS resolver by closing the socket.
*
****************************************************************************/
int dns_free_sock(FAR int *sockfd);
/****************************************************************************
* Name: dns_query_sock
*
* Description:
* Using the DNS resolver socket (sockfd), look up the the 'hostname', and
* return its IP address in 'ipaddr'
*
* Returned Value:
* Returns zero (OK) if the query was successful.
*
****************************************************************************/
int dns_query_sock(int sockfd, FAR const char *hostname, FAR in_addr_t *ipaddr);
/****************************************************************************
* Name: dns_query
*
* Description:
* Using the internal DNS resolver socket, look up the the 'hostname', and
* return its IP address in 'ipaddr'
*
* Returned Value:
* Returns zero (OK) if the query was successful.
*
****************************************************************************/
int dns_query(FAR const char *hostname, FAR in_addr_t *ipaddr);
/****************************************************************************
* Name: dns_setserver
*
* Description:
* Configure which DNS server to use for queries
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
void dns_setserver(FAR const struct in6_addr *dnsserver);
#else
void dns_setserver(FAR const struct in_addr *dnsserver);
#endif
/****************************************************************************
* Name: dns_getserver
*
* Description:
* Obtain the currently configured DNS server.
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
void dns_getserver(FAR struct in6_addr *dnsserver);
#else
void dns_getserver(FAR struct in_addr *dnsserver);
#endif
/****************************************************************************
* Name: dns_whois_socket
*
* Description:
* Get the binding for 'name' using the DNS server accessed via 'sockfd'
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
int dns_whois_socket(int sockfd, FAR const char *name,
FAR struct sockaddr_in6 *addr);
#else
int dns_whois_socket(int sockfd, FAR const char *name,
FAR struct sockaddr_in *addr);
#endif
/****************************************************************************
* Name: dns_whois
*
* Description:
* Get the binding for 'name' using the DNS server accessed via the DNS
* resolvers internal socket.
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
int dns_whois(FAR const char *name, FAR struct sockaddr_in6 *addr);
#else
int dns_whois(FAR const char *name, FAR struct sockaddr_in *addr);
#endif
/****************************************************************************
* Name: dns_gethostip
*
* Descriptions:
* Combines the operations of dns_bind_sock(), dns_query_sock(), and
* dns_free_sock() to obtain the the IP address ('ipaddr') associated with
* the 'hostname' in one operation.
*
****************************************************************************/
int dns_gethostip(FAR const char *hostname, FAR in_addr_t *ipaddr);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_NET_DNSCLIENT_H */

View File

@ -504,12 +504,17 @@ config ARCH_BZERO
endif # ARCH_OPTIMIZED_FUNCTIONS
menuconfig LIB_NETDB
bool "Network database support"
config LIBC_NETDB
bool
default n
menuconfig NETDB_HOSTFILE
bool "Network host file support"
default n
depends on FS_READABLE
select LIBC_NETDB
if LIB_NETDB
if NETDB_HOSTFILE
config NETDB_HOSTCONF_PATH
string "Path to host configuration file"
@ -523,7 +528,49 @@ config NETDB_BUFSIZE
int "gethostname() buffer size"
default 128
endif # LIB_NETDB
endif # NETDB_HOSTFILE
config NETDB_DNSCLIENT
bool "DNS Name resolution"
default n
depends on NET && NET_UDP
select LIBC_NETDB
---help---
Enable support for the name resolution.
if NETDB_DNSCLIENT
choice
prompt "Internet Protocol"
default NETDB_DNSCLIENT_IPv4 if NET_IPv4
default NETDB_DNSCLIENT_IPv6 if NET_IPv6 && !NET_IPv4
config NETDB_DNSCLIENT_IPv4
bool "IPv4"
depends on NET_IPv4
config NETDB_DNSCLIENT_IPv6
bool "IPv6"
depends on NET_IPv6
endchoice # Internet Protocol
config NETDB_DNSCLIENT_ENTRIES
int "Number of DNS resolver entries"
default 8
---help---
Number of DNS resolver entries. Default: 8
config NETDB_DNSCLIENT_MAXRESPONSE
int "Max response size"
default 96
---help---
This setting determines the maximum size of response message that
can be received by the DNS resolver. The default is 96 but may
need to be larger on enterprise networks (perhaps 176).
endif # NETDB_DNSCLIENT
comment "Non-standard Library Support"

View File

@ -74,6 +74,7 @@ include signal/Make.defs
include math/Make.defs
include fixedmath/Make.defs
include net/Make.defs
include netdb/Make.defs
include time/Make.defs
include libgen/Make.defs
include dirent/Make.defs

View File

@ -218,7 +218,7 @@ float lib_sqrtapprox(float x);
/* Defined in lib_parsehostfile.c */
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host,
FAR char *buf, size_t buflen);
#endif

View File

@ -46,7 +46,7 @@ endif
# netdb support
ifeq ($(CONFIG_LIB_NETDB),y)
ifeq ($(CONFIG_NETDB_HOSTFILE),y)
CSRCS += lib_netdb.c lib_gethostbyname.c lib_gethostbynamer.c
CSRCS += lib_gethostbyaddr.c lib_gethostbyaddrr.c lib_parsehostfile.c
endif

View File

@ -61,7 +61,7 @@
* IPv6 addresses, regardless of networking support.
*/
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
# undef CONFIG_NET_IPv4
# undef CONFIG_NET_IPv6
# define CONFIG_NET_IPv4 1

View File

@ -63,7 +63,7 @@
* IPv6 addresses, regardless of networking support.
*/
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
# undef CONFIG_NET_IPv4
# undef CONFIG_NET_IPv6
# define CONFIG_NET_IPv4 1

58
libc/netdb/Make.defs Normal file
View File

@ -0,0 +1,58 @@
############################################################################
# libc/netdb/Make.defs
#
# Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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.
#
############################################################################
ifeq ($(CONFIG_LIBC_NETDB),y)
# Add the netdb C files to the build
# Add host file support
ifeq ($(CONFIG_NETDB_HOSTFILE),y)
CSRCS += lib_netdb.c lib_gethostbyname.c lib_gethostbynamer.c
CSRCS += lib_gethostbyaddr.c lib_gethostbyaddrr.c lib_parsehostfile.c
endif
# Add DNS support
ifeq ($(CONFIG_NETDB_DNSCLIENT),y)
CSRCS = dns_resolver.c dns_socket.c dns_gethostip.c
endif
# Add the net directory to the build
DEPPATH += --dep-path netdb
VPATH += :netdb
endif

View File

@ -0,0 +1,91 @@
/****************************************************************************
* libc/netdb/dns_gethostip.c
*
* Copyright (C) 2007, 2009, 2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Based heavily on portions of uIP:
*
* Author: Adam Dunkels <adam@dunkels.com>
* Copyright (c) 2002-2003, Adam Dunkels.
* All rights reserved.
*
* 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <nuttx/config.h>
#include <nuttx/net/dnsclient.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: dns_gethostip
*
* Descriptions:
* Combines the operations of dns_bind_sock(), dns_query_sock(), and
* dns_free_sock() to obtain the the IP address ('ipaddr') associated with
* the 'hostname' in one operation.
*
****************************************************************************/
int dns_gethostip(FAR const char *hostname, FAR in_addr_t *ipaddr)
{
int sockfd = -1;
int ret=ERROR;
dns_bind_sock(&sockfd);
if (sockfd >= 0)
{
ret = dns_query_sock(sockfd, hostname, ipaddr);
dns_free_sock(&sockfd);
}
return ret;
}

123
libc/netdb/dns_resolver.c Normal file
View File

@ -0,0 +1,123 @@
/****************************************************************************
* libc/netdb/dns_resolver.c
* DNS host name to IP address resolver.
*
* The uIP DNS resolver functions are used to lookup a hostname and
* map it to a numerical IP address. It maintains a list of resolved
* hostnames that can be queried. New hostnames can be resolved using the
* dns_whois() function.
*
* Copyright (C) 2007, 2009, 2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Based heavily on portions of uIP:
*
* Author: Adam Dunkels <adam@dunkels.com>
* Copyright (c) 2002-2003, Adam Dunkels.
* All rights reserved.
*
* 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <nuttx/config.h>
#include <netinet/in.h>
#include <nuttx/net/dnsclient.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static int g_sockfd = -1;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: dns_bind
*
* Description:
* Initialize the DNS resolver using an internal, share-able socket.
*
****************************************************************************/
int dns_bind(void)
{
return dns_bind_sock(&g_sockfd);
}
/****************************************************************************
* Name: dns_query
*
* Description:
* Using the internal DNS resolver socket, look up the the 'hostname', and
* return its IP address in 'ipaddr'
*
* Returned Value:
* Returns zero (OK) if the query was successful.
*
****************************************************************************/
int dns_query(FAR const char *hostname, FAR in_addr_t *ipaddr)
{
return dns_query_sock(g_sockfd, hostname, ipaddr);
}
/****************************************************************************
* Name: dns_whois
*
* Description:
* Get the binding for 'name' using the DNS server accessed via the DNS
* resolvers internal socket.
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
int dns_whois(FAR const char *name, FAR struct sockaddr_in6 *addr)
#else
int dns_whois(FAR const char *name, FAR struct sockaddr_in *addr)
#endif
{
return dns_whois_socket(g_sockfd, name, addr);
}

629
libc/netdb/dns_socket.c Normal file
View File

@ -0,0 +1,629 @@
/****************************************************************************
* libc/netdb/dns_socket.c
* DNS host name to IP address resolver.
*
* The uIP DNS resolver functions are used to lookup a hostname and
* map it to a numerical IP address. It maintains a list of resolved
* hostnames that can be queried. New hostnames can be resolved using the
* dns_whois() function.
*
* Copyright (C) 2007, 2009, 2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Based heavily on portions of uIP:
*
* Author: Adam Dunkels <adam@dunkels.com>
* Copyright (c) 2002-2003, Adam Dunkels.
* All rights reserved.
*
* 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <nuttx/config.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <debug.h>
#include <assert.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/net/dnsclient.h>
#include <apps/netutils/netlib.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_NETDB_DNSCLIENT_ENTRIES
# define RESOLV_ENTRIES 4
#else /* CONFIG_NETDB_DNSCLIENT_ENTRIES */
# define RESOLV_ENTRIES CONFIG_NETDB_DNSCLIENT_ENTRIES
#endif /* CONFIG_NETDB_DNSCLIENT_ENTRIES */
#ifndef NULL
# define NULL (void *)0
#endif /* NULL */
/* The maximum number of retries when asking for a name */
#define MAX_RETRIES 8
#define DNS_FLAG1_RESPONSE 0x80
#define DNS_FLAG1_OPCODE_STATUS 0x10
#define DNS_FLAG1_OPCODE_INVERSE 0x08
#define DNS_FLAG1_OPCODE_STANDARD 0x00
#define DNS_FLAG1_AUTHORATIVE 0x04
#define DNS_FLAG1_TRUNC 0x02
#define DNS_FLAG1_RD 0x01
#define DNS_FLAG2_RA 0x80
#define DNS_FLAG2_ERR_MASK 0x0f
#define DNS_FLAG2_ERR_NONE 0x00
#define DNS_FLAG2_ERR_NAME 0x03
#define SEND_BUFFER_SIZE 64
#ifdef CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
# define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE
#else
# define RECV_BUFFER_SIZE 96
#endif
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
# define ADDRLEN sizeof(struct sockaddr_in6)
#else
# define ADDRLEN sizeof(struct sockaddr_in)
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/* The DNS message header */
struct dns_hdr
{
uint16_t id;
uint8_t flags1;
uint8_t flags2;
uint16_t numquestions;
uint16_t numanswers;
uint16_t numauthrr;
uint16_t numextrarr;
};
/* The DNS answer message structure */
struct dns_answer
{
/* DNS answer record starts with either a domain name or a pointer
* to a name already present somewhere in the packet.
*/
uint16_t type;
uint16_t class;
uint16_t ttl[2];
uint16_t len;
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
struct in6_addr ipaddr;
#else
struct in_addr ipaddr;
#endif
};
struct namemap
{
uint8_t state;
uint8_t tmr;
uint8_t retries;
uint8_t seqno;
uint8_t err;
char name[32];
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
struct in6_addr ipaddr;
#else
struct in_addr ipaddr;
#endif
};
/****************************************************************************
* Private Data
****************************************************************************/
static uint8_t g_seqno;
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
static struct sockaddr_in6 g_dnsserver;
#else
static struct sockaddr_in g_dnsserver;
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: dns_parse_name
*
* Description:
* Walk through a compact encoded DNS name and return the end of it.
*
****************************************************************************/
static FAR unsigned char *dns_parse_name(FAR unsigned char *query)
{
unsigned char n;
do
{
n = *query++;
while (n > 0)
{
++query;
--n;
}
}
while (*query != 0);
return query + 1;
}
/****************************************************************************
* Name: dns_send_query
*
* Description:
* Runs through the list of names to see if there are any that have
* not yet been queried and, if so, sends out a query.
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
static int dns_send_query(int sockfd, FAR const char *name,
FAR struct sockaddr_in6 *addr)
#else
static int dns_send_query(int sockfd, FAR const char *name,
FAR struct sockaddr_in *addr)
#endif
{
register FAR struct dns_hdr *hdr;
FAR char *query;
FAR char *nptr;
FAR const char *nameptr;
uint8_t seqno = g_seqno++;
static unsigned char endquery[] = {0, 0, 1, 0, 1};
char buffer[SEND_BUFFER_SIZE];
int n;
hdr = (FAR struct dns_hdr*)buffer;
memset(hdr, 0, sizeof(struct dns_hdr));
hdr->id = htons(seqno);
hdr->flags1 = DNS_FLAG1_RD;
hdr->numquestions = HTONS(1);
query = buffer + 12;
/* Convert hostname into suitable query format. */
nameptr = name - 1;
do
{
nameptr++;
nptr = query++;
for (n = 0; *nameptr != '.' && *nameptr != 0; nameptr++)
{
*query++ = *nameptr;
n++;
}
*nptr = n;
}
while (*nameptr != 0);
memcpy(query, endquery, 5);
return sendto(sockfd, buffer, query + 5 - buffer,
0, (struct sockaddr*)addr, ADDRLEN);
}
/****************************************************************************
* Name: dns_recv_response
*
* Description:
* Called when new UDP data arrives
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
# error "Not implemented"
#else
static int dns_recv_response(int sockfd, FAR struct sockaddr_in *addr)
#endif
{
FAR unsigned char *nameptr;
char buffer[RECV_BUFFER_SIZE];
FAR struct dns_answer *ans;
FAR struct dns_hdr *hdr;
#if 0 /* Not used */
uint8_t nquestions;
#endif
uint8_t nanswers;
int ret;
/* Receive the response */
ret = recv(sockfd, buffer, RECV_BUFFER_SIZE, 0);
if (ret < 0)
{
return ret;
}
hdr = (FAR struct dns_hdr *)buffer;
ndbg("ID %d\n", htons(hdr->id));
ndbg("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
ndbg("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
ndbg("Num questions %d, answers %d, authrr %d, extrarr %d\n",
htons(hdr->numquestions), htons(hdr->numanswers),
htons(hdr->numauthrr), htons(hdr->numextrarr));
/* Check for error. If so, call callback to inform */
if ((hdr->flags2 & DNS_FLAG2_ERR_MASK) != 0)
{
return ERROR;
}
/* We only care about the question(s) and the answers. The authrr
* and the extrarr are simply discarded.
*/
#if 0 /* Not used */
nquestions = htons(hdr->numquestions);
#endif
nanswers = htons(hdr->numanswers);
/* Skip the name in the question. TODO: This should really be
* checked against the name in the question, to be sure that they
* match.
*/
#ifdef CONFIG_DEBUG_NET
{
int d = 64;
nameptr = dns_parse_name((unsigned char *)buffer + 12) + 4;
for (;;)
{
ndbg("%02X %02X %02X %02X %02X %02X %02X %02X \n",
nameptr[0],nameptr[1],nameptr[2],nameptr[3],
nameptr[4],nameptr[5],nameptr[6],nameptr[7]);
nameptr += 8;
d -= 8;
if (d < 0)
{
break;
}
}
}
#endif
nameptr = dns_parse_name((unsigned char *)buffer + 12) + 4;
for (; nanswers > 0; nanswers--)
{
/* The first byte in the answer resource record determines if it
* is a compressed record or a normal one.
*/
if (*nameptr & 0xc0)
{
/* Compressed name. */
nameptr += 2;
ndbg("Compressed answer\n");
}
else
{
/* Not compressed name. */
nameptr = dns_parse_name(nameptr);
}
ans = (struct dns_answer *)nameptr;
ndbg("Answer: type %x, class %x, ttl %x, length %x \n", /* 0x%08X\n", */
htons(ans->type), htons(ans->class),
(htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]),
htons(ans->len) /* , ans->ipaddr.s_addr */);
/* Check for IP address type and Internet class. Others are discarded. */
if (ans->type == HTONS(1) &&
ans->class == HTONS(1) &&
ans->len == HTONS(4))
{
ans->ipaddr.s_addr = *(FAR uint32_t *)(nameptr + 10);
ndbg("IP address %d.%d.%d.%d\n",
(ans->ipaddr.s_addr ) & 0xff,
(ans->ipaddr.s_addr >> 8 ) & 0xff,
(ans->ipaddr.s_addr >> 16 ) & 0xff,
(ans->ipaddr.s_addr >> 24 ) & 0xff);
/* TODO: we should really check that this IP address is the one
* we want.
*/
addr->sin_addr.s_addr = ans->ipaddr.s_addr;
return OK;
}
else
{
nameptr = nameptr + 10 + htons(ans->len);
}
}
return ERROR;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: dns_bind_sock
*
* Description:
* Initialize the DNS resolver using the caller provided socket.
*
****************************************************************************/
int dns_bind_sock(FAR int *sockfd)
{
struct timeval tv;
int ret;
/* If the socket is already open, then close it now */
if (*sockfd >= 0)
{
dns_free_sock(sockfd);
}
/* Create a new socket */
*sockfd = socket(PF_INET, SOCK_DGRAM, 0);
if (*sockfd < 0)
{
ndbg("ERROR: socket() failed: %d\n", errno);
return ERROR;
}
/* Set up a receive timeout */
tv.tv_sec = 30;
tv.tv_usec = 0;
ret = setsockopt(*sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(struct timeval));
if (ret < 0)
{
ndbg("ERROR: setsockopt() failed: %d\n", errno);
close(*sockfd);
*sockfd = -1;
return ERROR;
}
return OK;
}
/****************************************************************************
* Name: dns_free_sock
*
* Description:
* Release the DNS resolver by closing the socket.
*
****************************************************************************/
int dns_free_sock(FAR int *sockfd)
{
if (*sockfd >= 0)
{
close(*sockfd);
*sockfd = -1;
}
return OK;
}
/****************************************************************************
* Name: dns_query_sock
*
* Description:
* Using the DNS resolver socket (sockfd), look up the the 'hostname', and
* return its IP address in 'ipaddr'
*
* Returned Value:
* Returns zero (OK) if the query was successful.
*
****************************************************************************/
int dns_query_sock(int sockfd, FAR const char *hostname, FAR in_addr_t *ipaddr)
{
#ifdef CONFIG_HAVE_GETHOSTBYNAME
FAR struct hostent *he;
nvdbg("Getting address of %s\n", hostname);
he = gethostbyname(hostname);
if (!he)
{
ndbg("gethostbyname failed: %d\n", h_errno);
return ERROR;
}
nvdbg("Using IP address %04x%04x\n",
(uint16_t)he->h_addr[1], (uint16_t)he->h_addr[0]);
memcpy(ipaddr, he->h_addr, sizeof(in_addr_t));
return OK;
#else
# ifdef CONFIG_NETDB_DNSCLIENT_IPv6
struct sockaddr_in6 addr;
# else
struct sockaddr_in addr;
# endif
/* First check if the host is an IP address. */
if (!netlib_ipaddrconv(hostname, (uint8_t*)ipaddr))
{
/* 'host' does not point to a valid address string. Try to resolve
* the host name to an IP address.
*/
if (dns_whois_socket(sockfd, hostname, &addr) < 0)
{
/* Needs to set the errno here */
return ERROR;
}
/* Save the host address -- Needs fixed for IPv6 */
*ipaddr = addr.sin_addr.s_addr;
}
return OK;
#endif
}
/****************************************************************************
* Name: dns_setserver
*
* Description:
* Configure which DNS server to use for queries
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
void dns_setserver(FAR const struct in6_addr *dnsserver)
#else
void dns_setserver(FAR const struct in_addr *dnsserver)
#endif
{
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
g_dnsserver.sin6_family = AF_INET6;
g_dnsserver.sin6_port = HTONS(53);
memcpy(&g_dnsserver.sin6_addr, dnsserver, ADDRLEN);
#else
g_dnsserver.sin_family = AF_INET;
g_dnsserver.sin_port = HTONS(53);
g_dnsserver.sin_addr.s_addr = dnsserver->s_addr;
#endif
}
/****************************************************************************
* Name: dns_getserver
*
* Description:
* Obtain the currently configured DNS server.
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
void dns_getserver(FAR struct in6_addr *dnsserver)
#else
void dns_getserver(FAR struct in_addr *dnsserver)
#endif
{
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
memcpy(dnsserver, &g_dnsserver.sin6_addr, ADDRLEN);
#else
dnsserver->s_addr = g_dnsserver.sin_addr.s_addr;
#endif
}
/****************************************************************************
* Name: dns_whois_socket
*
* Description:
* Get the binding for 'name' using the DNS server accessed via 'sockfd'
*
****************************************************************************/
#ifdef CONFIG_NETDB_DNSCLIENT_IPv6
int dns_whois_socket(int sockfd, FAR const char *name,
FAR struct sockaddr_in6 *addr)
#else
int dns_whois_socket(int sockfd, FAR const char *name,
FAR struct sockaddr_in *addr)
#endif
{
int retries;
int ret;
/* Loop while receive timeout errors occur and there are remaining retries */
for (retries = 0; retries < 3; retries++)
{
ret = dns_send_query(sockfd, name, &g_dnsserver);
if (ret < 0)
{
return ERROR;
}
ret = dns_recv_response(sockfd, addr);
if (ret >= 0)
{
/* Response received successfully */
return OK;
}
else if (errno != EAGAIN)
{
/* Some failure other than receive timeout occurred */
return ERROR;
}
}
return ERROR;
}

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/net/lib_gethostbyaddr.c
* libc/netdb/lib_gethostbyaddr.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -43,9 +43,9 @@
#include <errno.h>
#include "lib_internal.h"
#include "net/lib_netdb.h"
#include "netdb/lib_netdb.h"
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
/****************************************************************************
* Public Functions
@ -89,4 +89,4 @@ FAR struct hostent *gethostbyaddr(FAR const void *addr, socklen_t len, int type)
return ret == 0 ? &g_hostent : NULL;
}
#endif /* CONFIG_LIB_NETDB */
#endif /* CONFIG_NETDB_HOSTFILE */

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/net/lib_gethostbyaddrr.c
* libc/netdb/lib_gethostbyaddrr.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -48,9 +48,9 @@
#include <arpa/inet.h>
#include "lib_internal.h"
#include "net/lib_netdb.h"
#include "netdb/lib_netdb.h"
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
/****************************************************************************
* Public Functions
@ -185,4 +185,4 @@ errorout_with_herrnocode:
return ERROR;
}
#endif /* CONFIG_LIB_NETDB */
#endif /* CONFIG_NETDB_HOSTFILE */

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/net/lib_gethostbyname.c
* libc/netdb/lib_gethostbyname.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -43,9 +43,9 @@
#include <errno.h>
#include "lib_internal.h"
#include "net/lib_netdb.h"
#include "netdb/lib_netdb.h"
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
/****************************************************************************
* Public Functions
@ -89,4 +89,4 @@ FAR struct hostent *gethostbyname(FAR const char *name)
return ret == 0 ? &g_hostent : NULL;
}
#endif /* CONFIG_LIB_NETDB */
#endif /* CONFIG_NETDB_HOSTFILE */

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/net/lib_gethostbynamer.c
* libc/netdb/lib_gethostbynamer.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -49,7 +49,7 @@
#include "lib_internal.h"
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
/****************************************************************************
* Pre-processor Definitions
@ -353,4 +353,4 @@ errorout_with_herrnocode:
return ERROR;
}
#endif /* CONFIG_LIB_NETDB */
#endif /* CONFIG_NETDB_HOSTFILE */

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/net/lib_netdb.c
* libc/netdb/lib_netdb.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -41,9 +41,9 @@
#include <netdb.h>
#include "net/lib_netdb.h"
#include "netdb/lib_netdb.h"
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
/****************************************************************************
* Public Data
@ -56,4 +56,4 @@ char g_hostbuffer[CONFIG_NETDB_BUFSIZE];
* Public Functions
****************************************************************************/
#endif /* CONFIG_LIB_NETDB */
#endif /* CONFIG_NETDB_HOSTFILE */

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/net/lib_netdb.h
* libc/netdb/lib_netdb.h
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -44,7 +44,7 @@
#include <netdb.h>
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
/****************************************************************************
* Pre-processor Definitions

View File

@ -1,5 +1,5 @@
/****************************************************************************
* libc/net/lib_parsehostile.c
* libc/netdb/lib_parsehostile.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@ -50,7 +50,7 @@
#include "lib_internal.h"
#ifdef CONFIG_LIB_NETDB
#ifdef CONFIG_NETDB_HOSTFILE
/****************************************************************************
* Pre-processor Definitions
@ -446,4 +446,4 @@ ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host,
return nread;
}
#endif /* CONFIG_LIB_NETDB */
#endif /* CONFIG_NETDB_HOSTFILE */