11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$NetBSD: gethnamaddr.c,v 1.70 2006/03/22 00:03:51 christos Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ++Copyright++ 1985, 1988, 1993
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1985, 1988, 1993
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    The Regents of the University of California.  All rights reserved.
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    documentation and/or other materials provided with the distribution.
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    may be used to endorse or promote products derived from this software
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    without specific prior written permission.
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1993 by Digital Equipment Corporation.
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies, and that
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the name of Digital Equipment Corporation not be used in advertising or
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * publicity pertaining to distribution of the document or software without
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * specific, written prior permission.
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SOFTWARE.
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * -
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * --Copyright--
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h>
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h>
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h>
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/socket.h>
59c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk#include <sys/un.h>
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netinet/in.h>
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <arpa/inet.h>
62569fb9887d00104509df79fa77d92e3cf9afe7dbCalin Juravle#include <arpa/nameser.h>
635240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen#include "NetdClientDispatch.h"
64ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak#include "resolv_netid.h"
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_private.h"
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_cache.h"
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <assert.h>
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <ctype.h>
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netdb.h>
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdarg.h>
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
732cc2b2be692f1d559a09d2066e56e450249cc9c0Carl Shapiro#include <strings.h>
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <syslog.h>
75c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk#include <unistd.h>
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
77c20de902875dcaebde0ccd0b7a8351598f254d4cCalin Juravle#define ALIGNBYTES (sizeof(uintptr_t) - 1)
78c20de902875dcaebde0ccd0b7a8351598f254d4cCalin Juravle#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
79c20de902875dcaebde0ccd0b7a8351598f254d4cCalin Juravle
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef LOG_AUTH
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# define LOG_AUTH 0
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define MULTI_PTRS_ARE_ALIASES 1	/* XXX - experimental */
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "nsswitch.h"
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
90c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk// This should be synchronized to ResponseCode.h
91c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstatic const int DnsProxyQueryResult = 222;
92c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
9368c2755d71750401d82d9aa17774ebd385cb5dc0Elliott Hughesstatic const char AskedForGot[] =
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			  "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	MAXPACKET	(64*1024)
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union {
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    HEADER hdr;
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    u_char buf[MAXPACKET];
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} querybuf;
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef union {
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    int32_t al;
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    char ac;
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} align;
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void dprintf(const char *, res_state, ...)
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	__attribute__((__format__(__printf__, 1, 3)));
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct hostent *getanswer(const querybuf *, int, const char *, int,
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    res_state);
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void map_v4v6_address(const char *, char *);
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void map_v4v6_hostent(struct hostent *, char **, char *);
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void addrsort(char **, int, res_state);
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
118e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic void _sethtent(int);
119e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic void _endhtent(void);
120e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic struct hostent *_gethtent(void);
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid ht_sethostent(int);
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid ht_endhostent(void);
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct hostent *ht_gethostbyname(char *);
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct hostent *ht_gethostbyaddr(const char *, int, int);
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid dns_service(void);
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#undef dn_skipname
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint dn_skipname(const u_char *, const u_char *);
128e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic int _gethtbyaddr(void *, void *, va_list);
129e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic int _gethtbyname(void *, void *, va_list);
130e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic struct hostent *_gethtbyname2(const char *, int);
131e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic int _dns_gethtbyaddr(void *, void *, va_list);
132e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic int _dns_gethtbyname(void *, void *, va_list);
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
134ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczakstatic struct hostent *gethostbyname_internal(const char *, int, res_state, unsigned, unsigned);
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const ns_src default_dns_files[] = {
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	{ NSSRC_FILES, 	NS_SUCCESS },
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	{ NSSRC_DNS, 	NS_SUCCESS },
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	{ 0, 0 }
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project};
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdprintf(const char *msg, res_state res, ...)
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(msg != NULL);
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (res->options & RES_DEBUG) {
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		int save = errno;
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		va_list ap;
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		va_start (ap, res);
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		vprintf(msg, ap);
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		va_end (ap);
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		errno = save;
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# define dprintf(msg, res, num) ((void)0) /*nada*/
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define BOUNDED_INCR(x) \
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	do { \
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += (x); \
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (cp > eom) { \
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			h_errno = NO_RECOVERY; \
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NULL; \
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} \
1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} while (/*CONSTCOND*/0)
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define BOUNDS_CHECK(ptr, count) \
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	do { \
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((ptr) + (count) > eom) { \
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			h_errno = NO_RECOVERY; \
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NULL; \
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} \
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} while (/*CONSTCOND*/0)
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct hostent *
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgetanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    res_state res)
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const HEADER *hp;
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const u_char *cp;
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n;
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const u_char *eom, *erdata;
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *bp, **ap, **hap, *ep;
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int type, class, ancount, qdcount;
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int haveanswer, had_error;
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int toobig = 0;
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char tbuf[MAXDNAME];
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const char *tname;
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int (*name_ok)(const char *);
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_static  rs = __res_get_static();
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(answer != NULL);
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(qname != NULL);
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tname = qname;
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_name = NULL;
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	eom = answer->buf + anslen;
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch (qtype) {
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case T_A:
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case T_AAAA:
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		name_ok = res_hnok;
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case T_PTR:
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		name_ok = res_dnok;
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	default:
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;	/* XXX should be abort(); */
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * find first satisfactory answer
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = &answer->hdr;
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ancount = ntohs(hp->ancount);
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	qdcount = ntohs(hp->qdcount);
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	bp = rs->hostbuf;
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ep = rs->hostbuf + sizeof rs->hostbuf;
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp = answer->buf;
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	BOUNDED_INCR(HFIXEDSZ);
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (qdcount != 1) {
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NO_RECOVERY;
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((n < 0) || !(*name_ok)(bp)) {
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NO_RECOVERY;
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	BOUNDED_INCR(n + QFIXEDSZ);
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (qtype == T_A || qtype == T_AAAA) {
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* res_send() has already verified that the query name is the
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * same as the one we sent; this just gets the expanded name
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * (i.e., with the succeeding search-domain tacked on).
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = strlen(bp) + 1;		/* for the \0 */
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (n >= MAXHOSTNAMELEN) {
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			h_errno = NO_RECOVERY;
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NULL;
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		rs->host.h_name = bp;
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		bp += n;
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* The qname can be abbreviated, but h_name is now absolute. */
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		qname = rs->host.h_name;
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ap = rs->host_aliases;
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*ap = NULL;
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_aliases = rs->host_aliases;
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hap = rs->h_addr_ptrs;
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*hap = NULL;
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_addr_list = rs->h_addr_ptrs;
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	haveanswer = 0;
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	had_error = 0;
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (ancount-- > 0 && cp < eom && !had_error) {
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((n < 0) || !(*name_ok)(bp)) {
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			had_error++;
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += n;			/* name */
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		type = _getshort(cp);
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 		cp += INT16SZ;			/* type */
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		class = _getshort(cp);
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 		cp += INT16SZ + INT32SZ;	/* class, TTL */
2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = _getshort(cp);
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;			/* len */
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		BOUNDS_CHECK(cp, n);
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		erdata = cp + n;
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (class != C_IN) {
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* XXX - debug? syslog? */
2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp += n;
2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;		/* XXX - had_error++ ? */
2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ap >= &rs->host_aliases[MAXALIASES-1])
2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((n < 0) || !(*name_ok)(tbuf)) {
2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				had_error++;
2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp += n;
2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (cp != erdata) {
2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NO_RECOVERY;
2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return NULL;
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Store alias. */
2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*ap++ = bp;
2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = strlen(bp) + 1;	/* for the \0 */
2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n >= MAXHOSTNAMELEN) {
2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				had_error++;
2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bp += n;
3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Get canonical name. */
3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = strlen(tbuf) + 1;	/* for the \0 */
3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				had_error++;
3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			strlcpy(bp, tbuf, (size_t)(ep - bp));
3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			rs->host.h_name = bp;
3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bp += n;
3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (qtype == T_PTR && type == T_CNAME) {
3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n < 0 || !res_dnok(tbuf)) {
3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				had_error++;
3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp += n;
3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (cp != erdata) {
3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NO_RECOVERY;
3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return NULL;
3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Get canonical name. */
3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = strlen(tbuf) + 1;	/* for the \0 */
3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				had_error++;
3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			strlcpy(bp, tbuf, (size_t)(ep - bp));
3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			tname = bp;
3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bp += n;
3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (type != qtype) {
3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (type != T_KEY && type != T_SIG)
3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				syslog(LOG_NOTICE|LOG_AUTH,
3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				       qname, p_class(C_IN), p_type(qtype),
3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				       p_type(type));
3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp += n;
3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;		/* XXX - had_error++ ? */
3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (type) {
3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_PTR:
3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (strcasecmp(tname, bp) != 0) {
3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				syslog(LOG_NOTICE|LOG_AUTH,
3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				       AskedForGot, qname, bp);
3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				cp += n;
3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;	/* XXX - had_error++ ? */
3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((n < 0) || !res_hnok(bp)) {
3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				had_error++;
3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if MULTI_PTRS_ARE_ALIASES
3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp += n;
3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (cp != erdata) {
3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NO_RECOVERY;
3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return NULL;
3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!haveanswer)
3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_name = bp;
3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (ap < &rs->host_aliases[MAXALIASES-1])
3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*ap++ = bp;
3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = -1;
3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n != -1) {
3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = strlen(bp) + 1;	/* for the \0 */
3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (n >= MAXHOSTNAMELEN) {
3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					had_error++;
3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				bp += n;
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			rs->host.h_name = bp;
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (res->options & RES_USE_INET6) {
3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				n = strlen(bp) + 1;	/* for the \0 */
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (n >= MAXHOSTNAMELEN) {
3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					had_error++;
3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				bp += n;
3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				map_v4v6_hostent(&rs->host, &bp, ep);
3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			h_errno = NETDB_SUCCESS;
3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return &rs->host;
3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_A:
3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case T_AAAA:
3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (strcasecmp(rs->host.h_name, bp) != 0) {
3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				syslog(LOG_NOTICE|LOG_AUTH,
3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				       AskedForGot, rs->host.h_name, bp);
3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				cp += n;
3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;	/* XXX - had_error++ ? */
3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n != rs->host.h_length) {
3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				cp += n;
4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (type == T_AAAA) {
4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				struct in6_addr in6;
4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				memcpy(&in6, cp, IN6ADDRSZ);
4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					cp += n;
4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					continue;
4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!haveanswer) {
4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				int nn;
4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_name = bp;
4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nn = strlen(bp) + 1;	/* for the \0 */
4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				bp += nn;
4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bp += sizeof(align) -
4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    (size_t)((u_long)bp % sizeof(align));
4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (bp + n >= &rs->hostbuf[sizeof rs->hostbuf]) {
4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				dprintf("size (%d) too big\n", res, n);
4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				had_error++;
4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (hap >= &rs->h_addr_ptrs[MAXADDRS-1]) {
4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (!toobig++)
4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					dprintf("Too many addresses (%d)\n",
4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project						res, MAXADDRS);
4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				cp += n;
4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				continue;
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			(void)memcpy(*hap++ = bp, cp, (size_t)n);
4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bp += n;
4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp += n;
4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (cp != erdata) {
4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NO_RECOVERY;
4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return NULL;
4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:
4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			abort();
4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!had_error)
4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			haveanswer++;
4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (haveanswer) {
4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*ap = NULL;
4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*hap = NULL;
4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Note: we sort even if host can take only one address
4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * in its return structures - should give it the "best"
4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * address in that case, not some random one
4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (res->nsort && haveanswer > 1 && qtype == T_A)
4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			addrsort(rs->h_addr_ptrs, haveanswer, res);
4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!rs->host.h_name) {
4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			n = strlen(qname) + 1;	/* for the \0 */
4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (n > ep - bp || n >= MAXHOSTNAMELEN)
4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				goto no_recovery;
4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			strlcpy(bp, qname, (size_t)(ep - bp));
4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			rs->host.h_name = bp;
4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bp += n;
4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (res->options & RES_USE_INET6)
4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			map_v4v6_hostent(&rs->host, &bp, ep);
4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_SUCCESS;
4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return &rs->host;
4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project no_recovery:
4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	h_errno = NO_RECOVERY;
4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return NULL;
4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t buflen,
4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    struct hostent**result, int *errorp)
4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        struct hostent *res;
4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        res = gethostbyname(name);
4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        *errorp = h_errno;
4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (res == NULL) {
4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                *result = NULL;
4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                return -1;
4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        memcpy(hp, res, sizeof *hp);
4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        *result = hp;
4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        return 0;
4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct hostent *
4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgethostbyname(const char *name)
4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *hp;
4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_state res = __res_get_state();
4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (res == NULL)
4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(name != NULL);
5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
503c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	/* try IPv6 first - if that fails do IPv4 */
5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (res->options & RES_USE_INET6) {
505ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak		hp = gethostbyname_internal(name, AF_INET6, res, NETID_UNSET, MARK_UNSET);
5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (hp) {
5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			__res_put_state(res);
5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return hp;
5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
511ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	hp = gethostbyname_internal(name, AF_INET, res, NETID_UNSET, MARK_UNSET);
5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	__res_put_state(res);
5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return hp;
5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct hostent *
5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgethostbyname2(const char *name, int af)
5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
519ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	return android_gethostbynamefornet(name, af, NETID_UNSET, MARK_UNSET);
520c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk}
521c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
522c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstruct hostent *
523ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczakandroid_gethostbynamefornet(const char *name, int af, unsigned netid, unsigned mark)
524c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk{
5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *hp;
5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_state res = __res_get_state();
5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (res == NULL)
5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
530ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	hp = gethostbyname_internal(name, af, res, netid, mark);
5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	__res_put_state(res);
5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return hp;
5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
535c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
536c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstatic FILE* android_open_proxy()
537c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk{
538c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	int sock;
539c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	const int one = 1;
540c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	struct sockaddr_un proxy_addr;
541c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
5421781ed7774671d5a750839650b9582ff0abbcf42Nick Kralevich	sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
543c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (sock < 0) {
544c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		return NULL;
545c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
546c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
547c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
548c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	memset(&proxy_addr, 0, sizeof(proxy_addr));
549c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	proxy_addr.sun_family = AF_UNIX;
550c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd", sizeof(proxy_addr.sun_path));
551c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (TEMP_FAILURE_RETRY(connect(sock,
552c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			(const struct sockaddr*) &proxy_addr,
553c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			sizeof(proxy_addr))) != 0) {
554c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		close(sock);
555c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		return NULL;
556c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
557c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
558c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	return fdopen(sock, "r+");
559c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk}
560c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
561c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstatic struct hostent *
562c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkandroid_read_hostent(FILE* proxy)
563c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk{
564c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	uint32_t size;
565c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	char buf[4];
566c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (fread(buf, 1, sizeof(buf), proxy) != sizeof(buf)) return NULL;
567c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
5682582f02a01cd56c56a4e6c9de4444a6ec937cc37Sreeram Ramachandran	/* This is reading serialized data from system/netd/server/DnsProxyListener.cpp
569c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	 * and changes here need to be matched there */
570c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	int result_code = strtol(buf, NULL, 10);
571c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (result_code != DnsProxyQueryResult) {
572c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		fread(&size, 1, sizeof(size), proxy);
573c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		return NULL;
574c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
575c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
576c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (fread(&size, 1, sizeof(size), proxy) != sizeof(size)) return NULL;
577c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	size = ntohl(size);
578c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	res_static rs = __res_get_static();
579c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	memset(&rs->host, 0, sizeof(rs->host));
580c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	char *ptr = rs->hostbuf;
581c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
582c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (fread(ptr, 1, size, proxy) != size) return NULL;
583c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	ptr += size;
584c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	rs->host.h_name = rs->hostbuf;
585c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
586c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	char **aliases = rs->host_aliases;
587c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	rs->host.h_aliases = rs->host_aliases;
588c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	while (1) {
589c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		if (fread(&size, 1, sizeof(size), proxy) != sizeof(size)) return NULL;
590c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		size = ntohl(size);
591c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
592c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		if (size == 0) {
593c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			*aliases = NULL;
594c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			break;
595c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		}
596c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		if (fread(ptr, 1, size, proxy) != size) return NULL;
597c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		*aliases++ = ptr;
598c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		ptr += size;
599c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
600c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
601c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (fread(&size, 1, sizeof(size), proxy) != sizeof(size)) return NULL;
602c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	rs->host.h_addrtype = ntohl(size);
603c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
604c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (fread(&size, 1, sizeof(size), proxy) != sizeof(size)) return NULL;
605c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	rs->host.h_length = ntohl(size);
606c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
607c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	char **addrs = rs->h_addr_ptrs;
608c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	rs->host.h_addr_list = rs->h_addr_ptrs;
609c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	while (1) {
610c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		if (fread(&size, 1, sizeof(size), proxy) != sizeof(size)) return NULL;
611c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		size = ntohl(size);
612c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		if (size == 0) {
613c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			*addrs = NULL;
614c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			break;
615c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		}
616c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		if (fread(ptr, 1, size, proxy) != size) return NULL;
617c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		*addrs++ = ptr;
618c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		ptr += size;
619c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
620c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
621c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	return &rs->host;
622c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk}
623c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
624c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct hostent *
626c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkgethostbyname_internal_real(const char *name, int af, res_state res)
6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const char *cp;
6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *bp, *ep;
6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int size;
6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *hp;
632c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	res_static rs = __res_get_static();
6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	static const ns_dtab dtab[] = {
6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		NS_FILES_CB(_gethtbyname, NULL)
6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		{ NSSRC_DNS, _dns_gethtbyname, NULL },	/* force -DHESIOD */
6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		{ 0, 0, 0 }
6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	};
6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(name != NULL);
6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch (af) {
6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET:
6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		size = INADDRSZ;
6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET6:
6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		size = IN6ADDRSZ;
6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	default:
6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_INTERNAL;
6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		errno = EAFNOSUPPORT;
6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
6531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_addrtype = af;
6561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_length = size;
6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * if there aren't any dots, it could be a user-level alias.
6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * this is also done in res_nquery() since we are not the only
6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * function that looks up host names.
6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!strchr(name, '.') && (cp = __hostalias(name)))
6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		name = cp;
6651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * disallow names consisting only of digits/dots, unless
6681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * they end in a dot.
6691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
6701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (isdigit((u_char) name[0]))
6711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (cp = name;; ++cp) {
6721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!*cp) {
6731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (*--cp == '.')
6741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
6751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
6761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * All-numeric, no dot at the end.
6771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * Fake up a hostent as if we'd actually
6781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * done a lookup.
6791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
6801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (inet_pton(af, name,
6811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    (char *)(void *)rs->host_addr) <= 0) {
6821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					h_errno = HOST_NOT_FOUND;
6831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					return NULL;
6841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
6851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				strncpy(rs->hostbuf, name, MAXDNAME);
6861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->hostbuf[MAXDNAME] = '\0';
6871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				bp = rs->hostbuf + MAXDNAME;
6881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ep = rs->hostbuf + sizeof rs->hostbuf;
6891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_name = rs->hostbuf;
6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_aliases = rs->host_aliases;
6911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host_aliases[0] = NULL;
6921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->h_addr_ptrs[0] = (char *)(void *)rs->host_addr;
6931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->h_addr_ptrs[1] = NULL;
6941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_addr_list = rs->h_addr_ptrs;
6951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (res->options & RES_USE_INET6)
6961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					map_v4v6_hostent(&rs->host, &bp, ep);
6971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NETDB_SUCCESS;
6981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return &rs->host;
6991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
7001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!isdigit((u_char) *cp) && *cp != '.')
7011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
7021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
7031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((isxdigit((u_char) name[0]) && strchr(name, ':') != NULL) ||
7041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    name[0] == ':')
7051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (cp = name;; ++cp) {
7061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!*cp) {
7071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (*--cp == '.')
7081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
7091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
7101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * All-IPv6-legal, no dot at the end.
7111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * Fake up a hostent as if we'd actually
7121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * done a lookup.
7131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
7141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (inet_pton(af, name,
7151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    (char *)(void *)rs->host_addr) <= 0) {
7161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					h_errno = HOST_NOT_FOUND;
7171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					return NULL;
7181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
7191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				strncpy(rs->hostbuf, name, MAXDNAME);
7201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->hostbuf[MAXDNAME] = '\0';
7211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				bp = rs->hostbuf + MAXDNAME;
7221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				ep = rs->hostbuf + sizeof rs->hostbuf;
7231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_name = rs->hostbuf;
7241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_aliases = rs->host_aliases;
7251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host_aliases[0] = NULL;
7261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->h_addr_ptrs[0] = (char *)(void *)rs->host_addr;
7271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->h_addr_ptrs[1] = NULL;
7281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				rs->host.h_addr_list = rs->h_addr_ptrs;
7291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NETDB_SUCCESS;
7301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return &rs->host;
7311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
7321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!isxdigit((u_char) *cp) && *cp != ':' && *cp != '.')
7331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
7341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
7351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
7361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = NULL;
7371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	h_errno = NETDB_INTERNAL;
7381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (nsdispatch(&hp, dtab, NSDB_HOSTS, "gethostbyname",
7391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    default_dns_files, name, strlen(name), af) != NS_SUCCESS) {
7401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
741c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
7421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	h_errno = NETDB_SUCCESS;
7431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return hp;
7441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
7451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
746c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
747c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk// very similar in proxy-ness to android_getaddrinfo_proxy
748c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstatic struct hostent *
749ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczakgethostbyname_internal(const char *name, int af, res_state res, unsigned netid, unsigned mark)
750c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk{
751c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	const char *cache_mode = getenv("ANDROID_DNS_MODE");
752c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	FILE* proxy = NULL;
753c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	struct hostent *result = NULL;
754c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
755c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) {
756ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak		res_setnetid(res, netid);
757c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker		res_setmark(res, mark);
758c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		return gethostbyname_internal_real(name, af, res);
759c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
760c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
761c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	proxy = android_open_proxy();
762a6b24b7afb79294e6b709ede11395f13370d67a0Nick Kralevich	if (proxy == NULL) goto exit;
763c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
7645240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen	netid = __netdClientDispatch.netIdForResolv(netid);
7655240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen
7662582f02a01cd56c56a4e6c9de4444a6ec937cc37Sreeram Ramachandran	/* This is writing to system/netd/server/DnsProxyListener.cpp and changes
767c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	 * here need to be matched there */
768ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	if (fprintf(proxy, "gethostbyname %u %s %d",
769ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak			netid,
770c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			name == NULL ? "^" : name,
771c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk			af) < 0) {
772c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		goto exit;
773c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
774c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
775c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (fputc(0, proxy) == EOF || fflush(proxy) != 0) {
776c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		goto exit;
777c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
778c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
779c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	result = android_read_hostent(proxy);
780c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
781c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkexit:
782c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (proxy != NULL) {
783c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		fclose(proxy);
784c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
785c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	return result;
786c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk}
787c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
788c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
789c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstruct hostent *
790ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczakandroid_gethostbyaddrfornet_proxy(const void *addr,
791ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak    socklen_t len, int af, unsigned netid)
792c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk{
793c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	struct hostent *result = NULL;
794c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	FILE* proxy = android_open_proxy();
795c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
796c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (proxy == NULL) goto exit;
797c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
798c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	char buf[INET6_ADDRSTRLEN];  //big enough for IPv4 and IPv6
799c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	const char * addrStr = inet_ntop(af, addr, buf, sizeof(buf));
800c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (addrStr == NULL) goto exit;
801c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
8025240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen	netid = __netdClientDispatch.netIdForResolv(netid);
8035240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen
804ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	if (fprintf(proxy, "gethostbyaddr %s %d %d %u",
805ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak			addrStr, len, af, netid) < 0) {
806c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		goto exit;
807c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
808c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
809c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (fputc(0, proxy) == EOF || fflush(proxy) != 0) {
810c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		goto exit;
811c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
812c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
813c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	result = android_read_hostent(proxy);
814c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkexit:
815c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (proxy != NULL) {
816c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk		fclose(proxy);
817c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
818c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	return result;
819c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk}
820c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
8211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct hostent *
822ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczakandroid_gethostbyaddrfornet_real(const void *addr,
823ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak    socklen_t len, int af, unsigned netid, unsigned mark)
8241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
8251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const u_char *uaddr = (const u_char *)addr;
8261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	socklen_t size;
8271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *hp;
8281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	static const ns_dtab dtab[] = {
8291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		NS_FILES_CB(_gethtbyaddr, NULL)
8301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		{ NSSRC_DNS, _dns_gethtbyaddr, NULL },	/* force -DHESIOD */
8311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		{ 0, 0, 0 }
8321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	};
8331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(addr != NULL);
8351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
8363e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes	if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
8373e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes	    (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr *)addr) ||
8383e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes	     IN6_IS_ADDR_SITELOCAL((const struct in6_addr *)addr))) {
8391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = HOST_NOT_FOUND;
8401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
8411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
8423e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes	if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
8433e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes	    (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)addr) ||
8443e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes	     IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)addr))) {
8451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* Unmap. */
8463e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes		uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
8473e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes		addr = uaddr;
8481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		af = AF_INET;
8493e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes		len = NS_INADDRSZ;
8501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
8511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch (af) {
8521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET:
8533e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes		size = NS_INADDRSZ;
8541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
8551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET6:
8563e5f0c9849bf09ad9a5b1999430aec796276d9f6Elliott Hughes		size = NS_IN6ADDRSZ;
8571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
8581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	default:
8591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		errno = EAFNOSUPPORT;
8601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_INTERNAL;
8611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
8621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
8631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (size != len) {
8641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		errno = EINVAL;
8651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_INTERNAL;
8661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
8671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
8681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = NULL;
8691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	h_errno = NETDB_INTERNAL;
8701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (nsdispatch(&hp, dtab, NSDB_HOSTS, "gethostbyaddr",
871ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak		default_dns_files, uaddr, len, af, netid, mark) != NS_SUCCESS)
8721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
8731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	h_errno = NETDB_SUCCESS;
8741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return hp;
8751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
8761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
877c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstruct hostent *
878ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczakandroid_gethostbyaddrfornet(const void *addr, socklen_t len, int af, unsigned netid, unsigned mark)
879c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk{
880c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	const char *cache_mode = getenv("ANDROID_DNS_MODE");
881c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
882c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
883ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak		return android_gethostbyaddrfornet_proxy(addr, len, af, netid);
884c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	} else {
885ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak		return android_gethostbyaddrfornet_real(addr,len, af, netid, mark);
886c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk	}
887c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk}
888c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
889c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkstruct hostent *
890c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falkgethostbyaddr(const void *addr, socklen_t len, int af)
891c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk{
892ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	return android_gethostbyaddrfornet(addr, len, af, NETID_UNSET, MARK_UNSET);
893c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk}
894c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
895c63e59039d28c352e3053bb81319e960c392dbd4Mattias Falk
896e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic void
8971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_sethtent(int f)
8981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
8991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    res_static  rs = __res_get_static();
9001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    if (rs == NULL) return;
9011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!rs->hostf)
9021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		rs->hostf = fopen(_PATH_HOSTS, "r" );
9031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else
9041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		rewind(rs->hostf);
9051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->stayopen = f;
9061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
9071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
908e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic void
9091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_endhtent(void)
9101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
9111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    res_static  rs = __res_get_static();
9121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    if (rs == NULL) return;
9131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (rs->hostf && !rs->stayopen) {
9151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		(void) fclose(rs->hostf);
9161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		rs->hostf = NULL;
9171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
9181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
9191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
920e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic struct hostent *
9211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_gethtent(void)
9221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
9231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *p;
9241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *cp, **q;
9251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int af, len;
9261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_static  rs = __res_get_static();
9271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!rs->hostf && !(rs->hostf = fopen(_PATH_HOSTS, "r" ))) {
9291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_INTERNAL;
9301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
9311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
9321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project again:
9331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(p = fgets(rs->hostbuf, sizeof rs->hostbuf, rs->hostf))) {
9341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = HOST_NOT_FOUND;
9351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
9361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
9371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*p == '#')
9381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto again;
9391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(cp = strpbrk(p, "#\n")))
9401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto again;
9411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*cp = '\0';
9421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!(cp = strpbrk(p, " \t")))
9431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto again;
9441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*cp++ = '\0';
9451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (inet_pton(AF_INET6, p, (char *)(void *)rs->host_addr) > 0) {
9461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		af = AF_INET6;
9471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		len = IN6ADDRSZ;
9481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else if (inet_pton(AF_INET, p, (char *)(void *)rs->host_addr) > 0) {
9491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		res_state res = __res_get_state();
9501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (res == NULL)
9511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NULL;
9521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (res->options & RES_USE_INET6) {
9531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			map_v4v6_address((char *)(void *)rs->host_addr,
9541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    (char *)(void *)rs->host_addr);
9551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			af = AF_INET6;
9561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			len = IN6ADDRSZ;
9571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} else {
9581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			af = AF_INET;
9591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			len = INADDRSZ;
9601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
9611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		__res_put_state(res);
9621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else {
9631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto again;
9641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
9651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* if this is not something we're looking for, skip it. */
9661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (rs->host.h_addrtype != 0 && rs->host.h_addrtype != af)
9671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto again;
9681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (rs->host.h_length != 0 && rs->host.h_length != len)
9691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		goto again;
9701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->h_addr_ptrs[0] = (char *)(void *)rs->host_addr;
9711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->h_addr_ptrs[1] = NULL;
9721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_addr_list = rs->h_addr_ptrs;
9731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_length = len;
9741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_addrtype = af;
9751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (*cp == ' ' || *cp == '\t')
9761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp++;
9771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_name = cp;
9781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	q = rs->host.h_aliases = rs->host_aliases;
9791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((cp = strpbrk(cp, " \t")) != NULL)
9801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*cp++ = '\0';
9811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (cp && *cp) {
9821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*cp == ' ' || *cp == '\t') {
9831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp++;
9841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
9851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
9861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (q < &rs->host_aliases[MAXALIASES - 1])
9871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*q++ = cp;
9881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((cp = strpbrk(cp, " \t")) != NULL)
9891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*cp++ = '\0';
9901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
9911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*q = NULL;
9921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	h_errno = NETDB_SUCCESS;
9931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return &rs->host;
9941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
9951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
9961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*ARGSUSED*/
9971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
9981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_gethtbyname(void *rv, void *cb_data, va_list ap)
9991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
10001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *hp;
10011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const char *name;
10021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int af;
10031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(rv != NULL);
10051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	name = va_arg(ap, char *);
10071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* NOSTRICT skip len */(void)va_arg(ap, int);
10081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	af = va_arg(ap, int);
10091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = NULL;
10111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if 0
10121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	{
10131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		res_state res = __res_get_state();
10141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (res == NULL)
10151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_NOTFOUND;
10161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (res->options & RES_USE_INET6)
10171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			hp = _gethtbyname2(name, AF_INET6);
10181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (hp==NULL)
10191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			hp = _gethtbyname2(name, AF_INET);
10201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		__res_put_state(res);
10211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
10221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
10231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = _gethtbyname2(name, af);
10241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
10251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*((struct hostent **)rv) = hp;
10261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (hp == NULL) {
10271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = HOST_NOT_FOUND;
10281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
10291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
10301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return NS_SUCCESS;
10311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
10321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1033e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic struct hostent *
10341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_gethtbyname2(const char *name, int af)
10351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
10361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *p;
10371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *tmpbuf, *ptr, **cp;
10381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int num;
10391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	size_t len;
10401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_static rs = __res_get_static();
10411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(name != NULL);
10431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_sethtent(rs->stayopen);
10451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ptr = tmpbuf = NULL;
10461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	num = 0;
10471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while ((p = _gethtent()) != NULL && num < MAXADDRS) {
10481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (p->h_addrtype != af)
10491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
10501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (strcasecmp(p->h_name, name) != 0) {
10511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for (cp = p->h_aliases; *cp != NULL; cp++)
10521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (strcasecmp(*cp, name) == 0)
10531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
10541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (*cp == NULL) continue;
10551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
10561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (num == 0) {
10581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			size_t bufsize;
10591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			char *src;
10601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			bufsize = strlen(p->h_name) + 2 +
10621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				  MAXADDRS * p->h_length +
10631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				  ALIGNBYTES;
10641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for (cp = p->h_aliases; *cp != NULL; cp++)
10651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				bufsize += strlen(*cp) + 1;
10661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((tmpbuf = malloc(bufsize)) == NULL) {
10681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NETDB_INTERNAL;
10691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return NULL;
10701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
10711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ptr = tmpbuf;
10731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			src = p->h_name;
10741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			while ((*ptr++ = *src++) != '\0');
10751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			for (cp = p->h_aliases; *cp != NULL; cp++) {
10761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				src = *cp;
10771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				while ((*ptr++ = *src++) != '\0');
10781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
10791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*ptr++ = '\0';
10801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ptr = (char *)(void *)ALIGN(ptr);
10821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
10831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		(void)memcpy(ptr, p->h_addr_list[0], (size_t)p->h_length);
10851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ptr += p->h_length;
10861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		num++;
10871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
10881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_endhtent();
10891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (num == 0) return NULL;
10901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
10911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	len = ptr - tmpbuf;
10921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (len > (sizeof(rs->hostbuf) - ALIGNBYTES)) {
10931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		free(tmpbuf);
10941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		errno = ENOSPC;
10951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_INTERNAL;
10961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NULL;
10971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
10981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ptr = memcpy((void *)ALIGN(rs->hostbuf), tmpbuf, len);
10991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	free(tmpbuf);
11001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_name = ptr;
11021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (*ptr++);
11031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp = rs->host_aliases;
11051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (*ptr) {
11061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*cp++ = ptr;
11071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		while (*ptr++);
11081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
11091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ptr++;
11101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*cp = NULL;
11111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ptr = (char *)(void *)ALIGN(ptr);
11131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp = rs->h_addr_ptrs;
11141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (num--) {
11151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*cp++ = ptr;
11161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ptr += rs->host.h_length;
11171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
11181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*cp = NULL;
11191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return &rs->host;
11211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
11221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*ARGSUSED*/
1124e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic int
11251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_gethtbyaddr(void *rv, void *cb_data, va_list ap)
11261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
11271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *p;
11281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const unsigned char *addr;
11291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int len, af;
11301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_static  rs = __res_get_static();
11311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(rv != NULL);
11331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	addr = va_arg(ap, unsigned char *);
11351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	len = va_arg(ap, int);
11361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	af = va_arg(ap, int);
11371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_length = len;
11391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_addrtype = af;
11401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_sethtent(rs->stayopen);
11421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while ((p = _gethtent()) != NULL)
11431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (p->h_addrtype == af && !memcmp(p->h_addr, addr,
11441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    (size_t)len))
11451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
11461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	_endhtent();
11471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*((struct hostent **)rv) = p;
11481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (p==NULL) {
11491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = HOST_NOT_FOUND;
11501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
11511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
11521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return NS_SUCCESS;
11531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
11541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
11561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectmap_v4v6_address(const char *src, char *dst)
11571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
11581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_char *p = (u_char *)dst;
11591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char tmp[INADDRSZ];
11601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i;
11611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(src != NULL);
11631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(dst != NULL);
11641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Stash a temporary copy so our caller can update in place. */
11661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(void)memcpy(tmp, src, INADDRSZ);
11671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Mark this ipv6 addr as a mapped ipv4. */
11681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (i = 0; i < 10; i++)
11691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*p++ = 0x00;
11701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*p++ = 0xff;
11711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*p++ = 0xff;
11721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Retrieve the saved copy and we're done. */
11731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(void)memcpy((void *)p, tmp, INADDRSZ);
11741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
11751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
11771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectmap_v4v6_hostent(struct hostent *hp, char **bpp, char *ep)
11781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
11791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char **ap;
11801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(hp != NULL);
11821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(bpp != NULL);
11831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(ep != NULL);
11841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
11861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return;
11871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->h_addrtype = AF_INET6;
11881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->h_length = IN6ADDRSZ;
11891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (ap = hp->h_addr_list; *ap; ap++) {
11901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		int i = sizeof(align) - (size_t)((u_long)*bpp % sizeof(align));
11911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ep - *bpp < (i + IN6ADDRSZ)) {
11931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* Out of memory.  Truncate address list here.  XXX */
11941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			*ap = NULL;
11951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return;
11961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
11971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*bpp += i;
11981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		map_v4v6_address(*ap, *bpp);
11991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*ap = *bpp;
12001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*bpp += IN6ADDRSZ;
12011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
12031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
12051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectaddrsort(char **ap, int num, res_state res)
12061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
12071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i, j;
12081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char **p;
12091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	short aval[MAXADDRS];
12101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int needsort = 0;
12111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(ap != NULL);
12131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	p = ap;
12151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (i = 0; i < num; i++, p++) {
12161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    for (j = 0 ; (unsigned)j < res->nsort; j++)
12171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (res->sort_list[j].addr.s_addr ==
12181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    (((struct in_addr *)(void *)(*p))->s_addr &
12191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    res->sort_list[j].mask))
12201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
12211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    aval[i] = j;
12221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    if (needsort == 0 && i > 0 && j < aval[i-1])
12231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		needsort = i;
12241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!needsort)
12261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    return;
12271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (needsort < num) {
12291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    for (j = needsort - 1; j >= 0; j--) {
12301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (aval[j] > aval[j+1]) {
12311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    char *hp;
12321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    i = aval[j];
12341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    aval[j] = aval[j+1];
12351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    aval[j+1] = i;
12361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    hp = ap[j];
12381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    ap[j] = ap[j+1];
12391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    ap[j+1] = hp;
12401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} else
12411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    break;
12421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    }
12431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    needsort++;
12441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
12461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct hostent *
12481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgethostent(void)
12491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
12501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    res_static  rs = __res_get_static();
12511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_addrtype = 0;
12521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->host.h_length = 0;
12531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return _gethtent();
12541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
12551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*ARGSUSED*/
1257e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic int
12581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_dns_gethtbyname(void *rv, void *cb_data, va_list ap)
12591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
12601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	querybuf *buf;
12611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n, type;
12621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *hp;
12631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const char *name;
12641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int af;
12651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_state res;
12661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(rv != NULL);
12681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	name = va_arg(ap, char *);
12701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* NOSTRICT skip len */(void)va_arg(ap, int);
12711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	af = va_arg(ap, int);
12721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch (af) {
12741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET:
12751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		type = T_A;
12761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
12771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET6:
12781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		type = T_AAAA;
12791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
12801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	default:
12811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_UNAVAIL;
12821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	buf = malloc(sizeof(*buf));
12841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (buf == NULL) {
12851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_INTERNAL;
12861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
12871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res = __res_get_state();
12891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (res == NULL) {
12901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		free(buf);
12911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
12921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
12931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = res_nsearch(res, name, C_IN, type, buf->buf, sizeof(buf->buf));
12941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (n < 0) {
12951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		free(buf);
12961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		dprintf("res_nsearch failed (%d)\n", res, n);
12971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		__res_put_state(res);
12981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
12991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
13001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = getanswer(buf, n, name, type, res);
13011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	free(buf);
13021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	__res_put_state(res);
13031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (hp == NULL)
13041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (h_errno) {
13051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case HOST_NOT_FOUND:
13061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_NOTFOUND;
13071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TRY_AGAIN:
13081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_TRYAGAIN;
13091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:
13101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_UNAVAIL;
13111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
13121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*((struct hostent **)rv) = hp;
13131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return NS_SUCCESS;
13141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
13151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*ARGSUSED*/
1317e5c35e075fad5b5c143971c4401a360f6eaf5470Jim Huangstatic int
13181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_dns_gethtbyaddr(void *rv, void	*cb_data, va_list ap)
13191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
13201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char qbuf[MAXDNAME + 1], *qp, *ep;
13211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n;
13221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	querybuf *buf;
13231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct hostent *hp;
13241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const unsigned char *uaddr;
13251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int len, af, advance;
13261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_state res;
1327ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	unsigned netid, mark;
13281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res_static rs = __res_get_static();
13291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	assert(rv != NULL);
13311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	uaddr = va_arg(ap, unsigned char *);
13331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	len = va_arg(ap, int);
13341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	af = va_arg(ap, int);
1335ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	netid = va_arg(ap, unsigned);
1336ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	mark = va_arg(ap, unsigned);
13371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch (af) {
13391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET:
13401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		(void)snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa",
13411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    (uaddr[3] & 0xff), (uaddr[2] & 0xff),
13421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    (uaddr[1] & 0xff), (uaddr[0] & 0xff));
13431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
13441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case AF_INET6:
13461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		qp = qbuf;
13471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ep = qbuf + sizeof(qbuf) - 1;
13481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (n = IN6ADDRSZ - 1; n >= 0; n--) {
13491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			advance = snprintf(qp, (size_t)(ep - qp), "%x.%x.",
13501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    uaddr[n] & 0xf,
13511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    ((unsigned int)uaddr[n] >> 4) & 0xf);
13521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (advance > 0 && qp + advance < ep)
13531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				qp += advance;
13541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else {
13551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				h_errno = NETDB_INTERNAL;
13561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return NS_NOTFOUND;
13571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
13581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
13591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) {
13601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			h_errno = NETDB_INTERNAL;
13611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_NOTFOUND;
13621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
13631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
13641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	default:
13651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		abort();
13661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
13671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
13681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	buf = malloc(sizeof(*buf));
13691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (buf == NULL) {
13701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		h_errno = NETDB_INTERNAL;
13711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
13721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
13731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	res = __res_get_state();
13741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (res == NULL) {
13751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		free(buf);
13761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
13771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1378ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak	res_setnetid(res, netid);
1379c39214e0ac49b9f7de6fd9989331145c6e1cd584Chad Brubaker	res_setmark(res, mark);
13801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf, sizeof(buf->buf));
13811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (n < 0) {
13821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		free(buf);
13831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		dprintf("res_nquery failed (%d)\n", res, n);
13841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		__res_put_state(res);
13851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return NS_NOTFOUND;
13861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
13871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = getanswer(buf, n, qbuf, T_PTR, res);
13881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	free(buf);
13891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (hp == NULL) {
13901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		__res_put_state(res);
13911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (h_errno) {
13921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case HOST_NOT_FOUND:
13931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_NOTFOUND;
13941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case TRY_AGAIN:
13951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_TRYAGAIN;
13961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:
13971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return NS_UNAVAIL;
13981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
13991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
14001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->h_addrtype = af;
14011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->h_length = len;
14021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(void)memcpy(rs->host_addr, uaddr, (size_t)len);
14031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->h_addr_ptrs[0] = (char *)(void *)rs->host_addr;
14041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	rs->h_addr_ptrs[1] = NULL;
14051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (af == AF_INET && (res->options & RES_USE_INET6)) {
14061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		map_v4v6_address((char *)(void *)rs->host_addr,
14071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    (char *)(void *)rs->host_addr);
14081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		hp->h_addrtype = AF_INET6;
14091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		hp->h_length = IN6ADDRSZ;
14101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
14111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
14121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	__res_put_state(res);
14131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*((struct hostent **)rv) = hp;
14141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	h_errno = NETDB_SUCCESS;
14151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return NS_SUCCESS;
14161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1417