libc/netdb: Support save the mix of IPv4/IPv6 address into hostent
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Change-Id: I704d38afde14b6d90a7726096fd1f483f96ba237
This commit is contained in:
parent
7f2810f73a
commit
8d66a316da
@ -184,14 +184,17 @@ struct hostent
|
|||||||
FAR char **h_aliases; /* A pointer to an array of pointers to the
|
FAR char **h_aliases; /* A pointer to an array of pointers to the
|
||||||
* alternative host names, terminated by a
|
* alternative host names, terminated by a
|
||||||
* null pointer. */
|
* null pointer. */
|
||||||
int h_addrtype; /* Address type. */
|
FAR int *h_addrtypes; /* A pointer to an array of address type. */
|
||||||
int h_length; /* The length, in bytes, of the address. */
|
FAR int *h_lengths; /* A pointer to an array of the length, in bytes,
|
||||||
|
* of the address. */
|
||||||
FAR char **h_addr_list; /* A pointer to an array of pointers to network
|
FAR char **h_addr_list; /* A pointer to an array of pointers to network
|
||||||
* addresses (in network byte order) for the host,
|
* addresses (in network byte order) for the host,
|
||||||
* terminated by a null pointer. */
|
* terminated by a null pointer. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define h_addr h_addr_list[0] /* For backward compatibility */
|
#define h_addr h_addr_list[0] /* For backward compatibility */
|
||||||
|
#define h_length h_lengths[0]
|
||||||
|
#define h_addrtype h_addrtypes[0]
|
||||||
|
|
||||||
struct netent
|
struct netent
|
||||||
{
|
{
|
||||||
|
@ -287,7 +287,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
|
|||||||
{
|
{
|
||||||
for (i = 0; hp->h_addr_list[i]; i++)
|
for (i = 0; hp->h_addr_list[i]; i++)
|
||||||
{
|
{
|
||||||
if (family != AF_UNSPEC && hp->h_addrtype != family)
|
if (family != AF_UNSPEC && hp->h_addrtypes[i] != family)
|
||||||
{
|
{
|
||||||
/* Filter by protocol family. */
|
/* Filter by protocol family. */
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ int getaddrinfo(FAR const char *hostname, FAR const char *servname,
|
|||||||
|
|
||||||
/* REVISIT: filter by socktype and protocol not implemented. */
|
/* REVISIT: filter by socktype and protocol not implemented. */
|
||||||
|
|
||||||
ai = alloc_ai(hp->h_addrtype, socktype, proto, port,
|
ai = alloc_ai(hp->h_addrtypes[i], socktype, proto, port,
|
||||||
hp->h_addr_list[i]);
|
hp->h_addr_list[i]);
|
||||||
if (ai == NULL)
|
if (ai == NULL)
|
||||||
{
|
{
|
||||||
|
@ -61,8 +61,10 @@
|
|||||||
|
|
||||||
struct hostent_info_s
|
struct hostent_info_s
|
||||||
{
|
{
|
||||||
|
int hi_addrtypes[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||||
|
int hi_lengths[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||||
FAR char *hi_addrlist[CONFIG_NETDB_MAX_IPADDR + 1];
|
FAR char *hi_addrlist[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||||
char hi_data[1];
|
char hi_data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -164,34 +166,48 @@ static int lib_localhost(FAR const void *addr, socklen_t len, int type,
|
|||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
FAR struct hostent_info_s *info;
|
FAR struct hostent_info_s *info;
|
||||||
socklen_t addrlen;
|
|
||||||
FAR const uint8_t *src;
|
|
||||||
FAR char *dest;
|
FAR char *dest;
|
||||||
int namelen;
|
int namelen;
|
||||||
|
|
||||||
|
/* Make sure that space remains to hold the hostent structure */
|
||||||
|
|
||||||
|
if (buflen <= sizeof(struct hostent_info_s))
|
||||||
|
{
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = (FAR struct hostent_info_s *)buf;
|
||||||
|
dest = info->hi_data;
|
||||||
|
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||||
|
|
||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
|
|
||||||
|
host->h_addrtypes = info->hi_addrtypes;
|
||||||
|
host->h_lengths = info->hi_lengths;
|
||||||
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
if (lib_lo_ipv4match(addr, len, type))
|
if (lib_lo_ipv4match(addr, len, type))
|
||||||
{
|
{
|
||||||
/* Setup to transfer the IPv4 address */
|
/* Save the IPv4 address */
|
||||||
|
|
||||||
addrlen = sizeof(struct in_addr);
|
host->h_length = sizeof(struct in_addr);
|
||||||
src = (FAR uint8_t *)&g_lo_ipv4addr;
|
host->h_addr = (FAR char *)&g_lo_ipv4addr;
|
||||||
host->h_addrtype = AF_INET;
|
host->h_addrtype = AF_INET;
|
||||||
goto out_copy;
|
goto out_copyname;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
if (lib_lo_ipv6match(addr, len, type))
|
if (lib_lo_ipv6match(addr, len, type))
|
||||||
{
|
{
|
||||||
/* Setup to transfer the IPv6 address */
|
/* Save the IPv6 address */
|
||||||
|
|
||||||
addrlen = sizeof(struct in6_addr);
|
host->h_length = sizeof(struct in6_addr);
|
||||||
src = (FAR uint8_t *)&g_lo_ipv6addr;
|
host->h_addr = (FAR char *)&g_lo_ipv6addr;
|
||||||
host->h_addrtype = AF_INET6;
|
host->h_addrtype = AF_INET6;
|
||||||
goto out_copy;
|
goto out_copyname;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -199,29 +215,7 @@ static int lib_localhost(FAR const void *addr, socklen_t len, int type,
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
out_copy:
|
out_copyname:
|
||||||
/* Make sure that space remains to hold the hostent structure and
|
|
||||||
* the IP address.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (buflen <= (sizeof(struct hostent_info_s) + addrlen))
|
|
||||||
{
|
|
||||||
return -ERANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = (FAR struct hostent_info_s *)buf;
|
|
||||||
dest = info->hi_data;
|
|
||||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
|
||||||
|
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
|
||||||
memcpy(dest, src, addrlen);
|
|
||||||
|
|
||||||
info->hi_addrlist[0] = dest;
|
|
||||||
host->h_addr_list = info->hi_addrlist;
|
|
||||||
host->h_length = addrlen;
|
|
||||||
|
|
||||||
dest += addrlen;
|
|
||||||
buflen -= addrlen;
|
|
||||||
|
|
||||||
/* And copy localhost host name */
|
/* And copy localhost host name */
|
||||||
|
|
||||||
|
@ -66,8 +66,10 @@
|
|||||||
|
|
||||||
struct hostent_info_s
|
struct hostent_info_s
|
||||||
{
|
{
|
||||||
|
int hi_addrtypes[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||||
|
int hi_lengths[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||||
FAR char *hi_addrlist[CONFIG_NETDB_MAX_IPADDR + 1];
|
FAR char *hi_addrlist[CONFIG_NETDB_MAX_IPADDR + 1];
|
||||||
char hi_data[1];
|
char hi_data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -120,6 +122,10 @@ static int lib_numeric_address(FAR const char *name,
|
|||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
|
|
||||||
|
host->h_addrtypes = info->hi_addrtypes;
|
||||||
|
host->h_lengths = info->hi_lengths;
|
||||||
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
/* If the address contains a colon, then it might be a numeric IPv6
|
/* If the address contains a colon, then it might be a numeric IPv6
|
||||||
* address
|
* address
|
||||||
*/
|
*/
|
||||||
@ -189,12 +195,11 @@ static int lib_numeric_address(FAR const char *name,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->hi_addrlist[0] = ptr;
|
host->h_addr = ptr;
|
||||||
host->h_addr_list = info->hi_addrlist;
|
host->h_length = addrlen;
|
||||||
host->h_length = addrlen;
|
|
||||||
|
|
||||||
ptr += addrlen;
|
ptr += addrlen;
|
||||||
buflen -= addrlen;
|
buflen -= addrlen;
|
||||||
|
|
||||||
/* And copy name */
|
/* And copy name */
|
||||||
|
|
||||||
@ -235,53 +240,49 @@ static int lib_localhost(FAR const char *name, FAR struct hostent *host,
|
|||||||
FAR char *buf, size_t buflen)
|
FAR char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
FAR struct hostent_info_s *info;
|
FAR struct hostent_info_s *info;
|
||||||
socklen_t addrlen;
|
|
||||||
FAR const char *src;
|
|
||||||
FAR char *dest;
|
FAR char *dest;
|
||||||
int namelen;
|
int namelen;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
if (strcmp(name, g_lo_hostname) == 0)
|
if (strcmp(name, g_lo_hostname) == 0)
|
||||||
{
|
{
|
||||||
/* Yes.. it is the localhost */
|
/* Yes.. it is the localhost */
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
/* Make sure that space remains to hold the hostent structure */
|
||||||
/* Setup to transfer the IPv4 address */
|
|
||||||
|
|
||||||
addrlen = sizeof(struct in_addr);
|
if (buflen <= sizeof(struct hostent_info_s))
|
||||||
src = (FAR const char *)&g_lo_ipv4addr;
|
|
||||||
host->h_addrtype = AF_INET;
|
|
||||||
|
|
||||||
#else /* CONFIG_NET_IPv6 */
|
|
||||||
/* Setup to transfer the IPv6 address */
|
|
||||||
|
|
||||||
addrlen = sizeof(struct in6_addr);
|
|
||||||
src = (FAR const char *)&g_lo_ipv6addr;
|
|
||||||
host->h_addrtype = AF_INET6;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Make sure that space remains to hold the hostent structure and
|
|
||||||
* the IP address.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (buflen <= (sizeof(struct hostent_info_s) + addrlen))
|
|
||||||
{
|
{
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = (FAR struct hostent_info_s *)buf;
|
info = (FAR struct hostent_info_s *)buf;
|
||||||
dest = info->hi_data;
|
dest = info->hi_data;
|
||||||
buflen -= (sizeof(struct hostent_info_s) - 1);
|
buflen -= (sizeof(struct hostent_info_s) - 1);
|
||||||
|
|
||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
memcpy(dest, src, addrlen);
|
|
||||||
|
|
||||||
info->hi_addrlist[0] = dest;
|
host->h_addrtypes = info->hi_addrtypes;
|
||||||
host->h_addr_list = info->hi_addrlist;
|
host->h_lengths = info->hi_lengths;
|
||||||
host->h_length = addrlen;
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
dest += addrlen;
|
#ifdef CONFIG_NET_IPv4
|
||||||
buflen -= addrlen;
|
/* Save the IPv4 address */
|
||||||
|
|
||||||
|
info->hi_addrtypes[i] = AF_INET;
|
||||||
|
info->hi_lengths[i] = sizeof(struct in_addr);
|
||||||
|
info->hi_addrlist[i] = (FAR char *)&g_lo_ipv4addr;
|
||||||
|
i++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
/* Save the IPv6 address */
|
||||||
|
|
||||||
|
info->hi_addrtypes[i] = AF_INET6;
|
||||||
|
info->hi_lengths[i] = sizeof(struct in6_addr);
|
||||||
|
info->hi_addrlist[i] = (FAR char *)&g_lo_ipv6addr;
|
||||||
|
i++;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* And copy name */
|
/* And copy name */
|
||||||
|
|
||||||
@ -362,6 +363,10 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
|||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
|
|
||||||
|
host->h_addrtypes = info->hi_addrtypes;
|
||||||
|
host->h_lengths = info->hi_lengths;
|
||||||
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
/* Try to get the host address using the DNS name server */
|
/* Try to get the host address using the DNS name server */
|
||||||
|
|
||||||
naddr = buflen / sizeof(union dns_addr_u);
|
naddr = buflen / sizeof(union dns_addr_u);
|
||||||
@ -401,18 +406,14 @@ static int lib_find_answer(FAR const char *name, FAR struct hostent *host,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* REVISIT: This assumes addresses are all either IPv4 or IPv6. */
|
info->hi_addrtypes[i] = addrtype;
|
||||||
|
info->hi_lengths[i] = addrlen;
|
||||||
|
info->hi_addrlist[i] = addrdata;
|
||||||
|
|
||||||
info->hi_addrlist[i] = addrdata;
|
ptr += sizeof(union dns_addr_u);
|
||||||
host->h_addrtype = addrtype;
|
buflen -= sizeof(union dns_addr_u);
|
||||||
host->h_length = addrlen;
|
|
||||||
|
|
||||||
ptr += sizeof(union dns_addr_u);
|
|
||||||
buflen -= sizeof(union dns_addr_u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
host->h_addr_list = info->hi_addrlist;
|
|
||||||
|
|
||||||
/* And copy name */
|
/* And copy name */
|
||||||
|
|
||||||
namelen = strlen(name);
|
namelen = strlen(name);
|
||||||
@ -524,6 +525,10 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
|
|||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
|
|
||||||
|
host->h_addrtypes = info->hi_addrtypes;
|
||||||
|
host->h_lengths = info->hi_lengths;
|
||||||
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
/* Try to get the host address using the DNS name server */
|
/* Try to get the host address using the DNS name server */
|
||||||
|
|
||||||
naddr = buflen / sizeof(union dns_addr_u);
|
naddr = buflen / sizeof(union dns_addr_u);
|
||||||
@ -561,18 +566,14 @@ static int lib_dns_lookup(FAR const char *name, FAR struct hostent *host,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* REVISIT: This assumes addresses are all either IPv4 or IPv6. */
|
info->hi_addrtypes[i] = addrtype;
|
||||||
|
info->hi_lengths[i] = addrlen;
|
||||||
|
info->hi_addrlist[i] = addrdata;
|
||||||
|
|
||||||
info->hi_addrlist[i] = addrdata;
|
ptr += sizeof(union dns_addr_u);
|
||||||
host->h_addrtype = addrtype;
|
buflen -= sizeof(union dns_addr_u);
|
||||||
host->h_length = addrlen;
|
|
||||||
|
|
||||||
ptr += sizeof(union dns_addr_u);
|
|
||||||
buflen -= sizeof(union dns_addr_u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
host->h_addr_list = info->hi_addrlist;
|
|
||||||
|
|
||||||
/* And copy name */
|
/* And copy name */
|
||||||
|
|
||||||
namelen = strlen(name);
|
namelen = strlen(name);
|
||||||
|
@ -72,8 +72,10 @@
|
|||||||
struct hostent_info_s
|
struct hostent_info_s
|
||||||
{
|
{
|
||||||
FAR char *hi_aliases[CONFIG_NETDB_MAX_ALTNAMES + 1];
|
FAR char *hi_aliases[CONFIG_NETDB_MAX_ALTNAMES + 1];
|
||||||
|
int hi_addrtypes[2];
|
||||||
|
int hi_lengths[2];
|
||||||
FAR char *hi_addrlist[2];
|
FAR char *hi_addrlist[2];
|
||||||
char hi_data[1];
|
char hi_data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -292,6 +294,10 @@ ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host,
|
|||||||
memset(host, 0, sizeof(struct hostent));
|
memset(host, 0, sizeof(struct hostent));
|
||||||
memset(info, 0, sizeof(struct hostent_info_s));
|
memset(info, 0, sizeof(struct hostent_info_s));
|
||||||
|
|
||||||
|
host->h_addrtypes = info->hi_addrtypes;
|
||||||
|
host->h_lengths = info->hi_lengths;
|
||||||
|
host->h_addr_list = info->hi_addrlist;
|
||||||
|
|
||||||
/* Skip over any leading spaces */
|
/* Skip over any leading spaces */
|
||||||
|
|
||||||
do
|
do
|
||||||
@ -379,12 +385,11 @@ ssize_t lib_parse_hostfile(FAR FILE *stream, FAR struct hostent *host,
|
|||||||
host->h_addrtype = AF_INET;
|
host->h_addrtype = AF_INET;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->hi_addrlist[0] = ptr;
|
host->h_addr = ptr;
|
||||||
host->h_addr_list = info->hi_addrlist;
|
host->h_length = addrlen;
|
||||||
host->h_length = addrlen;
|
|
||||||
|
|
||||||
ptr += addrlen;
|
ptr += addrlen;
|
||||||
buflen -= addrlen;
|
buflen -= addrlen;
|
||||||
|
|
||||||
/* Skip over any additional whitespace */
|
/* Skip over any additional whitespace */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user