mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-02 01:40:07 +00:00
b455972fda
2000-05-27 Ulrich Drepper <drepper@redhat.com> * sysdeps/posix/getaddrinfo.c (gaih_inet): If req->ai_family == AF_UNSPEC don't allow the IPv6 lookup to return mapped IPv4 addresses. * nss/nss_files/files-hosts.c (LINE_PARSER): Simplify. Correct handling of AI_V4MAPPED flag. * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname2_r): If lookup of IPv6 address failed and RES_USE_INET6 bit in _res.options is set, perform lookup for T_A type and tell getanswer_r to convert the result with new argument. (_nss_dns_gethostbyaddr_r): Pass zero as new argument to getanswer_r. Don't convert addresses from IPv4 to IPv6 here. (getanswer_r): Take new parameter indicating if mapping from IPv4 to IPv6 is wanted. Allow qtype and type from reply to disagree if IPv4 mapping has to be done. Perform mappings if required by the caller and not if RES_USE_INET6 bit in _res.options is set. Add several __builtin_expect.
111 lines
3.3 KiB
C
111 lines
3.3 KiB
C
/* Hosts file parser in nss_files module.
|
|
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
|
This file is part of the GNU C Library.
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA. */
|
|
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <arpa/nameser.h>
|
|
#include <netdb.h>
|
|
#include <resolv.h>
|
|
|
|
|
|
/* Get implementation for some internal functions. */
|
|
#include "../resolv/mapv4v6addr.h"
|
|
|
|
|
|
#define ENTNAME hostent
|
|
#define DATABASE "hosts"
|
|
#define NEED_H_ERRNO
|
|
|
|
#define EXTRA_ARGS , af, flags
|
|
#define EXTRA_ARGS_DECL , int af, int flags
|
|
|
|
#define ENTDATA hostent_data
|
|
struct hostent_data
|
|
{
|
|
unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
|
|
char *h_addr_ptrs[2]; /* Points to that and null terminator. */
|
|
};
|
|
|
|
#define TRAILING_LIST_MEMBER h_aliases
|
|
#define TRAILING_LIST_SEPARATOR_P isspace
|
|
#include "files-parse.c"
|
|
LINE_PARSER
|
|
("#",
|
|
{
|
|
char *addr;
|
|
|
|
STRING_FIELD (addr, isspace, 1);
|
|
|
|
/* Parse address. */
|
|
if (inet_pton (af, addr, entdata->host_addr) <= 0
|
|
&& (af != AF_INET6 || (flags & AI_V4MAPPED) == 0
|
|
|| inet_pton (AF_INET, addr, entdata->host_addr) <= 0
|
|
|| (map_v4v6_address ((char *) entdata->host_addr,
|
|
(char *) entdata->host_addr),
|
|
0)))
|
|
/* Illegal address: ignore line. */
|
|
return 0;
|
|
|
|
/* We always return entries of the requested form. */
|
|
result->h_addrtype = af;
|
|
result->h_length = af == AF_INET ? INADDRSZ : IN6ADDRSZ;
|
|
|
|
/* Store a pointer to the address in the expected form. */
|
|
entdata->h_addr_ptrs[0] = entdata->host_addr;
|
|
entdata->h_addr_ptrs[1] = NULL;
|
|
result->h_addr_list = entdata->h_addr_ptrs;
|
|
|
|
STRING_FIELD (result->h_name, isspace, 1);
|
|
})
|
|
|
|
#define EXTRA_ARGS_VALUE \
|
|
, ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), \
|
|
((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
|
|
#include "files-XXX.c"
|
|
|
|
DB_LOOKUP (hostbyname, ,,
|
|
{
|
|
LOOKUP_NAME_CASE (h_name, h_aliases)
|
|
}, const char *name)
|
|
|
|
#undef EXTRA_ARGS_VALUE
|
|
/* XXX Is using _res to determine whether we want to convert IPv4 addresses
|
|
to IPv6 addresses really the right thing to do? */
|
|
#define EXTRA_ARGS_VALUE \
|
|
, af, ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
|
|
DB_LOOKUP (hostbyname2, ,,
|
|
{
|
|
LOOKUP_NAME_CASE (h_name, h_aliases)
|
|
}, const char *name, int af)
|
|
|
|
DB_LOOKUP (hostbyaddr, ,,
|
|
{
|
|
if (result->h_length == len
|
|
&& ! memcmp (addr, result->h_addr_list[0], len))
|
|
break;
|
|
}, const void *addr, socklen_t len, int af)
|
|
|
|
#undef EXTRA_ARGS_VALUE
|
|
#define EXTRA_ARGS_VALUE \
|
|
, af, flags
|
|
DB_LOOKUP (ipnodebyname, ,,
|
|
{
|
|
LOOKUP_NAME_CASE (h_name, h_aliases)
|
|
}, const char *name, int af, int flags)
|