libs/libc/netdb: Add getaddrinfo() and friends.
This commit is contained in:
parent
5c8a975d79
commit
1f4a1eab6d
2
TODO
2
TODO
@ -1177,7 +1177,7 @@ o Network (net/, drivers/net)
|
||||
|
||||
Title: MISSING netdb INTERFACES
|
||||
Description: There is no implementation for many netdb interfaces such as
|
||||
getaddrinfo(), freeaddrinfo(), getnameinfo(), etc.
|
||||
getnetbyname(), getprotobyname(), getnameinfo(), etc.
|
||||
Status: Open
|
||||
Priority: Low
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/netdb.h
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015, 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Reference: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html
|
||||
@ -114,23 +114,14 @@
|
||||
#define NI_NUMERICSCOPE (1 << 4)
|
||||
#define NI_DGRAM (1 << 5)
|
||||
|
||||
/* The <netdb.h> header shall define the following macros for use as error
|
||||
* values for gethostbyaddr() and gethostbyname()
|
||||
*/
|
||||
|
||||
#define HOST_NOT_FOUND 1
|
||||
#define NO_DATA 2
|
||||
#define NO_RECOVERY 3
|
||||
#define TRY_AGAIN 4
|
||||
|
||||
/* Address Information Errors. The <netdb.h> header shall define the
|
||||
* following macros for use as error values for getaddrinfo() and
|
||||
* getnameinfo():
|
||||
*
|
||||
* EAI_AGAIN - The name could not be resolved at this time. Future
|
||||
* attempts may succeed.
|
||||
* EAI_BADFLAGS - The flags had an invalid value.EAI_FAILA non-
|
||||
* recoverable error occurred.
|
||||
* EAI_BADFLAGS - The flags had an invalid value.
|
||||
* EAI_FAIL - A non-recoverable error occurred.
|
||||
* EAI_FAMILY - The address family was not recognized or the address
|
||||
* length was invalid for the specified family.
|
||||
* EAI_MEMORY - There was a memory allocation failure.
|
||||
@ -148,13 +139,14 @@
|
||||
|
||||
#define EAI_AGAIN 1
|
||||
#define EAI_BADFLAGS 2
|
||||
#define EAI_FAMILY 3
|
||||
#define EAI_MEMORY 4
|
||||
#define EAI_NONAME 5
|
||||
#define EAI_SERVICE 6
|
||||
#define EAI_SOCKTYPE 7
|
||||
#define EAI_SYSTEM 8
|
||||
#define EAI_OVERFLOW 9
|
||||
#define EAI_FAIL 3
|
||||
#define EAI_FAMILY 4
|
||||
#define EAI_MEMORY 5
|
||||
#define EAI_NONAME 6
|
||||
#define EAI_SERVICE 7
|
||||
#define EAI_SOCKTYPE 8
|
||||
#define EAI_SYSTEM 9
|
||||
#define EAI_OVERFLOW 10
|
||||
|
||||
/* h_errno values that may be returned by gethosbyname(), gethostbyname_r(),
|
||||
* gethostbyaddr(), or gethostbyaddr_r()
|
||||
@ -170,6 +162,9 @@
|
||||
*
|
||||
* TRY_AGAIN - A temporary and possibly transient error occurred, such as
|
||||
* a failure of a server to respond.
|
||||
*
|
||||
* These are obsolete and were removed in the Open Group Base Specifications
|
||||
* Issue 7, 2018 edition.
|
||||
*/
|
||||
|
||||
#define HOST_NOT_FOUND 1
|
||||
@ -254,9 +249,13 @@ extern "C"
|
||||
/* When the <netdb.h> header is included, h_errno shall be available as a
|
||||
* modifiable lvalue of type int. It is unspecified whether h_errno is a
|
||||
* macro or an identifier declared with external linkage.
|
||||
*
|
||||
* h_errno is obsolete and was removed in the Open Group Base Specifications
|
||||
* Issue 7, 2018 edition.
|
||||
*/
|
||||
|
||||
/* REVISIT: This should at least be per-task? */
|
||||
|
||||
EXTERN int h_errno;
|
||||
|
||||
/****************************************************************************
|
||||
@ -270,22 +269,25 @@ void endhostent(void);
|
||||
void endnetent(void);
|
||||
void endprotoent(void);
|
||||
void endservent(void);
|
||||
#endif
|
||||
void freeaddrinfo(FAR struct addrinfo *);
|
||||
FAR const char *gai_strerror(int);
|
||||
int getaddrinfo(FAR const char *restrict,
|
||||
FAR const char *restrict,
|
||||
FAR const struct addrinfo *restrict,
|
||||
FAR struct addrinfo **restrict);
|
||||
#endif
|
||||
|
||||
FAR struct hostent *gethostbyaddr(FAR const void *addr, socklen_t len,
|
||||
int type);
|
||||
FAR struct hostent *gethostbyname(FAR const char *name);
|
||||
FAR struct servent *getservbyname(FAR const char *name,
|
||||
FAR const char *proto);
|
||||
|
||||
#if 0 /* None of these are yet supported */
|
||||
FAR struct hostent *gethostent(void);
|
||||
int getnameinfo(FAR const struct sockaddr *restrict, socklen_t,
|
||||
FAR char *restrict, socklen_t, FAR char *restrict,
|
||||
int getnameinfo(FAR const struct sockaddr *restrict,
|
||||
socklen_t, FAR char *restrict,
|
||||
socklen_t, FAR char *restrict,
|
||||
socklen_t, int);
|
||||
FAR struct netent *getnetbyaddr(uint32_t, int);
|
||||
FAR struct netent *getnetbyname(FAR const char *);
|
||||
@ -293,7 +295,6 @@ FAR struct netent *getnetent(void);
|
||||
FAR struct protoent *getprotobyname(FAR const char *);
|
||||
FAR struct protoent *getprotobynumber(int);
|
||||
FAR struct protoent *getprotoent(void);
|
||||
FAR struct servent *getservbyname(FAR const char *, FAR const char *);
|
||||
FAR struct servent *getservbyport(int, FAR const char *);
|
||||
FAR struct servent *getservent(void);
|
||||
void sethostent(int);
|
||||
@ -310,6 +311,9 @@ int gethostbyaddr_r(FAR const void *addr, socklen_t len, int type,
|
||||
size_t buflen, int *h_errnop);
|
||||
int gethostbyname_r(FAR const char *name, FAR struct hostent *host,
|
||||
FAR char *buf, size_t buflen, int *h_errnop);
|
||||
int getservbyname_r(FAR const char *name, FAR const char *proto,
|
||||
FAR struct servent *result_buf, FAR char *buf,
|
||||
size_t buflen, FAR struct servent **result);
|
||||
|
||||
#endif /* CONFIG_LIBC_NETDB */
|
||||
|
||||
|
@ -9,6 +9,15 @@ config LIBC_NETDB
|
||||
|
||||
menu "NETDB Support"
|
||||
|
||||
config LIBC_GAISTRERROR
|
||||
bool "Enable gai_strerror"
|
||||
default n
|
||||
---help---
|
||||
The gai_strerror() function shall return a text string describing an error
|
||||
value for the getaddrinfo() and getnameinfo(). But it can also require a lot
|
||||
of memory. If this option is not selected, gai_strerror() will still exist in
|
||||
the build but it will not decode error values.
|
||||
|
||||
menuconfig NETDB_HOSTFILE
|
||||
bool "Network host file support"
|
||||
default n
|
||||
|
@ -38,6 +38,8 @@ ifeq ($(CONFIG_LIBC_NETDB),y)
|
||||
# Add the netdb C files to the build
|
||||
|
||||
CSRCS += lib_netdb.c lib_gethostbyname.c lib_gethostbynamer.c
|
||||
CSRCS += lib_getservbyname.c lib_getservbynamer.c
|
||||
CSRCS += lib_gaistrerror.c lib_freeaddrinfo.c lib_getaddrinfo.c
|
||||
|
||||
# Add host file support
|
||||
|
||||
@ -56,7 +58,7 @@ CSRCS += lib_dnscache.c
|
||||
endif
|
||||
endif
|
||||
|
||||
# Add the net directory to the build
|
||||
# Add the netdb directory to the build
|
||||
|
||||
DEPPATH += --dep-path netdb
|
||||
VPATH += :netdb
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/netdb/lib_dnsclien.c
|
||||
* libs/libc/netdb/lib_dnsbind.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2012, 2014-2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/netdb/lib_dnscache.c
|
||||
* libs/libc/netdb/lib_dnsinit.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2012, 2014-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
68
libs/libc/netdb/lib_freeaddrinfo.c
Normal file
68
libs/libc/netdb/lib_freeaddrinfo.c
Normal file
@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/netdb/lib_freeaddrinfo.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Juha Niskanen <juha.niskanen@haltian.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. 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 <nuttx/config.h>
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: freeaddrinfo
|
||||
****************************************************************************/
|
||||
|
||||
void freeaddrinfo(FAR struct addrinfo *ai)
|
||||
{
|
||||
FAR struct addrinfo *p;
|
||||
|
||||
DEBUGASSERT(ai != NULL);
|
||||
|
||||
do
|
||||
{
|
||||
p = ai;
|
||||
ai = ai->ai_next;
|
||||
lib_free(p);
|
||||
}
|
||||
while (ai != NULL);
|
||||
}
|
||||
|
125
libs/libc/netdb/lib_gaistrerror.c
Normal file
125
libs/libc/netdb/lib_gaistrerror.c
Normal file
@ -0,0 +1,125 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/netdb/lib_gaistrerror.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Juha Niskanen <juha.niskanen@haltian.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. 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 <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netdb.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct errno_strmap_s
|
||||
{
|
||||
uint8_t errnum;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_GAISTRERROR
|
||||
|
||||
/* This table maps all error numbers to descriptive strings.
|
||||
* The only assumption that the code makes with regard to this
|
||||
* this table is that it is ordered by error number.
|
||||
*
|
||||
* The size of this table is quite large. Its size can be
|
||||
* reduced by eliminating some of the more obscure error
|
||||
* strings.
|
||||
*
|
||||
* Only short names are currently supported.
|
||||
*/
|
||||
|
||||
static const struct errno_strmap_s g_gaierrnomap[] =
|
||||
{
|
||||
{ EAI_AGAIN, "EAI_AGAIN" },
|
||||
{ EAI_BADFLAGS, "EAI_BADFLAGS" },
|
||||
{ EAI_FAIL, "EAI_FAIL" },
|
||||
{ EAI_FAMILY, "EAI_FAMILY" },
|
||||
{ EAI_MEMORY, "EAI_MEMORY" },
|
||||
{ EAI_NONAME, "EAI_NONAME" },
|
||||
{ EAI_SERVICE, "EAI_SERVICE" },
|
||||
{ EAI_SOCKTYPE, "EAI_SOCKTYPE" },
|
||||
{ EAI_SYSTEM, "EAI_SYSTEM" },
|
||||
{ EAI_OVERFLOW, "EAI_OVERFLOW" },
|
||||
};
|
||||
|
||||
#define NERRNO_STRS (sizeof(g_gaierrnomap) / sizeof(struct errno_strmap_s))
|
||||
|
||||
#endif /* CONFIG_LIBC_GAISTRERROR */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gai_strerror
|
||||
****************************************************************************/
|
||||
|
||||
FAR const char *gai_strerror(int errnum)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_GAISTRERROR
|
||||
int ndxlow = 0;
|
||||
int ndxhi = NERRNO_STRS - 1;
|
||||
int ndxmid;
|
||||
|
||||
do
|
||||
{
|
||||
ndxmid = (ndxlow + ndxhi) >> 1;
|
||||
if (errnum > g_gaierrnomap[ndxmid].errnum)
|
||||
{
|
||||
ndxlow = ndxmid + 1;
|
||||
}
|
||||
else if (errnum < g_gaierrnomap[ndxmid].errnum)
|
||||
{
|
||||
ndxhi = ndxmid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_gaierrnomap[ndxmid].str;
|
||||
}
|
||||
}
|
||||
while (ndxlow <= ndxhi);
|
||||
#endif
|
||||
return "Unknown error";
|
||||
}
|
||||
|
311
libs/libc/netdb/lib_getaddrinfo.c
Normal file
311
libs/libc/netdb/lib_getaddrinfo.c
Normal file
@ -0,0 +1,311 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/netdb/lib_getaddrinfo.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Juha Niskanen <juha.niskanen@haltian.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. 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 <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <nuttx/net/loopback.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data Types
|
||||
****************************************************************************/
|
||||
|
||||
struct ai_s
|
||||
{
|
||||
struct addrinfo ai;
|
||||
union
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
} sa;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
FAR static struct ai_s *alloc_ai(int family, int port, FAR void *addr)
|
||||
{
|
||||
struct ai_s *ai;
|
||||
socklen_t addrlen;
|
||||
|
||||
addrlen = (family == AF_INET) ? sizeof(struct sockaddr_in)
|
||||
: sizeof(struct sockaddr_in6);
|
||||
|
||||
ai = lib_zalloc(sizeof(struct ai_s));
|
||||
if (ai == NULL)
|
||||
{
|
||||
return ai;
|
||||
}
|
||||
|
||||
ai->ai.ai_addr = (struct sockaddr *)&ai->sa;
|
||||
ai->ai.ai_addrlen = addrlen;
|
||||
ai->ai.ai_addr->sa_family = ai->ai.ai_family = family;
|
||||
|
||||
switch (family)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
case AF_INET:
|
||||
ai->sa.sin.sin_family = AF_INET;
|
||||
ai->sa.sin.sin_port = HTONS(port);
|
||||
memcpy(&ai->sa.sin.sin_addr, addr, sizeof(ai->sa.sin.sin_addr));
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
case AF_INET6:
|
||||
ai->sa.sin6.sin6_family = AF_INET6;
|
||||
ai->sa.sin6.sin6_port = HTONS(port);
|
||||
memcpy(&ai->sa.sin6.sin6_addr, addr, sizeof(ai->sa.sin6.sin6_addr));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: getaddrinfo
|
||||
****************************************************************************/
|
||||
|
||||
int getaddrinfo(FAR const char *restrict hostname,
|
||||
FAR const char *restrict servname,
|
||||
FAR const struct addrinfo *restrict hint,
|
||||
FAR struct addrinfo **restrict res)
|
||||
{
|
||||
int family = AF_UNSPEC;
|
||||
int port = 0;
|
||||
int flags = 0;
|
||||
int proto = 0;
|
||||
int socktype = 0;
|
||||
struct hostent *hp;
|
||||
struct ai_s *ai;
|
||||
struct ai_s *prev_ai = NULL;
|
||||
const int valid_flags = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
|
||||
AI_NUMERICSERV | AI_V4MAPPED | AI_ALL |
|
||||
AI_ADDRCONFIG;
|
||||
int i;
|
||||
|
||||
if (hostname == NULL && servname == NULL)
|
||||
{
|
||||
return EAI_NONAME;
|
||||
}
|
||||
|
||||
if (hint)
|
||||
{
|
||||
family = hint->ai_family;
|
||||
flags = hint->ai_flags;
|
||||
proto = hint->ai_protocol;
|
||||
socktype = hint->ai_socktype;
|
||||
|
||||
if ((flags & valid_flags) != flags)
|
||||
{
|
||||
return EAI_BADFLAGS;
|
||||
}
|
||||
|
||||
if (family != AF_INET &&
|
||||
family != AF_INET6 &&
|
||||
family != AF_UNSPEC)
|
||||
{
|
||||
return EAI_FAMILY;
|
||||
}
|
||||
}
|
||||
|
||||
if (servname)
|
||||
{
|
||||
char *endp;
|
||||
struct servent *sp;
|
||||
|
||||
port = strtol(servname, &endp, 10);
|
||||
if (port > 0 && port <= 65535 && *endp == '\0')
|
||||
{
|
||||
port = HTONS(port);
|
||||
}
|
||||
else if (flags & AI_NUMERICSERV)
|
||||
{
|
||||
return EAI_NONAME;
|
||||
}
|
||||
else if ((sp = getservbyname(servname, NULL)) != NULL)
|
||||
{
|
||||
port = sp->s_port;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EAI_SERVICE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & AI_PASSIVE)
|
||||
{
|
||||
in_addr_t addr;
|
||||
|
||||
addr = hostname ? inet_addr(hostname) : HTONL(0x00000000);
|
||||
|
||||
/* REVISIT: IPv6? */
|
||||
|
||||
ai = alloc_ai(AF_INET, port, &addr);
|
||||
if (ai == NULL)
|
||||
{
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
*res = (struct addrinfo *)ai;
|
||||
return OK;
|
||||
}
|
||||
|
||||
*res = NULL;
|
||||
|
||||
if (!hostname)
|
||||
{
|
||||
#ifdef CONFIG_NET_LOOPBACK
|
||||
/* Local service. */
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
if (family == AF_INET || family == AF_UNSPEC)
|
||||
{
|
||||
ai = alloc_ai(AF_INET, port, (void *)&g_lo_ipv4addr);
|
||||
if (ai == NULL)
|
||||
{
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
*res = (struct addrinfo *)ai;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
if (family == AF_INET6 || family == AF_UNSPEC)
|
||||
{
|
||||
ai = alloc_ai(AF_INET6, port, (void *)&g_lo_ipv6addr);
|
||||
if (ai == NULL)
|
||||
{
|
||||
return (*res != NULL) ? OK : EAI_MEMORY;
|
||||
}
|
||||
|
||||
/* Can return both IPv4 and IPv6 loopback. */
|
||||
|
||||
if (*res != NULL)
|
||||
{
|
||||
(*res)->ai_next = (struct addrinfo *)ai;
|
||||
}
|
||||
else
|
||||
{
|
||||
*res = (struct addrinfo *)ai;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (*res != NULL) ? OK : EAI_FAMILY;
|
||||
#else
|
||||
/* Local service, but no loopback so cannot succeed. */
|
||||
|
||||
return EAI_FAIL;
|
||||
#endif /* CONFIG_NET_LOOPBACK */
|
||||
}
|
||||
|
||||
/* REVISIT: no check for AI_NUMERICHOST flag. */
|
||||
|
||||
/* REVISIT: use gethostbyname_r with own buffer of refactor all
|
||||
* public APIs to use internal lookup function.
|
||||
*/
|
||||
|
||||
hp = gethostbyname(hostname);
|
||||
if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0])
|
||||
{
|
||||
for (i = 0; hp->h_addr_list[i]; i++)
|
||||
{
|
||||
if (family != AF_UNSPEC && hp->h_addrtype != family)
|
||||
{
|
||||
/* Filter by protocol family. */
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* REVISIT: filter by socktype and protocol not implemented. */
|
||||
|
||||
UNUSED(proto);
|
||||
UNUSED(socktype);
|
||||
|
||||
ai = alloc_ai(hp->h_addrtype, port, hp->h_addr_list[i]);
|
||||
if (ai == NULL)
|
||||
{
|
||||
if (*res)
|
||||
{
|
||||
freeaddrinfo(*res);
|
||||
}
|
||||
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
/* REVISIT: grok canonical name.
|
||||
*
|
||||
* OpenGroup: "if the canonical name is not available, then ai_canonname shall
|
||||
* refer to the hostname argument or a string with the same contents."
|
||||
*/
|
||||
|
||||
ai->ai.ai_canonname = (char *)hostname;
|
||||
|
||||
/* Add result to linked list.
|
||||
* TODO: RFC 3484/6724 destination address sort not implemented.
|
||||
*/
|
||||
|
||||
if (prev_ai)
|
||||
{
|
||||
prev_ai->ai.ai_next = (struct addrinfo *)ai;
|
||||
}
|
||||
else
|
||||
{
|
||||
*res = (struct addrinfo *)ai;
|
||||
}
|
||||
|
||||
prev_ai = ai;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
return EAI_AGAIN;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gethostname
|
||||
* Name: gethostbyname
|
||||
*
|
||||
* Description:
|
||||
* The gethostbyname() function returns a structure of type hostent for
|
||||
|
@ -697,7 +697,7 @@ errorout_with_herrnocode:
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gethostname_r
|
||||
* Name: gethostbyname_r
|
||||
*
|
||||
* Description:
|
||||
* The gethostbyname_r() function returns a structure of type hostent for
|
||||
|
66
libs/libc/netdb/lib_getservbyname.c
Normal file
66
libs/libc/netdb/lib_getservbyname.c
Normal file
@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/netdb/lib_getservbyname.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Juha Niskanen <juha.niskanen@haltian.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. 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 <nuttx/config.h>
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef CONFIG_LIBC_NETDB
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: getservbyname
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct servent *getservbyname(FAR const char *name, FAR const char *proto)
|
||||
{
|
||||
static struct servent ent;
|
||||
static char *buf[2];
|
||||
struct servent *res;
|
||||
int ret;
|
||||
|
||||
ret = getservbyname_r(name, proto, &ent, (void *)buf, sizeof buf, &res);
|
||||
return (ret != OK) ? NULL : res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LIBC_NETDB */
|
||||
|
169
libs/libc/netdb/lib_getservbynamer.c
Normal file
169
libs/libc/netdb/lib_getservbynamer.c
Normal file
@ -0,0 +1,169 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/netdb/lib_getservbynamer.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Juha Niskanen <juha.niskanen@haltian.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. 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 <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef CONFIG_LIBC_NETDB
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data Types
|
||||
****************************************************************************/
|
||||
|
||||
struct services_db_s
|
||||
{
|
||||
const char *s_name;
|
||||
int s_port;
|
||||
int s_protocol;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Declare your services here. TODO: read from /etc/services?
|
||||
* REVISIT: This is just an example, lets not add full list here.
|
||||
*/
|
||||
|
||||
const static struct services_db_s g_services_db[] =
|
||||
{
|
||||
{ "ntp", 123, IP_PROTO_TCP },
|
||||
{ "ntp", 123, IP_PROTO_UDP },
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: getservbyname_r
|
||||
****************************************************************************/
|
||||
|
||||
int getservbyname_r(FAR const char *name, FAR const char *proto,
|
||||
FAR struct servent *result_buf, FAR char *buf,
|
||||
size_t buflen, FAR struct servent **result)
|
||||
{
|
||||
char *end = "";
|
||||
int protocol;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(name != NULL && buf != NULL);
|
||||
DEBUGASSERT(result_buf != NULL && result != NULL);
|
||||
|
||||
/* Linux man page says result must be NULL in case of failure. */
|
||||
|
||||
*result = NULL;
|
||||
|
||||
/* We need space for two pointers for hostalias strings. */
|
||||
|
||||
if (buflen < 2 * sizeof(char *))
|
||||
{
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
/* Numeric port number strings are not service records. */
|
||||
|
||||
strtoul(name, &end, 10);
|
||||
if (*end == '\0')
|
||||
{
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
if (proto == NULL)
|
||||
{
|
||||
protocol = 0;
|
||||
}
|
||||
else if (strcmp(proto, "tcp") == 0)
|
||||
{
|
||||
protocol = IPPROTO_TCP;
|
||||
}
|
||||
else if (strcmp(proto, "udp") == 0)
|
||||
{
|
||||
protocol = IPPROTO_UDP;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(g_services_db); i++)
|
||||
{
|
||||
if (strcmp(name, g_services_db[i].s_name) == 0 &&
|
||||
(protocol == 0 || protocol == g_services_db[i].s_protocol))
|
||||
{
|
||||
result_buf->s_name = (char *)name;
|
||||
result_buf->s_aliases = (void *)buf;
|
||||
result_buf->s_aliases[0] = (char *)name;
|
||||
result_buf->s_aliases[1] = NULL;
|
||||
result_buf->s_port = HTONS(g_services_db[i].s_port);
|
||||
|
||||
if (g_services_db[i].s_protocol == IPPROTO_TCP)
|
||||
{
|
||||
result_buf->s_proto = "tcp";
|
||||
}
|
||||
else
|
||||
{
|
||||
result_buf->s_proto = "udp";
|
||||
}
|
||||
|
||||
*result = result_buf;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LIBC_NETDB */
|
||||
|
@ -10,12 +10,12 @@ config LIBC_STRERROR
|
||||
default n
|
||||
---help---
|
||||
strerror() is useful because it decodes 'errno' values into a human readable
|
||||
strings. But it can also require a lot of memory. If this option is selected,
|
||||
strerror() will still exist in the build but it will not decode error values.
|
||||
This option should be used by other logic to decide if it should use strerror()
|
||||
or not. For example, the NSH application will not use strerror() if this
|
||||
option is not selected; perror() will not use strerror() is this option is not
|
||||
selected (see also NSH_STRERROR).
|
||||
strings. But it can also require a lot of memory. If this option is not
|
||||
selected, strerror() will still exist in the build but it will not decode error
|
||||
values. This option should be used by other logic to decide if it should use
|
||||
strerror() or not. For example, the NSH application will not use strerror()
|
||||
if this option is not selected; perror() will not use strerror() is this option
|
||||
is not selected (see also NSH_STRERROR).
|
||||
|
||||
config LIBC_STRERROR_SHORT
|
||||
bool "Use short error descriptions in strerror()"
|
||||
|
Loading…
Reference in New Issue
Block a user