glibc/nss/nss_files/files-hosts.c
Ulrich Drepper b455972fda Update.
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.
2000-05-27 08:17:05 +00:00

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)