Home | History | Annotate | Line # | Download | only in net
gethnamaddr.c revision 1.42.2.13
      1  1.42.2.13      tron /*	$NetBSD: gethnamaddr.c,v 1.42.2.13 2004/08/22 14:28:03 tron Exp $	*/
      2        1.2       mrg 
      3        1.1       mrg /*
      4        1.1       mrg  * ++Copyright++ 1985, 1988, 1993
      5        1.1       mrg  * -
      6        1.1       mrg  * Copyright (c) 1985, 1988, 1993
      7        1.1       mrg  *    The Regents of the University of California.  All rights reserved.
      8        1.1       mrg  *
      9        1.1       mrg  * Redistribution and use in source and binary forms, with or without
     10        1.1       mrg  * modification, are permitted provided that the following conditions
     11        1.1       mrg  * are met:
     12        1.1       mrg  * 1. Redistributions of source code must retain the above copyright
     13        1.1       mrg  *    notice, this list of conditions and the following disclaimer.
     14        1.1       mrg  * 2. Redistributions in binary form must reproduce the above copyright
     15        1.1       mrg  *    notice, this list of conditions and the following disclaimer in the
     16        1.1       mrg  *    documentation and/or other materials provided with the distribution.
     17        1.1       mrg  * 3. All advertising materials mentioning features or use of this software
     18        1.1       mrg  *    must display the following acknowledgement:
     19        1.1       mrg  * 	This product includes software developed by the University of
     20        1.1       mrg  * 	California, Berkeley and its contributors.
     21        1.1       mrg  * 4. Neither the name of the University nor the names of its contributors
     22        1.1       mrg  *    may be used to endorse or promote products derived from this software
     23        1.1       mrg  *    without specific prior written permission.
     24        1.1       mrg  *
     25        1.1       mrg  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     26        1.1       mrg  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27        1.1       mrg  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28        1.1       mrg  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     29        1.1       mrg  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30        1.1       mrg  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31        1.1       mrg  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32        1.1       mrg  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33        1.1       mrg  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34        1.1       mrg  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35        1.1       mrg  * SUCH DAMAGE.
     36        1.1       mrg  * -
     37        1.1       mrg  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
     38        1.1       mrg  *
     39        1.1       mrg  * Permission to use, copy, modify, and distribute this software for any
     40        1.1       mrg  * purpose with or without fee is hereby granted, provided that the above
     41        1.1       mrg  * copyright notice and this permission notice appear in all copies, and that
     42        1.1       mrg  * the name of Digital Equipment Corporation not be used in advertising or
     43        1.1       mrg  * publicity pertaining to distribution of the document or software without
     44        1.1       mrg  * specific, written prior permission.
     45        1.1       mrg  *
     46        1.1       mrg  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
     47        1.1       mrg  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
     48        1.1       mrg  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
     49        1.1       mrg  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     50        1.1       mrg  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
     51        1.1       mrg  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
     52        1.1       mrg  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     53        1.1       mrg  * SOFTWARE.
     54        1.1       mrg  * -
     55        1.1       mrg  * --Copyright--
     56        1.1       mrg  */
     57        1.1       mrg 
     58        1.2       mrg #include <sys/cdefs.h>
     59        1.1       mrg #if defined(LIBC_SCCS) && !defined(lint)
     60        1.2       mrg #if 0
     61        1.1       mrg static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93";
     62        1.4     perry static char rcsid[] = "Id: gethnamaddr.c,v 8.21 1997/06/01 20:34:37 vixie Exp ";
     63        1.2       mrg #else
     64  1.42.2.13      tron __RCSID("$NetBSD: gethnamaddr.c,v 1.42.2.13 2004/08/22 14:28:03 tron Exp $");
     65        1.2       mrg #endif
     66        1.1       mrg #endif /* LIBC_SCCS and not lint */
     67        1.1       mrg 
     68        1.6    kleink #if defined(_LIBC)
     69        1.3   thorpej #include "namespace.h"
     70        1.6    kleink #endif
     71        1.1       mrg #include <sys/param.h>
     72        1.1       mrg #include <sys/socket.h>
     73        1.1       mrg #include <netinet/in.h>
     74        1.1       mrg #include <arpa/inet.h>
     75        1.1       mrg #include <arpa/nameser.h>
     76        1.1       mrg 
     77       1.25     lukem #include <assert.h>
     78       1.25     lukem #include <ctype.h>
     79       1.25     lukem #include <errno.h>
     80        1.1       mrg #include <netdb.h>
     81        1.1       mrg #include <resolv.h>
     82       1.25     lukem #include <stdio.h>
     83        1.1       mrg #include <syslog.h>
     84       1.15     lukem 
     85       1.15     lukem #ifdef __STDC__
     86       1.15     lukem #include <stdarg.h>
     87       1.15     lukem #else
     88       1.15     lukem #include <varargs.h>
     89       1.15     lukem #endif
     90        1.1       mrg 
     91        1.1       mrg #ifndef LOG_AUTH
     92        1.1       mrg # define LOG_AUTH 0
     93        1.1       mrg #endif
     94        1.1       mrg 
     95        1.1       mrg #define MULTI_PTRS_ARE_ALIASES 1	/* XXX - experimental */
     96        1.1       mrg 
     97        1.9     lukem #include <nsswitch.h>
     98        1.2       mrg #include <stdlib.h>
     99        1.2       mrg #include <string.h>
    100        1.1       mrg 
    101        1.2       mrg #ifdef YP
    102        1.2       mrg #include <rpc/rpc.h>
    103        1.2       mrg #include <rpcsvc/yp_prot.h>
    104        1.2       mrg #include <rpcsvc/ypclnt.h>
    105        1.5    kleink #endif
    106        1.5    kleink 
    107        1.6    kleink #if defined(_LIBC) && defined(__weak_alias)
    108       1.29   mycroft __weak_alias(gethostbyaddr,_gethostbyaddr)
    109       1.29   mycroft __weak_alias(gethostbyname,_gethostbyname)
    110        1.1       mrg #endif
    111        1.1       mrg 
    112        1.1       mrg #define	MAXALIASES	35
    113        1.1       mrg #define	MAXADDRS	35
    114        1.1       mrg 
    115        1.1       mrg static const char AskedForGot[] =
    116        1.1       mrg 			  "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
    117        1.1       mrg 
    118        1.1       mrg static char *h_addr_ptrs[MAXADDRS + 1];
    119        1.1       mrg 
    120        1.2       mrg #ifdef YP
    121        1.2       mrg static char *__ypdomain;
    122        1.2       mrg #endif
    123        1.2       mrg 
    124        1.1       mrg static struct hostent host;
    125        1.1       mrg static char *host_aliases[MAXALIASES];
    126        1.1       mrg static char hostbuf[8*1024];
    127       1.23  christos static u_int32_t host_addr[16 / sizeof(u_int32_t)];	/* IPv4 or IPv6 */
    128        1.1       mrg static FILE *hostf = NULL;
    129        1.1       mrg static int stayopen = 0;
    130        1.1       mrg 
    131   1.42.2.9     lukem #define	MAXPACKET	(64*1024)
    132        1.1       mrg 
    133        1.1       mrg typedef union {
    134        1.1       mrg     HEADER hdr;
    135        1.1       mrg     u_char buf[MAXPACKET];
    136        1.1       mrg } querybuf;
    137        1.1       mrg 
    138        1.1       mrg typedef union {
    139        1.1       mrg     int32_t al;
    140        1.1       mrg     char ac;
    141        1.1       mrg } align;
    142        1.1       mrg 
    143        1.1       mrg #ifdef DEBUG
    144       1.38  sommerfe static void dprintf __P((char *, ...))
    145       1.38  sommerfe 	__attribute__((__format__(__printf__, 1, 2)));
    146        1.2       mrg #endif
    147        1.2       mrg static struct hostent *getanswer __P((const querybuf *, int,
    148        1.2       mrg     const char *, int));
    149        1.2       mrg static void map_v4v6_address __P((const char *, char *));
    150   1.42.2.2     lukem static void map_v4v6_hostent __P((struct hostent *, char **, char *));
    151        1.2       mrg #ifdef RESOLVSORT
    152        1.2       mrg static void addrsort __P((char **, int));
    153        1.2       mrg #endif
    154        1.2       mrg 
    155        1.2       mrg void _sethtent __P((int));
    156        1.2       mrg void _endhtent __P((void));
    157        1.2       mrg struct hostent *_gethtent __P((void));
    158        1.2       mrg struct hostent *_gethtbyname2 __P((const char *, int));
    159        1.2       mrg void ht_sethostent __P((int));
    160        1.2       mrg void ht_endhostent __P((void));
    161        1.2       mrg struct hostent *ht_gethostbyname __P((char *));
    162        1.2       mrg struct hostent *ht_gethostbyaddr __P((const char *, int, int ));
    163        1.2       mrg void dns_service __P((void));
    164       1.39  christos #undef dn_skipname
    165        1.2       mrg int dn_skipname __P((const u_char *, const u_char *));
    166        1.9     lukem int _gethtbyaddr __P((void *, void *, va_list));
    167        1.9     lukem int _gethtbyname __P((void *, void *, va_list));
    168        1.9     lukem int _dns_gethtbyaddr __P((void *, void *, va_list));
    169        1.9     lukem int _dns_gethtbyname __P((void *, void *, va_list));
    170        1.2       mrg #ifdef YP
    171        1.9     lukem struct hostent *_yphostent __P((char *, int));
    172        1.9     lukem int _yp_gethtbyaddr __P((void *, void *, va_list));
    173        1.9     lukem int _yp_gethtbyname __P((void *, void *, va_list));
    174        1.2       mrg #endif
    175        1.2       mrg 
    176       1.12     lukem static const ns_src default_dns_files[] = {
    177       1.27     lukem 	{ NSSRC_FILES, 	NS_SUCCESS },
    178       1.11     lukem 	{ NSSRC_DNS, 	NS_SUCCESS },
    179       1.11     lukem 	{ 0 }
    180       1.11     lukem };
    181       1.11     lukem 
    182        1.2       mrg 
    183        1.2       mrg #ifdef DEBUG
    184        1.1       mrg static void
    185       1.38  sommerfe dprintf(char *msg, ...)
    186        1.1       mrg {
    187       1.25     lukem 	_DIAGASSERT(msg != NULL);
    188       1.25     lukem 
    189        1.1       mrg 	if (_res.options & RES_DEBUG) {
    190        1.1       mrg 		int save = errno;
    191       1.38  sommerfe 		va_list ap;
    192        1.1       mrg 
    193       1.38  sommerfe 		va_start (ap, msg);
    194       1.38  sommerfe 		vprintf(msg, ap);
    195       1.38  sommerfe 		va_end (ap);
    196       1.38  sommerfe 
    197        1.1       mrg 		errno = save;
    198        1.1       mrg 	}
    199        1.1       mrg }
    200        1.1       mrg #else
    201        1.1       mrg # define dprintf(msg, num) /*nada*/
    202        1.1       mrg #endif
    203        1.1       mrg 
    204       1.32    itojun #define BOUNDED_INCR(x) \
    205       1.32    itojun 	do { \
    206  1.42.2.12      tron 		cp += (x); \
    207  1.42.2.12      tron 		if (cp > eom) { \
    208       1.32    itojun 			h_errno = NO_RECOVERY; \
    209       1.32    itojun 			return (NULL); \
    210       1.32    itojun 		} \
    211       1.34  christos 	} while (/*CONSTCOND*/0)
    212       1.32    itojun 
    213       1.32    itojun #define BOUNDS_CHECK(ptr, count) \
    214       1.32    itojun 	do { \
    215  1.42.2.12      tron 		if ((ptr) + (count) > eom) { \
    216       1.32    itojun 			h_errno = NO_RECOVERY; \
    217       1.32    itojun 			return (NULL); \
    218       1.32    itojun 		} \
    219       1.34  christos 	} while (/*CONSTCOND*/0)
    220       1.32    itojun 
    221        1.1       mrg static struct hostent *
    222        1.1       mrg getanswer(answer, anslen, qname, qtype)
    223        1.1       mrg 	const querybuf *answer;
    224        1.1       mrg 	int anslen;
    225        1.1       mrg 	const char *qname;
    226        1.1       mrg 	int qtype;
    227        1.1       mrg {
    228       1.25     lukem 	const HEADER *hp;
    229       1.25     lukem 	const u_char *cp;
    230       1.25     lukem 	int n;
    231       1.32    itojun 	const u_char *eom, *erdata;
    232   1.42.2.2     lukem 	char *bp, **ap, **hap, *ep;
    233   1.42.2.2     lukem 	int type, class, ancount, qdcount;
    234        1.1       mrg 	int haveanswer, had_error;
    235        1.1       mrg 	int toobig = 0;
    236        1.1       mrg 	char tbuf[MAXDNAME];
    237        1.1       mrg 	const char *tname;
    238        1.1       mrg 	int (*name_ok) __P((const char *));
    239        1.1       mrg 
    240       1.25     lukem 	_DIAGASSERT(answer != NULL);
    241       1.25     lukem 	_DIAGASSERT(qname != NULL);
    242       1.25     lukem 
    243        1.1       mrg 	tname = qname;
    244        1.1       mrg 	host.h_name = NULL;
    245        1.1       mrg 	eom = answer->buf + anslen;
    246        1.1       mrg 	switch (qtype) {
    247        1.1       mrg 	case T_A:
    248        1.1       mrg 	case T_AAAA:
    249        1.1       mrg 		name_ok = res_hnok;
    250        1.1       mrg 		break;
    251        1.1       mrg 	case T_PTR:
    252        1.1       mrg 		name_ok = res_dnok;
    253        1.1       mrg 		break;
    254        1.1       mrg 	default:
    255        1.1       mrg 		return (NULL);	/* XXX should be abort(); */
    256        1.1       mrg 	}
    257        1.1       mrg 	/*
    258        1.1       mrg 	 * find first satisfactory answer
    259        1.1       mrg 	 */
    260        1.1       mrg 	hp = &answer->hdr;
    261        1.1       mrg 	ancount = ntohs(hp->ancount);
    262        1.1       mrg 	qdcount = ntohs(hp->qdcount);
    263        1.1       mrg 	bp = hostbuf;
    264   1.42.2.2     lukem 	ep = hostbuf + sizeof hostbuf;
    265       1.32    itojun 	cp = answer->buf;
    266       1.32    itojun 	BOUNDED_INCR(HFIXEDSZ);
    267        1.1       mrg 	if (qdcount != 1) {
    268        1.1       mrg 		h_errno = NO_RECOVERY;
    269        1.1       mrg 		return (NULL);
    270        1.1       mrg 	}
    271   1.42.2.2     lukem 	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
    272        1.1       mrg 	if ((n < 0) || !(*name_ok)(bp)) {
    273        1.1       mrg 		h_errno = NO_RECOVERY;
    274        1.1       mrg 		return (NULL);
    275        1.1       mrg 	}
    276       1.32    itojun 	BOUNDED_INCR(n + QFIXEDSZ);
    277        1.1       mrg 	if (qtype == T_A || qtype == T_AAAA) {
    278        1.1       mrg 		/* res_send() has already verified that the query name is the
    279        1.1       mrg 		 * same as the one we sent; this just gets the expanded name
    280        1.1       mrg 		 * (i.e., with the succeeding search-domain tacked on).
    281        1.1       mrg 		 */
    282        1.1       mrg 		n = strlen(bp) + 1;		/* for the \0 */
    283        1.1       mrg 		if (n >= MAXHOSTNAMELEN) {
    284        1.1       mrg 			h_errno = NO_RECOVERY;
    285        1.1       mrg 			return (NULL);
    286        1.1       mrg 		}
    287        1.1       mrg 		host.h_name = bp;
    288        1.1       mrg 		bp += n;
    289        1.1       mrg 		/* The qname can be abbreviated, but h_name is now absolute. */
    290        1.1       mrg 		qname = host.h_name;
    291        1.1       mrg 	}
    292        1.1       mrg 	ap = host_aliases;
    293        1.1       mrg 	*ap = NULL;
    294        1.1       mrg 	host.h_aliases = host_aliases;
    295        1.1       mrg 	hap = h_addr_ptrs;
    296        1.1       mrg 	*hap = NULL;
    297        1.1       mrg 	host.h_addr_list = h_addr_ptrs;
    298        1.1       mrg 	haveanswer = 0;
    299        1.1       mrg 	had_error = 0;
    300        1.1       mrg 	while (ancount-- > 0 && cp < eom && !had_error) {
    301   1.42.2.2     lukem 		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
    302        1.1       mrg 		if ((n < 0) || !(*name_ok)(bp)) {
    303        1.1       mrg 			had_error++;
    304        1.1       mrg 			continue;
    305        1.1       mrg 		}
    306        1.1       mrg 		cp += n;			/* name */
    307       1.32    itojun 		BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
    308        1.1       mrg 		type = _getshort(cp);
    309        1.1       mrg  		cp += INT16SZ;			/* type */
    310        1.1       mrg 		class = _getshort(cp);
    311        1.1       mrg  		cp += INT16SZ + INT32SZ;	/* class, TTL */
    312        1.1       mrg 		n = _getshort(cp);
    313        1.1       mrg 		cp += INT16SZ;			/* len */
    314       1.32    itojun 		BOUNDS_CHECK(cp, n);
    315       1.32    itojun 		erdata = cp + n;
    316        1.1       mrg 		if (class != C_IN) {
    317        1.1       mrg 			/* XXX - debug? syslog? */
    318        1.1       mrg 			cp += n;
    319        1.1       mrg 			continue;		/* XXX - had_error++ ? */
    320        1.1       mrg 		}
    321        1.1       mrg 		if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
    322        1.1       mrg 			if (ap >= &host_aliases[MAXALIASES-1])
    323        1.1       mrg 				continue;
    324        1.1       mrg 			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
    325        1.1       mrg 			if ((n < 0) || !(*name_ok)(tbuf)) {
    326        1.1       mrg 				had_error++;
    327        1.1       mrg 				continue;
    328        1.1       mrg 			}
    329        1.1       mrg 			cp += n;
    330       1.32    itojun 			if (cp != erdata) {
    331       1.32    itojun 				h_errno = NO_RECOVERY;
    332       1.32    itojun 				return (NULL);
    333       1.32    itojun 			}
    334        1.1       mrg 			/* Store alias. */
    335        1.1       mrg 			*ap++ = bp;
    336        1.1       mrg 			n = strlen(bp) + 1;	/* for the \0 */
    337        1.1       mrg 			if (n >= MAXHOSTNAMELEN) {
    338        1.1       mrg 				had_error++;
    339        1.1       mrg 				continue;
    340        1.1       mrg 			}
    341        1.1       mrg 			bp += n;
    342        1.1       mrg 			/* Get canonical name. */
    343        1.1       mrg 			n = strlen(tbuf) + 1;	/* for the \0 */
    344   1.42.2.2     lukem 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
    345        1.1       mrg 				had_error++;
    346        1.1       mrg 				continue;
    347        1.1       mrg 			}
    348        1.1       mrg 			strcpy(bp, tbuf);
    349        1.1       mrg 			host.h_name = bp;
    350        1.1       mrg 			bp += n;
    351        1.1       mrg 			continue;
    352        1.1       mrg 		}
    353        1.1       mrg 		if (qtype == T_PTR && type == T_CNAME) {
    354        1.1       mrg 			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
    355        1.1       mrg 			if (n < 0 || !res_dnok(tbuf)) {
    356        1.1       mrg 				had_error++;
    357        1.1       mrg 				continue;
    358        1.1       mrg 			}
    359        1.1       mrg 			cp += n;
    360       1.32    itojun 			if (cp != erdata) {
    361       1.32    itojun 				h_errno = NO_RECOVERY;
    362       1.32    itojun 				return (NULL);
    363       1.32    itojun 			}
    364        1.1       mrg 			/* Get canonical name. */
    365        1.1       mrg 			n = strlen(tbuf) + 1;	/* for the \0 */
    366   1.42.2.2     lukem 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
    367        1.1       mrg 				had_error++;
    368        1.1       mrg 				continue;
    369        1.1       mrg 			}
    370        1.1       mrg 			strcpy(bp, tbuf);
    371        1.1       mrg 			tname = bp;
    372        1.1       mrg 			bp += n;
    373        1.1       mrg 			continue;
    374        1.1       mrg 		}
    375        1.1       mrg 		if (type != qtype) {
    376       1.28     assar 			if (type != T_KEY && type != T_SIG)
    377       1.28     assar 				syslog(LOG_NOTICE|LOG_AUTH,
    378        1.1       mrg 	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
    379       1.28     assar 				       qname, p_class(C_IN), p_type(qtype),
    380       1.28     assar 				       p_type(type));
    381        1.1       mrg 			cp += n;
    382        1.1       mrg 			continue;		/* XXX - had_error++ ? */
    383        1.1       mrg 		}
    384        1.1       mrg 		switch (type) {
    385        1.1       mrg 		case T_PTR:
    386        1.1       mrg 			if (strcasecmp(tname, bp) != 0) {
    387        1.1       mrg 				syslog(LOG_NOTICE|LOG_AUTH,
    388        1.1       mrg 				       AskedForGot, qname, bp);
    389        1.1       mrg 				cp += n;
    390        1.1       mrg 				continue;	/* XXX - had_error++ ? */
    391        1.1       mrg 			}
    392   1.42.2.2     lukem 			n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
    393        1.1       mrg 			if ((n < 0) || !res_hnok(bp)) {
    394        1.1       mrg 				had_error++;
    395        1.1       mrg 				break;
    396        1.1       mrg 			}
    397        1.1       mrg #if MULTI_PTRS_ARE_ALIASES
    398        1.1       mrg 			cp += n;
    399       1.32    itojun 			if (cp != erdata) {
    400       1.32    itojun 				h_errno = NO_RECOVERY;
    401       1.32    itojun 				return (NULL);
    402       1.32    itojun 			}
    403        1.1       mrg 			if (!haveanswer)
    404        1.1       mrg 				host.h_name = bp;
    405        1.1       mrg 			else if (ap < &host_aliases[MAXALIASES-1])
    406        1.1       mrg 				*ap++ = bp;
    407        1.1       mrg 			else
    408        1.1       mrg 				n = -1;
    409        1.1       mrg 			if (n != -1) {
    410        1.1       mrg 				n = strlen(bp) + 1;	/* for the \0 */
    411        1.1       mrg 				if (n >= MAXHOSTNAMELEN) {
    412        1.1       mrg 					had_error++;
    413        1.1       mrg 					break;
    414        1.1       mrg 				}
    415        1.1       mrg 				bp += n;
    416        1.1       mrg 			}
    417        1.1       mrg 			break;
    418        1.1       mrg #else
    419        1.1       mrg 			host.h_name = bp;
    420        1.1       mrg 			if (_res.options & RES_USE_INET6) {
    421        1.1       mrg 				n = strlen(bp) + 1;	/* for the \0 */
    422        1.1       mrg 				if (n >= MAXHOSTNAMELEN) {
    423        1.1       mrg 					had_error++;
    424        1.1       mrg 					break;
    425        1.1       mrg 				}
    426        1.1       mrg 				bp += n;
    427   1.42.2.2     lukem 				map_v4v6_hostent(&host, &bp, ep);
    428        1.1       mrg 			}
    429        1.1       mrg 			h_errno = NETDB_SUCCESS;
    430        1.1       mrg 			return (&host);
    431        1.1       mrg #endif
    432        1.1       mrg 		case T_A:
    433        1.1       mrg 		case T_AAAA:
    434        1.1       mrg 			if (strcasecmp(host.h_name, bp) != 0) {
    435        1.1       mrg 				syslog(LOG_NOTICE|LOG_AUTH,
    436        1.1       mrg 				       AskedForGot, host.h_name, bp);
    437        1.1       mrg 				cp += n;
    438        1.1       mrg 				continue;	/* XXX - had_error++ ? */
    439        1.1       mrg 			}
    440        1.1       mrg 			if (n != host.h_length) {
    441        1.1       mrg 				cp += n;
    442        1.1       mrg 				continue;
    443   1.42.2.8     lukem 			}
    444   1.42.2.8     lukem 			if (type == T_AAAA) {
    445   1.42.2.8     lukem 				struct in6_addr in6;
    446   1.42.2.8     lukem 				memcpy(&in6, cp, IN6ADDRSZ);
    447   1.42.2.8     lukem 				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
    448   1.42.2.8     lukem 					cp += n;
    449   1.42.2.8     lukem 					continue;
    450   1.42.2.8     lukem 				}
    451        1.1       mrg 			}
    452        1.1       mrg 			if (!haveanswer) {
    453       1.25     lukem 				int nn;
    454        1.1       mrg 
    455        1.1       mrg 				host.h_name = bp;
    456        1.1       mrg 				nn = strlen(bp) + 1;	/* for the \0 */
    457        1.1       mrg 				bp += nn;
    458        1.1       mrg 			}
    459        1.1       mrg 
    460       1.14     lukem 			bp += sizeof(align) -
    461       1.14     lukem 			    (size_t)((u_long)bp % sizeof(align));
    462        1.1       mrg 
    463        1.1       mrg 			if (bp + n >= &hostbuf[sizeof hostbuf]) {
    464        1.1       mrg 				dprintf("size (%d) too big\n", n);
    465        1.1       mrg 				had_error++;
    466        1.1       mrg 				continue;
    467        1.1       mrg 			}
    468        1.1       mrg 			if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
    469        1.1       mrg 				if (!toobig++)
    470        1.1       mrg 					dprintf("Too many addresses (%d)\n",
    471        1.1       mrg 						MAXADDRS);
    472        1.1       mrg 				cp += n;
    473        1.1       mrg 				continue;
    474        1.1       mrg 			}
    475        1.7    kleink 			(void)memcpy(*hap++ = bp, cp, (size_t)n);
    476        1.1       mrg 			bp += n;
    477        1.1       mrg 			cp += n;
    478       1.32    itojun 			if (cp != erdata) {
    479       1.32    itojun 				h_errno = NO_RECOVERY;
    480       1.32    itojun 				return (NULL);
    481       1.32    itojun 			}
    482        1.1       mrg 			break;
    483        1.1       mrg 		default:
    484        1.1       mrg 			abort();
    485        1.1       mrg 		}
    486        1.1       mrg 		if (!had_error)
    487        1.1       mrg 			haveanswer++;
    488        1.1       mrg 	}
    489        1.1       mrg 	if (haveanswer) {
    490        1.1       mrg 		*ap = NULL;
    491        1.1       mrg 		*hap = NULL;
    492        1.1       mrg # if defined(RESOLVSORT)
    493        1.1       mrg 		/*
    494        1.1       mrg 		 * Note: we sort even if host can take only one address
    495        1.1       mrg 		 * in its return structures - should give it the "best"
    496        1.1       mrg 		 * address in that case, not some random one
    497        1.1       mrg 		 */
    498        1.1       mrg 		if (_res.nsort && haveanswer > 1 && qtype == T_A)
    499        1.1       mrg 			addrsort(h_addr_ptrs, haveanswer);
    500        1.1       mrg # endif /*RESOLVSORT*/
    501        1.1       mrg 		if (!host.h_name) {
    502        1.1       mrg 			n = strlen(qname) + 1;	/* for the \0 */
    503   1.42.2.2     lukem 			if (n > ep - bp || n >= MAXHOSTNAMELEN)
    504        1.1       mrg 				goto no_recovery;
    505        1.1       mrg 			strcpy(bp, qname);
    506        1.1       mrg 			host.h_name = bp;
    507        1.1       mrg 			bp += n;
    508        1.1       mrg 		}
    509        1.1       mrg 		if (_res.options & RES_USE_INET6)
    510   1.42.2.2     lukem 			map_v4v6_hostent(&host, &bp, ep);
    511        1.1       mrg 		h_errno = NETDB_SUCCESS;
    512        1.1       mrg 		return (&host);
    513        1.1       mrg 	}
    514        1.1       mrg  no_recovery:
    515        1.1       mrg 	h_errno = NO_RECOVERY;
    516        1.1       mrg 	return (NULL);
    517        1.1       mrg }
    518        1.1       mrg 
    519        1.1       mrg struct hostent *
    520        1.1       mrg gethostbyname(name)
    521        1.1       mrg 	const char *name;
    522        1.1       mrg {
    523        1.1       mrg 	struct hostent *hp;
    524        1.1       mrg 
    525       1.25     lukem 	_DIAGASSERT(name != NULL);
    526       1.25     lukem 
    527        1.1       mrg 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
    528        1.1       mrg 		h_errno = NETDB_INTERNAL;
    529        1.1       mrg 		return (NULL);
    530        1.1       mrg 	}
    531        1.1       mrg 	if (_res.options & RES_USE_INET6) {
    532        1.1       mrg 		hp = gethostbyname2(name, AF_INET6);
    533        1.1       mrg 		if (hp)
    534        1.1       mrg 			return (hp);
    535        1.1       mrg 	}
    536        1.1       mrg 	return (gethostbyname2(name, AF_INET));
    537        1.1       mrg }
    538        1.1       mrg 
    539        1.1       mrg struct hostent *
    540        1.1       mrg gethostbyname2(name, af)
    541        1.1       mrg 	const char *name;
    542        1.1       mrg 	int af;
    543        1.1       mrg {
    544        1.2       mrg 	const char *cp;
    545   1.42.2.2     lukem 	char *bp, *ep;
    546   1.42.2.2     lukem 	int size;
    547        1.2       mrg 	struct hostent *hp;
    548       1.12     lukem 	static const ns_dtab dtab[] = {
    549       1.11     lukem 		NS_FILES_CB(_gethtbyname, NULL)
    550        1.9     lukem 		{ NSSRC_DNS, _dns_gethtbyname, NULL },	/* force -DHESIOD */
    551       1.11     lukem 		NS_NIS_CB(_yp_gethtbyname, NULL)
    552       1.11     lukem 		{ 0 }
    553        1.9     lukem 	};
    554        1.1       mrg 
    555       1.25     lukem 	_DIAGASSERT(name != NULL);
    556       1.25     lukem 
    557        1.1       mrg 	switch (af) {
    558        1.1       mrg 	case AF_INET:
    559        1.1       mrg 		size = INADDRSZ;
    560        1.1       mrg 		break;
    561        1.1       mrg 	case AF_INET6:
    562        1.1       mrg 		size = IN6ADDRSZ;
    563        1.1       mrg 		break;
    564        1.1       mrg 	default:
    565        1.1       mrg 		h_errno = NETDB_INTERNAL;
    566        1.1       mrg 		errno = EAFNOSUPPORT;
    567        1.1       mrg 		return (NULL);
    568        1.1       mrg 	}
    569        1.1       mrg 
    570        1.1       mrg 	host.h_addrtype = af;
    571        1.1       mrg 	host.h_length = size;
    572        1.1       mrg 
    573        1.1       mrg 	/*
    574        1.1       mrg 	 * if there aren't any dots, it could be a user-level alias.
    575        1.1       mrg 	 * this is also done in res_query() since we are not the only
    576        1.1       mrg 	 * function that looks up host names.
    577        1.1       mrg 	 */
    578        1.1       mrg 	if (!strchr(name, '.') && (cp = __hostalias(name)))
    579        1.1       mrg 		name = cp;
    580        1.1       mrg 
    581        1.1       mrg 	/*
    582        1.1       mrg 	 * disallow names consisting only of digits/dots, unless
    583        1.1       mrg 	 * they end in a dot.
    584        1.1       mrg 	 */
    585       1.35     itohy 	if (isdigit((u_char) name[0]))
    586        1.1       mrg 		for (cp = name;; ++cp) {
    587        1.1       mrg 			if (!*cp) {
    588        1.1       mrg 				if (*--cp == '.')
    589        1.1       mrg 					break;
    590        1.1       mrg 				/*
    591        1.1       mrg 				 * All-numeric, no dot at the end.
    592        1.1       mrg 				 * Fake up a hostent as if we'd actually
    593        1.1       mrg 				 * done a lookup.
    594        1.1       mrg 				 */
    595       1.23  christos 				if (inet_pton(af, name,
    596       1.31  christos 				    (char *)(void *)host_addr) <= 0) {
    597        1.1       mrg 					h_errno = HOST_NOT_FOUND;
    598        1.1       mrg 					return (NULL);
    599        1.1       mrg 				}
    600        1.1       mrg 				strncpy(hostbuf, name, MAXDNAME);
    601        1.1       mrg 				hostbuf[MAXDNAME] = '\0';
    602        1.1       mrg 				bp = hostbuf + MAXDNAME;
    603   1.42.2.2     lukem 				ep = hostbuf + sizeof hostbuf;
    604        1.1       mrg 				host.h_name = hostbuf;
    605        1.1       mrg 				host.h_aliases = host_aliases;
    606        1.1       mrg 				host_aliases[0] = NULL;
    607       1.31  christos 				h_addr_ptrs[0] = (char *)(void *)host_addr;
    608        1.1       mrg 				h_addr_ptrs[1] = NULL;
    609        1.1       mrg 				host.h_addr_list = h_addr_ptrs;
    610        1.1       mrg 				if (_res.options & RES_USE_INET6)
    611   1.42.2.2     lukem 					map_v4v6_hostent(&host, &bp, ep);
    612        1.1       mrg 				h_errno = NETDB_SUCCESS;
    613        1.1       mrg 				return (&host);
    614        1.1       mrg 			}
    615       1.35     itohy 			if (!isdigit((u_char) *cp) && *cp != '.')
    616        1.1       mrg 				break;
    617        1.1       mrg 		}
    618       1.35     itohy 	if ((isxdigit((u_char) name[0]) && strchr(name, ':') != NULL) ||
    619        1.1       mrg 	    name[0] == ':')
    620        1.1       mrg 		for (cp = name;; ++cp) {
    621        1.1       mrg 			if (!*cp) {
    622        1.1       mrg 				if (*--cp == '.')
    623        1.1       mrg 					break;
    624        1.1       mrg 				/*
    625        1.1       mrg 				 * All-IPv6-legal, no dot at the end.
    626        1.1       mrg 				 * Fake up a hostent as if we'd actually
    627        1.1       mrg 				 * done a lookup.
    628        1.1       mrg 				 */
    629       1.23  christos 				if (inet_pton(af, name,
    630       1.31  christos 				    (char *)(void *)host_addr) <= 0) {
    631        1.1       mrg 					h_errno = HOST_NOT_FOUND;
    632        1.1       mrg 					return (NULL);
    633        1.1       mrg 				}
    634        1.1       mrg 				strncpy(hostbuf, name, MAXDNAME);
    635        1.1       mrg 				hostbuf[MAXDNAME] = '\0';
    636        1.1       mrg 				bp = hostbuf + MAXDNAME;
    637   1.42.2.2     lukem 				ep = hostbuf + sizeof hostbuf;
    638        1.1       mrg 				host.h_name = hostbuf;
    639        1.1       mrg 				host.h_aliases = host_aliases;
    640        1.1       mrg 				host_aliases[0] = NULL;
    641       1.31  christos 				h_addr_ptrs[0] = (char *)(void *)host_addr;
    642        1.1       mrg 				h_addr_ptrs[1] = NULL;
    643        1.1       mrg 				host.h_addr_list = h_addr_ptrs;
    644        1.1       mrg 				h_errno = NETDB_SUCCESS;
    645        1.1       mrg 				return (&host);
    646        1.1       mrg 			}
    647       1.35     itohy 			if (!isxdigit((u_char) *cp) && *cp != ':' && *cp != '.')
    648        1.1       mrg 				break;
    649        1.1       mrg 		}
    650        1.1       mrg 
    651        1.2       mrg 	hp = (struct hostent *)NULL;
    652       1.10     lukem 	h_errno = NETDB_INTERNAL;
    653       1.11     lukem 	if (nsdispatch(&hp, dtab, NSDB_HOSTS, "gethostbyname",
    654   1.42.2.1     lukem 	    default_dns_files, name, strlen(name), af) != NS_SUCCESS)
    655        1.9     lukem 		return (struct hostent *)NULL;
    656        1.9     lukem 	h_errno = NETDB_SUCCESS;
    657        1.2       mrg 	return (hp);
    658        1.1       mrg }
    659        1.1       mrg 
    660        1.1       mrg struct hostent *
    661        1.1       mrg gethostbyaddr(addr, len, af)
    662        1.1       mrg 	const char *addr;	/* XXX should have been def'd as u_char! */
    663       1.40    kleink 	socklen_t len;
    664       1.40    kleink 	int af;
    665        1.1       mrg {
    666        1.1       mrg 	const u_char *uaddr = (const u_char *)addr;
    667        1.9     lukem 	int size;
    668        1.2       mrg 	struct hostent *hp;
    669       1.12     lukem 	static const ns_dtab dtab[] = {
    670       1.11     lukem 		NS_FILES_CB(_gethtbyaddr, NULL)
    671        1.9     lukem 		{ NSSRC_DNS, _dns_gethtbyaddr, NULL },	/* force -DHESIOD */
    672       1.11     lukem 		NS_NIS_CB(_yp_gethtbyaddr, NULL)
    673       1.11     lukem 		{ 0 }
    674        1.9     lukem 	};
    675        1.1       mrg 
    676       1.25     lukem 	_DIAGASSERT(addr != NULL);
    677       1.25     lukem 
    678        1.1       mrg 	if (af == AF_INET6 && len == IN6ADDRSZ &&
    679       1.41    itojun 	    (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr *)(const void *)uaddr) ||
    680       1.41    itojun 	     IN6_IS_ADDR_SITELOCAL((const struct in6_addr *)(const void *)uaddr))) {
    681       1.41    itojun 		h_errno = HOST_NOT_FOUND;
    682       1.42    itojun 		return (NULL);
    683       1.41    itojun 	}
    684       1.41    itojun 	if (af == AF_INET6 && len == IN6ADDRSZ &&
    685       1.31  christos 	    (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)(const void *)uaddr) ||
    686       1.31  christos 	     IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)(const void *)uaddr))) {
    687        1.1       mrg 		/* Unmap. */
    688       1.24    itojun 		addr += IN6ADDRSZ - INADDRSZ;
    689       1.24    itojun 		uaddr += IN6ADDRSZ - INADDRSZ;
    690        1.1       mrg 		af = AF_INET;
    691        1.1       mrg 		len = INADDRSZ;
    692        1.1       mrg 	}
    693        1.1       mrg 	switch (af) {
    694        1.1       mrg 	case AF_INET:
    695        1.1       mrg 		size = INADDRSZ;
    696        1.1       mrg 		break;
    697        1.1       mrg 	case AF_INET6:
    698        1.1       mrg 		size = IN6ADDRSZ;
    699        1.1       mrg 		break;
    700        1.1       mrg 	default:
    701        1.1       mrg 		errno = EAFNOSUPPORT;
    702        1.1       mrg 		h_errno = NETDB_INTERNAL;
    703        1.1       mrg 		return (NULL);
    704        1.1       mrg 	}
    705        1.1       mrg 	if (size != len) {
    706        1.1       mrg 		errno = EINVAL;
    707        1.1       mrg 		h_errno = NETDB_INTERNAL;
    708        1.1       mrg 		return (NULL);
    709        1.1       mrg 	}
    710        1.2       mrg 	hp = (struct hostent *)NULL;
    711       1.10     lukem 	h_errno = NETDB_INTERNAL;
    712       1.11     lukem 	if (nsdispatch(&hp, dtab, NSDB_HOSTS, "gethostbyaddr",
    713       1.11     lukem 	    default_dns_files, uaddr, len, af) != NS_SUCCESS)
    714        1.9     lukem 		return (struct hostent *)NULL;
    715       1.10     lukem 	h_errno = NETDB_SUCCESS;
    716        1.1       mrg 	return (hp);
    717        1.1       mrg }
    718        1.1       mrg 
    719        1.1       mrg void
    720        1.1       mrg _sethtent(f)
    721        1.1       mrg 	int f;
    722        1.1       mrg {
    723        1.1       mrg 	if (!hostf)
    724        1.1       mrg 		hostf = fopen(_PATH_HOSTS, "r" );
    725        1.1       mrg 	else
    726        1.1       mrg 		rewind(hostf);
    727        1.1       mrg 	stayopen = f;
    728        1.1       mrg }
    729        1.1       mrg 
    730        1.1       mrg void
    731        1.1       mrg _endhtent()
    732        1.1       mrg {
    733        1.1       mrg 	if (hostf && !stayopen) {
    734        1.1       mrg 		(void) fclose(hostf);
    735        1.1       mrg 		hostf = NULL;
    736        1.1       mrg 	}
    737        1.1       mrg }
    738        1.1       mrg 
    739        1.1       mrg struct hostent *
    740        1.1       mrg _gethtent()
    741        1.1       mrg {
    742        1.1       mrg 	char *p;
    743       1.25     lukem 	char *cp, **q;
    744        1.1       mrg 	int af, len;
    745        1.1       mrg 
    746        1.1       mrg 	if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
    747        1.1       mrg 		h_errno = NETDB_INTERNAL;
    748        1.1       mrg 		return (NULL);
    749        1.1       mrg 	}
    750        1.1       mrg  again:
    751        1.1       mrg 	if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
    752        1.1       mrg 		h_errno = HOST_NOT_FOUND;
    753        1.1       mrg 		return (NULL);
    754        1.1       mrg 	}
    755        1.1       mrg 	if (*p == '#')
    756        1.1       mrg 		goto again;
    757        1.1       mrg 	if (!(cp = strpbrk(p, "#\n")))
    758        1.1       mrg 		goto again;
    759        1.1       mrg 	*cp = '\0';
    760        1.1       mrg 	if (!(cp = strpbrk(p, " \t")))
    761        1.1       mrg 		goto again;
    762        1.1       mrg 	*cp++ = '\0';
    763       1.31  christos 	if (inet_pton(AF_INET6, p, (char *)(void *)host_addr) > 0) {
    764        1.1       mrg 		af = AF_INET6;
    765        1.1       mrg 		len = IN6ADDRSZ;
    766       1.31  christos 	} else if (inet_pton(AF_INET, p, (char *)(void *)host_addr) > 0) {
    767        1.1       mrg 		if (_res.options & RES_USE_INET6) {
    768       1.31  christos 			map_v4v6_address((char *)(void *)host_addr,
    769       1.31  christos 			    (char *)(void *)host_addr);
    770        1.1       mrg 			af = AF_INET6;
    771        1.1       mrg 			len = IN6ADDRSZ;
    772        1.1       mrg 		} else {
    773        1.1       mrg 			af = AF_INET;
    774        1.1       mrg 			len = INADDRSZ;
    775        1.1       mrg 		}
    776        1.1       mrg 	} else {
    777        1.1       mrg 		goto again;
    778        1.1       mrg 	}
    779       1.21    itojun 	/* if this is not something we're looking for, skip it. */
    780       1.21    itojun 	if (host.h_addrtype != af)
    781       1.21    itojun 		goto again;
    782       1.21    itojun 	if (host.h_length != len)
    783       1.21    itojun 		goto again;
    784       1.31  christos 	h_addr_ptrs[0] = (char *)(void *)host_addr;
    785        1.1       mrg 	h_addr_ptrs[1] = NULL;
    786        1.1       mrg 	host.h_addr_list = h_addr_ptrs;
    787        1.1       mrg 	host.h_length = len;
    788        1.1       mrg 	host.h_addrtype = af;
    789        1.1       mrg 	while (*cp == ' ' || *cp == '\t')
    790        1.1       mrg 		cp++;
    791        1.1       mrg 	host.h_name = cp;
    792        1.1       mrg 	q = host.h_aliases = host_aliases;
    793        1.2       mrg 	if ((cp = strpbrk(cp, " \t")) != NULL)
    794        1.1       mrg 		*cp++ = '\0';
    795        1.1       mrg 	while (cp && *cp) {
    796        1.1       mrg 		if (*cp == ' ' || *cp == '\t') {
    797        1.1       mrg 			cp++;
    798        1.1       mrg 			continue;
    799        1.1       mrg 		}
    800        1.1       mrg 		if (q < &host_aliases[MAXALIASES - 1])
    801        1.1       mrg 			*q++ = cp;
    802        1.2       mrg 		if ((cp = strpbrk(cp, " \t")) != NULL)
    803        1.1       mrg 			*cp++ = '\0';
    804        1.1       mrg 	}
    805        1.1       mrg 	*q = NULL;
    806        1.1       mrg 	h_errno = NETDB_SUCCESS;
    807        1.1       mrg 	return (&host);
    808        1.1       mrg }
    809        1.1       mrg 
    810       1.13  christos /*ARGSUSED*/
    811        1.9     lukem int
    812        1.9     lukem _gethtbyname(rv, cb_data, ap)
    813        1.9     lukem 	void	*rv;
    814        1.9     lukem 	void	*cb_data;
    815        1.9     lukem 	va_list	 ap;
    816        1.1       mrg {
    817        1.1       mrg 	struct hostent *hp;
    818        1.9     lukem 	const char *name;
    819       1.30   mycroft 	int af;
    820        1.1       mrg 
    821       1.25     lukem 	_DIAGASSERT(rv != NULL);
    822       1.25     lukem 
    823        1.9     lukem 	name = va_arg(ap, char *);
    824       1.30   mycroft 	/* NOSTRICT skip len */(void)va_arg(ap, int);
    825        1.9     lukem 	af = va_arg(ap, int);
    826        1.9     lukem 
    827        1.9     lukem 	hp = NULL;
    828       1.20    itojun #if 0
    829        1.9     lukem 	if (_res.options & RES_USE_INET6)
    830        1.1       mrg 		hp = _gethtbyname2(name, AF_INET6);
    831        1.9     lukem 	if (hp==NULL)
    832        1.9     lukem 		hp = _gethtbyname2(name, AF_INET);
    833       1.20    itojun #else
    834       1.20    itojun 	hp = _gethtbyname2(name, af);
    835       1.20    itojun #endif
    836        1.9     lukem 	*((struct hostent **)rv) = hp;
    837       1.41    itojun 	if (hp == NULL) {
    838        1.9     lukem 		h_errno = HOST_NOT_FOUND;
    839        1.9     lukem 		return NS_NOTFOUND;
    840        1.1       mrg 	}
    841        1.9     lukem 	return NS_SUCCESS;
    842        1.1       mrg }
    843        1.1       mrg 
    844        1.1       mrg struct hostent *
    845        1.1       mrg _gethtbyname2(name, af)
    846        1.1       mrg 	const char *name;
    847        1.1       mrg 	int af;
    848        1.1       mrg {
    849       1.25     lukem 	struct hostent *p;
    850       1.25     lukem 	char *tmpbuf, *ptr, **cp;
    851       1.25     lukem 	int num;
    852       1.25     lukem 	size_t len;
    853       1.25     lukem 
    854       1.25     lukem 	_DIAGASSERT(name != NULL);
    855       1.18      tron 
    856        1.1       mrg 	_sethtent(0);
    857       1.18      tron 	ptr = tmpbuf = NULL;
    858       1.18      tron 	num = 0;
    859       1.18      tron 	while ((p = _gethtent()) != NULL && num < MAXADDRS) {
    860        1.1       mrg 		if (p->h_addrtype != af)
    861        1.1       mrg 			continue;
    862       1.18      tron 		if (strcasecmp(p->h_name, name) != 0) {
    863       1.18      tron 			for (cp = p->h_aliases; *cp != NULL; cp++)
    864       1.18      tron 				if (strcasecmp(*cp, name) == 0)
    865       1.18      tron 					break;
    866       1.18      tron 			if (*cp == NULL) continue;
    867       1.18      tron 		}
    868       1.18      tron 
    869       1.18      tron 		if (num == 0) {
    870       1.25     lukem 			size_t bufsize;
    871       1.25     lukem 			char *src;
    872       1.18      tron 
    873       1.18      tron 			bufsize = strlen(p->h_name) + 2 +
    874       1.22      tron 				  MAXADDRS * p->h_length +
    875       1.22      tron 				  ALIGNBYTES;
    876       1.18      tron 			for (cp = p->h_aliases; *cp != NULL; cp++)
    877       1.18      tron 				bufsize += strlen(*cp) + 1;
    878       1.18      tron 
    879       1.18      tron 			if ((tmpbuf = malloc(bufsize)) == NULL) {
    880       1.18      tron 				h_errno = NETDB_INTERNAL;
    881       1.18      tron 				return NULL;
    882       1.18      tron 			}
    883       1.18      tron 
    884       1.18      tron 			ptr = tmpbuf;
    885       1.18      tron 			src = p->h_name;
    886       1.18      tron 			while ((*ptr++ = *src++) != '\0');
    887       1.18      tron 			for (cp = p->h_aliases; *cp != NULL; cp++) {
    888       1.18      tron 				src = *cp;
    889       1.18      tron 				while ((*ptr++ = *src++) != '\0');
    890       1.18      tron 			}
    891       1.18      tron 			*ptr++ = '\0';
    892       1.22      tron 
    893       1.31  christos 			ptr = (char *)(void *)ALIGN(ptr);
    894       1.18      tron 		}
    895       1.18      tron 
    896       1.18      tron 		(void)memcpy(ptr, p->h_addr_list[0], (size_t)p->h_length);
    897       1.18      tron 		ptr += p->h_length;
    898       1.18      tron 		num++;
    899        1.1       mrg 	}
    900        1.1       mrg 	_endhtent();
    901       1.18      tron 	if (num == 0) return NULL;
    902       1.18      tron 
    903       1.18      tron 	len = ptr - tmpbuf;
    904       1.33      tron 	if (len > (sizeof(hostbuf) - ALIGNBYTES)) {
    905       1.18      tron 		free(tmpbuf);
    906       1.18      tron 		errno = ENOSPC;
    907       1.18      tron 		h_errno = NETDB_INTERNAL;
    908       1.18      tron 		return NULL;
    909       1.18      tron 	}
    910       1.33      tron 	ptr = memcpy((void *)ALIGN(hostbuf), tmpbuf, len);
    911       1.18      tron 	free(tmpbuf);
    912       1.18      tron 
    913       1.18      tron 	host.h_name = ptr;
    914       1.18      tron 	while (*ptr++);
    915       1.18      tron 
    916       1.18      tron 	cp = host_aliases;
    917       1.18      tron 	while (*ptr) {
    918       1.18      tron 		*cp++ = ptr;
    919       1.18      tron 		while (*ptr++);
    920       1.18      tron 	}
    921       1.18      tron 	ptr++;
    922       1.18      tron 	*cp = NULL;
    923       1.18      tron 
    924       1.31  christos 	ptr = (char *)(void *)ALIGN(ptr);
    925       1.18      tron 	cp = h_addr_ptrs;
    926       1.18      tron 	while (num--) {
    927       1.18      tron 		*cp++ = ptr;
    928       1.18      tron 		ptr += host.h_length;
    929       1.18      tron 	}
    930       1.18      tron 	*cp = NULL;
    931       1.18      tron 
    932       1.18      tron 	return (&host);
    933        1.1       mrg }
    934        1.1       mrg 
    935       1.13  christos /*ARGSUSED*/
    936        1.9     lukem int
    937        1.9     lukem _gethtbyaddr(rv, cb_data, ap)
    938        1.9     lukem 	void	*rv;
    939        1.9     lukem 	void	*cb_data;
    940        1.9     lukem 	va_list	 ap;
    941        1.1       mrg {
    942       1.25     lukem 	struct hostent *p;
    943        1.9     lukem 	const unsigned char *addr;
    944        1.9     lukem 	int len, af;
    945        1.9     lukem 
    946       1.25     lukem 	_DIAGASSERT(rv != NULL);
    947       1.25     lukem 
    948        1.9     lukem 	addr = va_arg(ap, unsigned char *);
    949        1.9     lukem 	len = va_arg(ap, int);
    950        1.9     lukem 	af = va_arg(ap, int);
    951        1.9     lukem 
    952       1.21    itojun 	host.h_length = len;
    953       1.21    itojun 	host.h_addrtype = af;
    954        1.1       mrg 
    955        1.1       mrg 	_sethtent(0);
    956        1.2       mrg 	while ((p = _gethtent()) != NULL)
    957        1.7    kleink 		if (p->h_addrtype == af && !memcmp(p->h_addr, addr,
    958        1.7    kleink 		    (size_t)len))
    959        1.1       mrg 			break;
    960        1.1       mrg 	_endhtent();
    961        1.9     lukem 	*((struct hostent **)rv) = p;
    962        1.9     lukem 	if (p==NULL) {
    963        1.9     lukem 		h_errno = HOST_NOT_FOUND;
    964        1.9     lukem 		return NS_NOTFOUND;
    965        1.9     lukem 	}
    966        1.9     lukem 	return NS_SUCCESS;
    967        1.1       mrg }
    968        1.1       mrg 
    969        1.1       mrg static void
    970        1.1       mrg map_v4v6_address(src, dst)
    971        1.1       mrg 	const char *src;
    972        1.1       mrg 	char *dst;
    973        1.1       mrg {
    974        1.1       mrg 	u_char *p = (u_char *)dst;
    975        1.1       mrg 	char tmp[INADDRSZ];
    976        1.1       mrg 	int i;
    977        1.1       mrg 
    978       1.25     lukem 	_DIAGASSERT(src != NULL);
    979       1.25     lukem 	_DIAGASSERT(dst != NULL);
    980       1.25     lukem 
    981        1.1       mrg 	/* Stash a temporary copy so our caller can update in place. */
    982        1.7    kleink 	(void)memcpy(tmp, src, INADDRSZ);
    983        1.1       mrg 	/* Mark this ipv6 addr as a mapped ipv4. */
    984        1.1       mrg 	for (i = 0; i < 10; i++)
    985        1.1       mrg 		*p++ = 0x00;
    986        1.1       mrg 	*p++ = 0xff;
    987        1.1       mrg 	*p++ = 0xff;
    988        1.1       mrg 	/* Retrieve the saved copy and we're done. */
    989        1.7    kleink 	(void)memcpy((void *)p, tmp, INADDRSZ);
    990        1.1       mrg }
    991        1.1       mrg 
    992        1.1       mrg static void
    993   1.42.2.2     lukem map_v4v6_hostent(hp, bpp, ep)
    994        1.1       mrg 	struct hostent *hp;
    995        1.1       mrg 	char **bpp;
    996   1.42.2.2     lukem 	char *ep;
    997        1.1       mrg {
    998        1.1       mrg 	char **ap;
    999        1.1       mrg 
   1000       1.25     lukem 	_DIAGASSERT(hp != NULL);
   1001       1.25     lukem 	_DIAGASSERT(bpp != NULL);
   1002   1.42.2.3     lukem 	_DIAGASSERT(ep != NULL);
   1003       1.25     lukem 
   1004        1.1       mrg 	if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
   1005        1.1       mrg 		return;
   1006        1.1       mrg 	hp->h_addrtype = AF_INET6;
   1007        1.1       mrg 	hp->h_length = IN6ADDRSZ;
   1008        1.1       mrg 	for (ap = hp->h_addr_list; *ap; ap++) {
   1009        1.8  christos 		int i = sizeof(align) - (size_t)((u_long)*bpp % sizeof(align));
   1010        1.1       mrg 
   1011   1.42.2.2     lukem 		if (ep - *bpp < (i + IN6ADDRSZ)) {
   1012        1.1       mrg 			/* Out of memory.  Truncate address list here.  XXX */
   1013        1.1       mrg 			*ap = NULL;
   1014        1.1       mrg 			return;
   1015        1.1       mrg 		}
   1016        1.1       mrg 		*bpp += i;
   1017        1.1       mrg 		map_v4v6_address(*ap, *bpp);
   1018        1.1       mrg 		*ap = *bpp;
   1019        1.1       mrg 		*bpp += IN6ADDRSZ;
   1020        1.1       mrg 	}
   1021        1.1       mrg }
   1022        1.1       mrg 
   1023        1.1       mrg #ifdef RESOLVSORT
   1024        1.1       mrg static void
   1025        1.1       mrg addrsort(ap, num)
   1026        1.1       mrg 	char **ap;
   1027        1.1       mrg 	int num;
   1028        1.1       mrg {
   1029        1.1       mrg 	int i, j;
   1030        1.1       mrg 	char **p;
   1031        1.1       mrg 	short aval[MAXADDRS];
   1032        1.1       mrg 	int needsort = 0;
   1033        1.1       mrg 
   1034       1.25     lukem 	_DIAGASSERT(ap != NULL);
   1035       1.25     lukem 
   1036        1.1       mrg 	p = ap;
   1037        1.1       mrg 	for (i = 0; i < num; i++, p++) {
   1038        1.1       mrg 	    for (j = 0 ; (unsigned)j < _res.nsort; j++)
   1039        1.1       mrg 		if (_res.sort_list[j].addr.s_addr ==
   1040       1.14     lukem 		    (((struct in_addr *)(void *)(*p))->s_addr &
   1041       1.14     lukem 		    _res.sort_list[j].mask))
   1042        1.1       mrg 			break;
   1043        1.1       mrg 	    aval[i] = j;
   1044        1.1       mrg 	    if (needsort == 0 && i > 0 && j < aval[i-1])
   1045        1.1       mrg 		needsort = i;
   1046        1.1       mrg 	}
   1047        1.1       mrg 	if (!needsort)
   1048        1.1       mrg 	    return;
   1049        1.1       mrg 
   1050        1.1       mrg 	while (needsort < num) {
   1051        1.1       mrg 	    for (j = needsort - 1; j >= 0; j--) {
   1052        1.1       mrg 		if (aval[j] > aval[j+1]) {
   1053        1.1       mrg 		    char *hp;
   1054        1.1       mrg 
   1055        1.1       mrg 		    i = aval[j];
   1056        1.1       mrg 		    aval[j] = aval[j+1];
   1057        1.1       mrg 		    aval[j+1] = i;
   1058        1.1       mrg 
   1059        1.1       mrg 		    hp = ap[j];
   1060        1.1       mrg 		    ap[j] = ap[j+1];
   1061        1.1       mrg 		    ap[j+1] = hp;
   1062        1.1       mrg 		} else
   1063        1.1       mrg 		    break;
   1064        1.1       mrg 	    }
   1065        1.1       mrg 	    needsort++;
   1066        1.1       mrg 	}
   1067        1.1       mrg }
   1068        1.1       mrg #endif
   1069        1.1       mrg 
   1070        1.1       mrg #if defined(BSD43_BSD43_NFS) || defined(sun)
   1071       1.25     lukem /* XXX: should we remove this cruft? - lukem */
   1072        1.1       mrg /* some libc's out there are bound internally to these names (UMIPS) */
   1073        1.1       mrg void
   1074        1.1       mrg ht_sethostent(stayopen)
   1075        1.1       mrg 	int stayopen;
   1076        1.1       mrg {
   1077        1.1       mrg 	_sethtent(stayopen);
   1078        1.1       mrg }
   1079        1.1       mrg 
   1080        1.1       mrg void
   1081        1.1       mrg ht_endhostent()
   1082        1.1       mrg {
   1083        1.1       mrg 	_endhtent();
   1084        1.1       mrg }
   1085        1.1       mrg 
   1086        1.1       mrg struct hostent *
   1087        1.1       mrg ht_gethostbyname(name)
   1088        1.1       mrg 	char *name;
   1089        1.1       mrg {
   1090        1.1       mrg 	return (_gethtbyname(name));
   1091        1.1       mrg }
   1092        1.1       mrg 
   1093        1.1       mrg struct hostent *
   1094        1.1       mrg ht_gethostbyaddr(addr, len, af)
   1095        1.1       mrg 	const char *addr;
   1096        1.1       mrg 	int len, af;
   1097        1.1       mrg {
   1098        1.1       mrg 	return (_gethtbyaddr(addr, len, af));
   1099        1.1       mrg }
   1100        1.1       mrg 
   1101        1.1       mrg struct hostent *
   1102        1.1       mrg gethostent()
   1103        1.1       mrg {
   1104        1.1       mrg 	return (_gethtent());
   1105        1.1       mrg }
   1106        1.1       mrg 
   1107        1.1       mrg void
   1108        1.1       mrg dns_service()
   1109        1.1       mrg {
   1110        1.1       mrg 	return;
   1111        1.1       mrg }
   1112        1.1       mrg 
   1113       1.39  christos int
   1114        1.1       mrg dn_skipname(comp_dn, eom)
   1115        1.1       mrg 	const u_char *comp_dn, *eom;
   1116        1.1       mrg {
   1117        1.1       mrg 	return (__dn_skipname(comp_dn, eom));
   1118        1.1       mrg }
   1119        1.1       mrg #endif /*old-style libc with yp junk in it*/
   1120        1.2       mrg 
   1121       1.13  christos /*ARGSUSED*/
   1122        1.9     lukem int
   1123        1.9     lukem _dns_gethtbyname(rv, cb_data, ap)
   1124        1.9     lukem 	void	*rv;
   1125        1.9     lukem 	void	*cb_data;
   1126        1.9     lukem 	va_list	 ap;
   1127        1.9     lukem {
   1128   1.42.2.9     lukem 	querybuf *buf;
   1129        1.9     lukem 	int n, type;
   1130        1.9     lukem 	struct hostent *hp;
   1131        1.9     lukem 	const char *name;
   1132       1.17  christos 	int af;
   1133        1.9     lukem 
   1134       1.25     lukem 	_DIAGASSERT(rv != NULL);
   1135       1.25     lukem 
   1136        1.9     lukem 	name = va_arg(ap, char *);
   1137       1.17  christos 	/* NOSTRICT skip len */(void)va_arg(ap, int);
   1138        1.9     lukem 	af = va_arg(ap, int);
   1139        1.9     lukem 
   1140        1.9     lukem 	switch (af) {
   1141        1.9     lukem 	case AF_INET:
   1142        1.9     lukem 		type = T_A;
   1143        1.9     lukem 		break;
   1144        1.9     lukem 	case AF_INET6:
   1145        1.9     lukem 		type = T_AAAA;
   1146        1.9     lukem 		break;
   1147        1.9     lukem 	default:
   1148        1.9     lukem 		return NS_UNAVAIL;
   1149        1.9     lukem 	}
   1150   1.42.2.9     lukem 	buf = malloc(sizeof(*buf));
   1151   1.42.2.9     lukem 	if (buf == NULL) {
   1152   1.42.2.9     lukem 		h_errno = NETDB_INTERNAL;
   1153   1.42.2.9     lukem 		return NS_NOTFOUND;
   1154   1.42.2.9     lukem 	}
   1155   1.42.2.9     lukem 	n = res_search(name, C_IN, type, buf->buf, sizeof(buf->buf));
   1156   1.42.2.9     lukem 	if (n < 0) {
   1157   1.42.2.9     lukem 		free(buf);
   1158        1.9     lukem 		dprintf("res_search failed (%d)\n", n);
   1159        1.9     lukem 		return NS_NOTFOUND;
   1160        1.9     lukem 	}
   1161   1.42.2.9     lukem 	hp = getanswer(buf, n, name, type);
   1162   1.42.2.9     lukem 	free(buf);
   1163        1.9     lukem 	if (hp == NULL)
   1164        1.9     lukem 		switch (h_errno) {
   1165        1.9     lukem 		case HOST_NOT_FOUND:
   1166        1.9     lukem 			return NS_NOTFOUND;
   1167        1.9     lukem 		case TRY_AGAIN:
   1168        1.9     lukem 			return NS_TRYAGAIN;
   1169        1.9     lukem 		default:
   1170        1.9     lukem 			return NS_UNAVAIL;
   1171        1.9     lukem 		}
   1172        1.9     lukem 	*((struct hostent **)rv) = hp;
   1173        1.9     lukem 	return NS_SUCCESS;
   1174        1.9     lukem }
   1175        1.9     lukem 
   1176       1.13  christos /*ARGSUSED*/
   1177        1.9     lukem int
   1178        1.9     lukem _dns_gethtbyaddr(rv, cb_data, ap)
   1179        1.9     lukem 	void	*rv;
   1180        1.9     lukem 	void	*cb_data;
   1181        1.9     lukem 	va_list	 ap;
   1182        1.9     lukem {
   1183   1.42.2.6     lukem 	char qbuf[MAXDNAME + 1], *qp, *ep;
   1184        1.9     lukem 	int n;
   1185   1.42.2.9     lukem 	querybuf *buf;
   1186        1.9     lukem 	struct hostent *hp;
   1187        1.9     lukem 	const unsigned char *uaddr;
   1188   1.42.2.4     lukem 	int len, af, advance;
   1189        1.9     lukem 
   1190       1.25     lukem 	_DIAGASSERT(rv != NULL);
   1191       1.25     lukem 
   1192        1.9     lukem 	uaddr = va_arg(ap, unsigned char *);
   1193        1.9     lukem 	len = va_arg(ap, int);
   1194        1.9     lukem 	af = va_arg(ap, int);
   1195        1.9     lukem 
   1196        1.9     lukem 	switch (af) {
   1197        1.9     lukem 	case AF_INET:
   1198   1.42.2.4     lukem 		(void)snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa",
   1199   1.42.2.4     lukem 		    (uaddr[3] & 0xff), (uaddr[2] & 0xff),
   1200   1.42.2.4     lukem 		    (uaddr[1] & 0xff), (uaddr[0] & 0xff));
   1201        1.9     lukem 		break;
   1202        1.9     lukem 
   1203        1.9     lukem 	case AF_INET6:
   1204        1.9     lukem 		qp = qbuf;
   1205   1.42.2.6     lukem 		ep = qbuf + sizeof(qbuf) - 1;
   1206        1.9     lukem 		for (n = IN6ADDRSZ - 1; n >= 0; n--) {
   1207   1.42.2.6     lukem 			advance = snprintf(qp, (size_t)(ep - qp), "%x.%x.",
   1208   1.42.2.6     lukem 			    uaddr[n] & 0xf,
   1209   1.42.2.4     lukem 			    ((unsigned int)uaddr[n] >> 4) & 0xf);
   1210   1.42.2.6     lukem 			if (advance > 0 && qp + advance < ep)
   1211   1.42.2.4     lukem 				qp += advance;
   1212   1.42.2.7     lukem 			else {
   1213   1.42.2.7     lukem 				h_errno = NETDB_INTERNAL;
   1214   1.42.2.4     lukem 				return NS_NOTFOUND;
   1215   1.42.2.7     lukem 			}
   1216        1.9     lukem 		}
   1217   1.42.2.7     lukem 		if (strlcat(qbuf, "ip6.arpa", sizeof(qbuf)) >= sizeof(qbuf)) {
   1218   1.42.2.7     lukem 			h_errno = NETDB_INTERNAL;
   1219   1.42.2.6     lukem 			return NS_NOTFOUND;
   1220   1.42.2.7     lukem 		}
   1221        1.9     lukem 		break;
   1222        1.9     lukem 	default:
   1223        1.9     lukem 		abort();
   1224        1.9     lukem 	}
   1225        1.9     lukem 
   1226   1.42.2.9     lukem 	buf = malloc(sizeof(*buf));
   1227   1.42.2.9     lukem 	if (buf == NULL) {
   1228   1.42.2.9     lukem 		h_errno = NETDB_INTERNAL;
   1229   1.42.2.9     lukem 		return NS_NOTFOUND;
   1230   1.42.2.9     lukem 	}
   1231   1.42.2.9     lukem 	n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof(buf->buf));
   1232        1.9     lukem 	if (n < 0) {
   1233   1.42.2.9     lukem 		free(buf);
   1234        1.9     lukem 		dprintf("res_query failed (%d)\n", n);
   1235        1.9     lukem 		return NS_NOTFOUND;
   1236        1.9     lukem 	}
   1237   1.42.2.9     lukem 	hp = getanswer(buf, n, qbuf, T_PTR);
   1238   1.42.2.9     lukem 	free(buf);
   1239        1.9     lukem 	if (hp == NULL)
   1240        1.9     lukem 		switch (h_errno) {
   1241        1.9     lukem 		case HOST_NOT_FOUND:
   1242        1.9     lukem 			return NS_NOTFOUND;
   1243        1.9     lukem 		case TRY_AGAIN:
   1244        1.9     lukem 			return NS_TRYAGAIN;
   1245        1.9     lukem 		default:
   1246        1.9     lukem 			return NS_UNAVAIL;
   1247        1.9     lukem 		}
   1248        1.9     lukem 	hp->h_addrtype = af;
   1249        1.9     lukem 	hp->h_length = len;
   1250       1.13  christos 	(void)memcpy(host_addr, uaddr, (size_t)len);
   1251       1.31  christos 	h_addr_ptrs[0] = (char *)(void *)host_addr;
   1252       1.31  christos 	h_addr_ptrs[1] = NULL;
   1253        1.9     lukem 	if (af == AF_INET && (_res.options & RES_USE_INET6)) {
   1254       1.31  christos 		map_v4v6_address((char *)(void *)host_addr,
   1255       1.31  christos 		    (char *)(void *)host_addr);
   1256        1.9     lukem 		hp->h_addrtype = AF_INET6;
   1257        1.9     lukem 		hp->h_length = IN6ADDRSZ;
   1258        1.9     lukem 	}
   1259        1.9     lukem 
   1260        1.9     lukem 	*((struct hostent **)rv) = hp;
   1261        1.9     lukem 	h_errno = NETDB_SUCCESS;
   1262        1.9     lukem 	return NS_SUCCESS;
   1263        1.9     lukem }
   1264        1.9     lukem 
   1265        1.2       mrg #ifdef YP
   1266       1.13  christos /*ARGSUSED*/
   1267        1.2       mrg struct hostent *
   1268        1.9     lukem _yphostent(line, af)
   1269        1.2       mrg 	char *line;
   1270        1.9     lukem 	int af;
   1271        1.2       mrg {
   1272        1.2       mrg 	static struct in_addr host_addrs[MAXADDRS];
   1273       1.37    itojun 	static struct in6_addr host6_addrs[MAXADDRS];
   1274        1.2       mrg 	char *p = line;
   1275        1.2       mrg 	char *cp, **q;
   1276        1.2       mrg 	char **hap;
   1277       1.37    itojun 	int addrok;
   1278        1.2       mrg 	int more;
   1279       1.37    itojun 	int naddrs;
   1280        1.2       mrg 
   1281       1.25     lukem 	_DIAGASSERT(line != NULL);
   1282       1.25     lukem 
   1283        1.2       mrg 	host.h_name = NULL;
   1284        1.2       mrg 	host.h_addr_list = h_addr_ptrs;
   1285       1.37    itojun 	host.h_addrtype = af;
   1286       1.37    itojun 	switch (af) {
   1287       1.37    itojun 	case AF_INET:
   1288       1.37    itojun 		host.h_length = INADDRSZ;
   1289       1.37    itojun 		break;
   1290       1.37    itojun 	case AF_INET6:
   1291       1.37    itojun 		host.h_length = IN6ADDRSZ;
   1292       1.37    itojun 		break;
   1293       1.37    itojun 	default:
   1294       1.37    itojun 		return (NULL);
   1295       1.37    itojun 	}
   1296        1.2       mrg 	hap = h_addr_ptrs;
   1297        1.2       mrg 	q = host.h_aliases = host_aliases;
   1298       1.37    itojun 	naddrs = 0;
   1299        1.2       mrg 
   1300        1.2       mrg nextline:
   1301       1.36    itojun 	/* check for host_addrs overflow */
   1302       1.37    itojun 	if (naddrs >= sizeof(host_addrs) / sizeof(host_addrs[0]))
   1303       1.37    itojun 		goto done;
   1304       1.37    itojun 	if (naddrs >= sizeof(host6_addrs) / sizeof(host6_addrs[0]))
   1305       1.36    itojun 		goto done;
   1306       1.36    itojun 
   1307        1.2       mrg 	more = 0;
   1308        1.2       mrg 	cp = strpbrk(p, " \t");
   1309       1.36    itojun 	if (cp == NULL)
   1310       1.36    itojun 		goto done;
   1311        1.2       mrg 	*cp++ = '\0';
   1312        1.2       mrg 
   1313       1.37    itojun 	/* p has should have an address */
   1314       1.37    itojun 	switch (af) {
   1315       1.37    itojun 	case AF_INET:
   1316       1.37    itojun 		addrok = inet_aton(p, &host_addrs[naddrs]);
   1317       1.37    itojun 		break;
   1318       1.37    itojun 	case AF_INET6:
   1319       1.37    itojun 		addrok = inet_pton(af, p, &host6_addrs[naddrs]);
   1320       1.37    itojun 		break;
   1321       1.37    itojun 	}
   1322       1.37    itojun 	if (addrok != 1) {
   1323       1.37    itojun 		/* skip to the next line */
   1324       1.37    itojun 		while (cp && *cp) {
   1325       1.37    itojun 			if (*cp == '\n') {
   1326       1.37    itojun 				cp++;
   1327       1.37    itojun 				goto nextline;
   1328       1.37    itojun 			}
   1329       1.37    itojun 			cp++;
   1330       1.37    itojun 		}
   1331       1.37    itojun 
   1332       1.37    itojun 		goto done;
   1333       1.37    itojun 	}
   1334       1.37    itojun 
   1335       1.37    itojun 	switch (af) {
   1336       1.37    itojun 	case AF_INET:
   1337       1.37    itojun 		*hap++ = (char *)(void *)&host_addrs[naddrs++];
   1338       1.37    itojun 		break;
   1339       1.37    itojun 	case AF_INET6:
   1340       1.37    itojun 		*hap++ = (char *)(void *)&host6_addrs[naddrs++];
   1341       1.37    itojun 		break;
   1342       1.37    itojun 	}
   1343        1.2       mrg 
   1344        1.2       mrg 	while (*cp == ' ' || *cp == '\t')
   1345        1.2       mrg 		cp++;
   1346        1.2       mrg 	p = cp;
   1347        1.2       mrg 	cp = strpbrk(p, " \t\n");
   1348        1.2       mrg 	if (cp != NULL) {
   1349        1.2       mrg 		if (*cp == '\n')
   1350        1.2       mrg 			more = 1;
   1351        1.2       mrg 		*cp++ = '\0';
   1352        1.2       mrg 	}
   1353        1.2       mrg 	if (!host.h_name)
   1354        1.2       mrg 		host.h_name = p;
   1355        1.2       mrg 	else if (strcmp(host.h_name, p)==0)
   1356        1.2       mrg 		;
   1357        1.2       mrg 	else if (q < &host_aliases[MAXALIASES - 1])
   1358        1.2       mrg 		*q++ = p;
   1359        1.2       mrg 	p = cp;
   1360        1.2       mrg 	if (more)
   1361        1.2       mrg 		goto nextline;
   1362        1.2       mrg 
   1363        1.2       mrg 	while (cp && *cp) {
   1364        1.2       mrg 		if (*cp == ' ' || *cp == '\t') {
   1365        1.2       mrg 			cp++;
   1366        1.2       mrg 			continue;
   1367        1.2       mrg 		}
   1368        1.2       mrg 		if (*cp == '\n') {
   1369        1.2       mrg 			cp++;
   1370        1.2       mrg 			goto nextline;
   1371        1.2       mrg 		}
   1372        1.2       mrg 		if (q < &host_aliases[MAXALIASES - 1])
   1373        1.2       mrg 			*q++ = cp;
   1374        1.2       mrg 		cp = strpbrk(cp, " \t");
   1375        1.2       mrg 		if (cp != NULL)
   1376        1.2       mrg 			*cp++ = '\0';
   1377        1.2       mrg 	}
   1378       1.37    itojun 
   1379        1.2       mrg done:
   1380       1.36    itojun 	if (host.h_name == NULL)
   1381       1.36    itojun 		return (NULL);
   1382        1.2       mrg 	*q = NULL;
   1383        1.2       mrg 	*hap = NULL;
   1384        1.2       mrg 	return (&host);
   1385        1.2       mrg }
   1386        1.2       mrg 
   1387       1.13  christos /*ARGSUSED*/
   1388        1.9     lukem int
   1389        1.9     lukem _yp_gethtbyaddr(rv, cb_data, ap)
   1390        1.9     lukem 	void	*rv;
   1391        1.9     lukem 	void	*cb_data;
   1392        1.9     lukem 	va_list	 ap;
   1393        1.2       mrg {
   1394        1.2       mrg 	struct hostent *hp = (struct hostent *)NULL;
   1395        1.2       mrg 	static char *__ypcurrent;
   1396        1.2       mrg 	int __ypcurrentlen, r;
   1397       1.37    itojun 	char name[INET6_ADDRSTRLEN];	/* XXX enough? */
   1398        1.9     lukem 	const unsigned char *uaddr;
   1399       1.17  christos 	int af;
   1400       1.37    itojun 	const char *map;
   1401        1.9     lukem 
   1402       1.25     lukem 	_DIAGASSERT(rv != NULL);
   1403       1.25     lukem 
   1404        1.9     lukem 	uaddr = va_arg(ap, unsigned char *);
   1405       1.17  christos 	/* NOSTRICT skip len */(void)va_arg(ap, int);
   1406        1.9     lukem 	af = va_arg(ap, int);
   1407        1.2       mrg 
   1408        1.2       mrg 	if (!__ypdomain) {
   1409        1.2       mrg 		if (_yp_check(&__ypdomain) == 0)
   1410        1.9     lukem 			return NS_UNAVAIL;
   1411        1.2       mrg 	}
   1412        1.9     lukem 	/*
   1413       1.37    itojun 	 * XXX unfortunately, we cannot support IPv6 extended scoped address
   1414       1.37    itojun 	 * notation here.  gethostbyaddr() is not scope-aware.  too bad.
   1415        1.9     lukem 	 */
   1416       1.37    itojun 	if (inet_ntop(af, uaddr, name, sizeof(name)) == NULL)
   1417       1.37    itojun 		return NS_UNAVAIL;
   1418        1.2       mrg 	if (__ypcurrent)
   1419        1.2       mrg 		free(__ypcurrent);
   1420        1.2       mrg 	__ypcurrent = NULL;
   1421       1.37    itojun 	switch (af) {
   1422       1.37    itojun 	case AF_INET:
   1423       1.37    itojun 		map = "hosts.byaddr";
   1424       1.37    itojun 		break;
   1425       1.37    itojun 	default:
   1426       1.37    itojun 		map = "ipnodes.byaddr";
   1427       1.37    itojun 		break;
   1428       1.37    itojun 	}
   1429       1.37    itojun 	r = yp_match(__ypdomain, map, name,
   1430        1.8  christos 		(int)strlen(name), &__ypcurrent, &__ypcurrentlen);
   1431        1.2       mrg 	if (r==0)
   1432        1.9     lukem 		hp = _yphostent(__ypcurrent, af);
   1433        1.9     lukem 	if (hp==NULL) {
   1434        1.2       mrg 		h_errno = HOST_NOT_FOUND;
   1435        1.9     lukem 		return NS_NOTFOUND;
   1436        1.9     lukem 	}
   1437        1.9     lukem 	*((struct hostent **)rv) = hp;
   1438        1.9     lukem 	return NS_SUCCESS;
   1439        1.2       mrg }
   1440        1.2       mrg 
   1441       1.13  christos /*ARGSUSED*/
   1442        1.9     lukem int
   1443        1.9     lukem _yp_gethtbyname(rv, cb_data, ap)
   1444        1.9     lukem 	void	*rv;
   1445        1.9     lukem 	void	*cb_data;
   1446        1.9     lukem 	va_list	 ap;
   1447        1.2       mrg {
   1448        1.2       mrg 	struct hostent *hp = (struct hostent *)NULL;
   1449        1.2       mrg 	static char *__ypcurrent;
   1450        1.2       mrg 	int __ypcurrentlen, r;
   1451        1.9     lukem 	const char *name;
   1452       1.17  christos 	int af;
   1453       1.37    itojun 	const char *map;
   1454       1.25     lukem 
   1455       1.25     lukem 	_DIAGASSERT(rv != NULL);
   1456        1.9     lukem 
   1457        1.9     lukem 	name = va_arg(ap, char *);
   1458       1.17  christos 	/* NOSTRICT skip len */(void)va_arg(ap, int);
   1459        1.9     lukem 	af = va_arg(ap, int);
   1460        1.2       mrg 
   1461        1.2       mrg 	if (!__ypdomain) {
   1462        1.2       mrg 		if (_yp_check(&__ypdomain) == 0)
   1463        1.9     lukem 			return NS_UNAVAIL;
   1464        1.2       mrg 	}
   1465        1.2       mrg 	if (__ypcurrent)
   1466        1.2       mrg 		free(__ypcurrent);
   1467        1.2       mrg 	__ypcurrent = NULL;
   1468       1.37    itojun 	switch (af) {
   1469       1.37    itojun 	case AF_INET:
   1470       1.37    itojun 		map = "hosts.byname";
   1471       1.37    itojun 		break;
   1472       1.37    itojun 	default:
   1473       1.37    itojun 		map = "ipnodes.byname";
   1474       1.37    itojun 		break;
   1475       1.37    itojun 	}
   1476       1.37    itojun 	r = yp_match(__ypdomain, map, name,
   1477        1.8  christos 		(int)strlen(name), &__ypcurrent, &__ypcurrentlen);
   1478        1.2       mrg 	if (r==0)
   1479        1.9     lukem 		hp = _yphostent(__ypcurrent, af);
   1480        1.9     lukem 	if (hp==NULL) {
   1481        1.2       mrg 		h_errno = HOST_NOT_FOUND;
   1482        1.9     lukem 		return NS_NOTFOUND;
   1483        1.9     lukem 	}
   1484        1.9     lukem 	*((struct hostent **)rv) = hp;
   1485        1.9     lukem 	return NS_SUCCESS;
   1486        1.2       mrg }
   1487        1.2       mrg #endif
   1488