17c478bd9Sstevel@tonic-gate /*
24e567b44SStacey Marshall  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
37c478bd9Sstevel@tonic-gate  */
47c478bd9Sstevel@tonic-gate 
59525b14bSRao Shoaib 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * Copyright (c) 1985, 1989, 1993
87c478bd9Sstevel@tonic-gate  *    The Regents of the University of California.  All rights reserved.
9*55fea89dSDan Cross  *
107c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
117c478bd9Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
127c478bd9Sstevel@tonic-gate  * are met:
137c478bd9Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
147c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
157c478bd9Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
167c478bd9Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
177c478bd9Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
187c478bd9Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
197c478bd9Sstevel@tonic-gate  *    must display the following acknowledgement:
207c478bd9Sstevel@tonic-gate  * 	This product includes software developed by the University of
217c478bd9Sstevel@tonic-gate  * 	California, Berkeley and its contributors.
227c478bd9Sstevel@tonic-gate  * 4. Neither the name of the University nor the names of its contributors
237c478bd9Sstevel@tonic-gate  *    may be used to endorse or promote products derived from this software
247c478bd9Sstevel@tonic-gate  *    without specific prior written permission.
25*55fea89dSDan Cross  *
267c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
277c478bd9Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
287c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
297c478bd9Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
307c478bd9Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
317c478bd9Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
327c478bd9Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
337c478bd9Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
347c478bd9Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
357c478bd9Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
367c478bd9Sstevel@tonic-gate  * SUCH DAMAGE.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
41*55fea89dSDan Cross  *
427c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, and distribute this software for any
437c478bd9Sstevel@tonic-gate  * purpose with or without fee is hereby granted, provided that the above
447c478bd9Sstevel@tonic-gate  * copyright notice and this permission notice appear in all copies, and that
457c478bd9Sstevel@tonic-gate  * the name of Digital Equipment Corporation not be used in advertising or
467c478bd9Sstevel@tonic-gate  * publicity pertaining to distribution of the document or software without
477c478bd9Sstevel@tonic-gate  * specific, written prior permission.
48*55fea89dSDan Cross  *
497c478bd9Sstevel@tonic-gate  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
507c478bd9Sstevel@tonic-gate  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
517c478bd9Sstevel@tonic-gate  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
527c478bd9Sstevel@tonic-gate  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
537c478bd9Sstevel@tonic-gate  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
547c478bd9Sstevel@tonic-gate  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
557c478bd9Sstevel@tonic-gate  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
567c478bd9Sstevel@tonic-gate  * SOFTWARE.
577c478bd9Sstevel@tonic-gate  */
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /*
609525b14bSRao Shoaib  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
617c478bd9Sstevel@tonic-gate  * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
627c478bd9Sstevel@tonic-gate  *
637c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, and distribute this software for any
647c478bd9Sstevel@tonic-gate  * purpose with or without fee is hereby granted, provided that the above
657c478bd9Sstevel@tonic-gate  * copyright notice and this permission notice appear in all copies.
667c478bd9Sstevel@tonic-gate  *
679525b14bSRao Shoaib  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
689525b14bSRao Shoaib  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
699525b14bSRao Shoaib  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
709525b14bSRao Shoaib  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
719525b14bSRao Shoaib  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
729525b14bSRao Shoaib  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
739525b14bSRao Shoaib  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
747c478bd9Sstevel@tonic-gate  */
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate #include "port_before.h"
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate #include <sys/types.h>
797c478bd9Sstevel@tonic-gate #include <sys/param.h>
807c478bd9Sstevel@tonic-gate #include <sys/socket.h>
817c478bd9Sstevel@tonic-gate #include <sys/time.h>
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #include <netinet/in.h>
847c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
857c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate #include <ctype.h>
887c478bd9Sstevel@tonic-gate #include <stdio.h>
897c478bd9Sstevel@tonic-gate #include <stdlib.h>
907c478bd9Sstevel@tonic-gate #include <string.h>
917c478bd9Sstevel@tonic-gate #include <unistd.h>
927c478bd9Sstevel@tonic-gate #include <netdb.h>
937c478bd9Sstevel@tonic-gate 
949525b14bSRao Shoaib #ifndef HAVE_MD5
959525b14bSRao Shoaib # include "../dst/md5.h"
969525b14bSRao Shoaib #else
979525b14bSRao Shoaib # ifdef SOLARIS2
989525b14bSRao Shoaib #  include <sys/md5.h>
999525b14bSRao Shoaib # endif
1009525b14bSRao Shoaib #endif
1019525b14bSRao Shoaib #ifndef _MD5_H_
1029525b14bSRao Shoaib # define _MD5_H_ 1	/*%< make sure we do not include rsaref md5.h file */
1039525b14bSRao Shoaib #endif
1049525b14bSRao Shoaib 
1059525b14bSRao Shoaib 
1067c478bd9Sstevel@tonic-gate #include "port_after.h"
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
1097c478bd9Sstevel@tonic-gate #include <resolv.h>
1107c478bd9Sstevel@tonic-gate 
1119525b14bSRao Shoaib /* ISC purposely put port_after.h before <resolv.h> to force in6 stuff
1129525b14bSRao Shoaib  * (above) so we explicitly include port_resolv.h here */
1139525b14bSRao Shoaib #include "port_resolv.h"
1149525b14bSRao Shoaib 
1157c478bd9Sstevel@tonic-gate #include "res_private.h"
1167c478bd9Sstevel@tonic-gate 
1179525b14bSRao Shoaib /*% Options.  Should all be left alone. */
1187c478bd9Sstevel@tonic-gate #define RESOLVSORT
1197c478bd9Sstevel@tonic-gate #define DEBUG
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate #ifdef  SUNW_INITCHKIF
1227c478bd9Sstevel@tonic-gate #include <net/if.h>
1237c478bd9Sstevel@tonic-gate #include <netinet/if_ether.h>
1247c478bd9Sstevel@tonic-gate #include <sys/sockio.h>
1257c478bd9Sstevel@tonic-gate #define MAXIFS  8192
1267c478bd9Sstevel@tonic-gate #endif  /* SUNW_INITCHKIF */
1277c478bd9Sstevel@tonic-gate 
1289525b14bSRao Shoaib #ifdef SOLARIS2
1297c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
1309525b14bSRao Shoaib #endif
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate static void res_setoptions __P((res_state, const char *, const char *));
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate #ifdef RESOLVSORT
1357c478bd9Sstevel@tonic-gate static const char sort_mask[] = "/&";
1367c478bd9Sstevel@tonic-gate #define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
1377c478bd9Sstevel@tonic-gate static u_int32_t net_mask __P((struct in_addr));
1387c478bd9Sstevel@tonic-gate #endif
1397c478bd9Sstevel@tonic-gate 
1409525b14bSRao Shoaib #if !defined(isascii)	/*%< XXX - could be a function */
1417c478bd9Sstevel@tonic-gate # define isascii(c) (!(c & 0200))
1427c478bd9Sstevel@tonic-gate #endif
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate /*
1457c478bd9Sstevel@tonic-gate  * Resolver state default settings.
1467c478bd9Sstevel@tonic-gate  */
1477c478bd9Sstevel@tonic-gate 
1489525b14bSRao Shoaib /*%
1497c478bd9Sstevel@tonic-gate  * Set up default settings.  If the configuration file exist, the values
1507c478bd9Sstevel@tonic-gate  * there will have precedence.  Otherwise, the server address is set to
1517c478bd9Sstevel@tonic-gate  * INADDR_ANY and the default domain name comes from the gethostname().
1527c478bd9Sstevel@tonic-gate  *
1537c478bd9Sstevel@tonic-gate  * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
1547c478bd9Sstevel@tonic-gate  * rather than INADDR_ANY ("0.0.0.0") as the default name server address
1557c478bd9Sstevel@tonic-gate  * since it was noted that INADDR_ANY actually meant ``the first interface
1567c478bd9Sstevel@tonic-gate  * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
1577c478bd9Sstevel@tonic-gate  * it had to be "up" in order for you to reach your own name server.  It
158*55fea89dSDan Cross  * was later decided that since the recommended practice is to always
1597c478bd9Sstevel@tonic-gate  * install local static routes through 127.0.0.1 for all your network
1607c478bd9Sstevel@tonic-gate  * interfaces, that we could solve this problem without a code change.
1617c478bd9Sstevel@tonic-gate  *
1627c478bd9Sstevel@tonic-gate  * The configuration file should always be used, since it is the only way
1637c478bd9Sstevel@tonic-gate  * to specify a default domain.  If you are running a server on your local
1647c478bd9Sstevel@tonic-gate  * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
1657c478bd9Sstevel@tonic-gate  * in the configuration file.
1667c478bd9Sstevel@tonic-gate  *
1677c478bd9Sstevel@tonic-gate  * Return 0 if completes successfully, -1 on error
1687c478bd9Sstevel@tonic-gate  */
1697c478bd9Sstevel@tonic-gate int
res_ninit(res_state statp)1707c478bd9Sstevel@tonic-gate res_ninit(res_state statp) {
1717c478bd9Sstevel@tonic-gate 	extern int __res_vinit(res_state, int);
1727c478bd9Sstevel@tonic-gate 	return (__res_vinit(statp, 0));
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate 
1759525b14bSRao Shoaib /*% This function has to be reachable by res_data.c but not publically. */
1767c478bd9Sstevel@tonic-gate int
__res_vinit(res_state statp,int preinit)1777c478bd9Sstevel@tonic-gate __res_vinit(res_state statp, int preinit) {
1787c478bd9Sstevel@tonic-gate 	register FILE *fp;
1797c478bd9Sstevel@tonic-gate 	register char *cp, **pp;
1807c478bd9Sstevel@tonic-gate 	register int n;
1817c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ];
1829525b14bSRao Shoaib 	int nserv = 0;    /*%< number of nameserver records read from file */
1837c478bd9Sstevel@tonic-gate 	int haveenv = 0;
1847c478bd9Sstevel@tonic-gate 	int havesearch = 0;
1857c478bd9Sstevel@tonic-gate #ifdef RESOLVSORT
1867c478bd9Sstevel@tonic-gate 	int nsort = 0;
1877c478bd9Sstevel@tonic-gate 	char *net;
1887c478bd9Sstevel@tonic-gate #endif
1897c478bd9Sstevel@tonic-gate 	int dots;
1907c478bd9Sstevel@tonic-gate 	union res_sockaddr_union u[2];
1919525b14bSRao Shoaib 	int maxns = MAXNS;
1927c478bd9Sstevel@tonic-gate 
1939525b14bSRao Shoaib 	RES_SET_H_ERRNO(statp, 0);
194c16fc660Ssm 	if (statp->_u._ext.ext != NULL)
195c16fc660Ssm 		res_ndestroy(statp);
196c16fc660Ssm 
1977c478bd9Sstevel@tonic-gate 	if (!preinit) {
1987c478bd9Sstevel@tonic-gate 		statp->retrans = RES_TIMEOUT;
1997c478bd9Sstevel@tonic-gate 		statp->retry = RES_DFLRETRY;
2007c478bd9Sstevel@tonic-gate 		statp->options = RES_DEFAULT;
2019525b14bSRao Shoaib 		res_rndinit(statp);
2029525b14bSRao Shoaib 		statp->id = res_nrandomid(statp);
2037c478bd9Sstevel@tonic-gate 	}
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	memset(u, 0, sizeof(u));
2067c478bd9Sstevel@tonic-gate #ifdef USELOOPBACK
2077c478bd9Sstevel@tonic-gate 	u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
2087c478bd9Sstevel@tonic-gate #else
2097c478bd9Sstevel@tonic-gate 	u[nserv].sin.sin_addr.s_addr = INADDR_ANY;
2107c478bd9Sstevel@tonic-gate #endif
2117c478bd9Sstevel@tonic-gate 	u[nserv].sin.sin_family = AF_INET;
2127c478bd9Sstevel@tonic-gate 	u[nserv].sin.sin_port = htons(NAMESERVER_PORT);
2137c478bd9Sstevel@tonic-gate #ifdef HAVE_SA_LEN
2147c478bd9Sstevel@tonic-gate 	u[nserv].sin.sin_len = sizeof(struct sockaddr_in);
2157c478bd9Sstevel@tonic-gate #endif
2167c478bd9Sstevel@tonic-gate 	nserv++;
2177c478bd9Sstevel@tonic-gate #ifdef HAS_INET6_STRUCTS
2187c478bd9Sstevel@tonic-gate #ifdef USELOOPBACK
2197c478bd9Sstevel@tonic-gate 	u[nserv].sin6.sin6_addr = in6addr_loopback;
2207c478bd9Sstevel@tonic-gate #else
2217c478bd9Sstevel@tonic-gate 	u[nserv].sin6.sin6_addr = in6addr_any;
2227c478bd9Sstevel@tonic-gate #endif
2237c478bd9Sstevel@tonic-gate 	u[nserv].sin6.sin6_family = AF_INET6;
2247c478bd9Sstevel@tonic-gate 	u[nserv].sin6.sin6_port = htons(NAMESERVER_PORT);
2257c478bd9Sstevel@tonic-gate #ifdef HAVE_SA_LEN
2267c478bd9Sstevel@tonic-gate 	u[nserv].sin6.sin6_len = sizeof(struct sockaddr_in6);
2277c478bd9Sstevel@tonic-gate #endif
2287c478bd9Sstevel@tonic-gate 	nserv++;
2297c478bd9Sstevel@tonic-gate #endif
2307c478bd9Sstevel@tonic-gate 	statp->nscount = 0;
2317c478bd9Sstevel@tonic-gate 	statp->ndots = 1;
2327c478bd9Sstevel@tonic-gate 	statp->pfcode = 0;
2337c478bd9Sstevel@tonic-gate 	statp->_vcsock = -1;
2347c478bd9Sstevel@tonic-gate 	statp->_flags = 0;
2357c478bd9Sstevel@tonic-gate 	statp->qhook = NULL;
2367c478bd9Sstevel@tonic-gate 	statp->rhook = NULL;
2377c478bd9Sstevel@tonic-gate 	statp->_u._ext.nscount = 0;
2387c478bd9Sstevel@tonic-gate 	statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext));
2397c478bd9Sstevel@tonic-gate 	if (statp->_u._ext.ext != NULL) {
2407c478bd9Sstevel@tonic-gate 	        memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
2417c478bd9Sstevel@tonic-gate 		statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
2427c478bd9Sstevel@tonic-gate 		strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
2437c478bd9Sstevel@tonic-gate 		strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
2449525b14bSRao Shoaib 	} else {
2459525b14bSRao Shoaib 		/*
2469525b14bSRao Shoaib 		 * Historically res_init() rarely, if at all, failed.
2479525b14bSRao Shoaib 		 * Examples and applications exist which do not check
2489525b14bSRao Shoaib 		 * our return code.  Furthermore several applications
2499525b14bSRao Shoaib 		 * simply call us to get the systems domainname.  So
2509525b14bSRao Shoaib 		 * rather then immediately fail here we store the
2519525b14bSRao Shoaib 		 * failure, which is returned later, in h_errno.  And
2529525b14bSRao Shoaib 		 * prevent the collection of 'nameserver' information
2539525b14bSRao Shoaib 		 * by setting maxns to 0.  Thus applications that fail
2549525b14bSRao Shoaib 		 * to check our return code wont be able to make
2559525b14bSRao Shoaib 		 * queries anyhow.
2569525b14bSRao Shoaib 		 */
2579525b14bSRao Shoaib 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
2589525b14bSRao Shoaib 		maxns = 0;
2599525b14bSRao Shoaib 	}
2607c478bd9Sstevel@tonic-gate #ifdef RESOLVSORT
2617c478bd9Sstevel@tonic-gate 	statp->nsort = 0;
2627c478bd9Sstevel@tonic-gate #endif
2637c478bd9Sstevel@tonic-gate 	res_setservers(statp, u, nserv);
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate #ifdef  SUNW_INITCHKIF
2667c478bd9Sstevel@tonic-gate /*
2677c478bd9Sstevel@tonic-gate  * Short circuit res_init() if no non-loopback interfaces are up. This is
2687c478bd9Sstevel@tonic-gate  * done to avoid boot delays if "dns" comes before "files" in nsswitch.conf.
2697c478bd9Sstevel@tonic-gate  * An additional fix has been added to this code, to count all external
2707c478bd9Sstevel@tonic-gate  * interfaces, which includes the IPv6 interfaces. If no external interfaces
2717c478bd9Sstevel@tonic-gate  * are found, an additional check is carried out to determine if any deprecated
2727c478bd9Sstevel@tonic-gate  * interfaces are up.
2737c478bd9Sstevel@tonic-gate  */
2747c478bd9Sstevel@tonic-gate 	{
2757c478bd9Sstevel@tonic-gate 		int s;
2767c478bd9Sstevel@tonic-gate 		struct lifnum lifn;
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 		if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2797c478bd9Sstevel@tonic-gate 			perror("res_init: socket");
280c16fc660Ssm 			goto freedata;
2817c478bd9Sstevel@tonic-gate 		}
2827c478bd9Sstevel@tonic-gate 		lifn.lifn_family = AF_UNSPEC;
2837c478bd9Sstevel@tonic-gate 		lifn.lifn_flags = LIFC_EXTERNAL_SOURCE;
2847c478bd9Sstevel@tonic-gate 		if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) {
2857c478bd9Sstevel@tonic-gate 			close(s);
286c16fc660Ssm 			goto freedata;
2877c478bd9Sstevel@tonic-gate 		}
2887c478bd9Sstevel@tonic-gate 		if (lifn.lifn_count == 0) {
2897c478bd9Sstevel@tonic-gate 			/*
2907c478bd9Sstevel@tonic-gate 			 * Check if there are any deprecated interfaces up
2917c478bd9Sstevel@tonic-gate 			 */
2927c478bd9Sstevel@tonic-gate 			struct lifconf lifc;
2937c478bd9Sstevel@tonic-gate 			uchar_t *buf;
2947c478bd9Sstevel@tonic-gate 			int buflen, i, int_up = 0;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 			lifn.lifn_flags = 0;
2977c478bd9Sstevel@tonic-gate 			if ((ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) ||
2987c478bd9Sstevel@tonic-gate 					(lifn.lifn_count < 1)) {
2997c478bd9Sstevel@tonic-gate 				close(s);
300c16fc660Ssm 				goto freedata;
3017c478bd9Sstevel@tonic-gate 			}
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 			buflen = lifn.lifn_count * sizeof (struct lifreq);
3047c478bd9Sstevel@tonic-gate 			buf = (uchar_t *)malloc(buflen);
3057c478bd9Sstevel@tonic-gate 			if (buf == NULL) {
3067c478bd9Sstevel@tonic-gate 				close(s);
307c16fc660Ssm 				goto freedata;
3087c478bd9Sstevel@tonic-gate 			}
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 			lifc.lifc_family = AF_UNSPEC;
3117c478bd9Sstevel@tonic-gate 			lifc.lifc_flags = 0;
3127c478bd9Sstevel@tonic-gate 			lifc.lifc_len = buflen;
3137c478bd9Sstevel@tonic-gate 			lifc.lifc_lifcu.lifcu_buf = (caddr_t)buf;
3147c478bd9Sstevel@tonic-gate 			if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) {
3157c478bd9Sstevel@tonic-gate 				close(s);
3167c478bd9Sstevel@tonic-gate 				free(buf);
317c16fc660Ssm 				goto freedata;
3187c478bd9Sstevel@tonic-gate 			}
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 			for (i = 0; i < lifn.lifn_count; ++i) {
3217c478bd9Sstevel@tonic-gate 				struct lifreq *lreqp, lreq;
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 				lreqp = (struct lifreq *)&lifc.lifc_req[i];
3247c478bd9Sstevel@tonic-gate 				strlcpy(lreq.lifr_name, lreqp->lifr_name,
3257c478bd9Sstevel@tonic-gate 						sizeof (lreq.lifr_name));
3267c478bd9Sstevel@tonic-gate 				if (ioctl(s, SIOCGLIFFLAGS, &lreq) < 0) {
3277c478bd9Sstevel@tonic-gate 					close(s);
3287c478bd9Sstevel@tonic-gate 					free(buf);
329c16fc660Ssm 					goto freedata;
3307c478bd9Sstevel@tonic-gate 				}
3317c478bd9Sstevel@tonic-gate 				if ((lreq.lifr_flags & IFF_UP) &&
3327c478bd9Sstevel@tonic-gate 					!(lreq.lifr_flags & IFF_NOLOCAL) &&
3337c478bd9Sstevel@tonic-gate 					!(lreq.lifr_flags & IFF_NOXMIT) &&
3347c478bd9Sstevel@tonic-gate 					!(lreq.lifr_flags & IFF_LOOPBACK)) {
3357c478bd9Sstevel@tonic-gate 					int_up = 1;
3367c478bd9Sstevel@tonic-gate 					break;
3377c478bd9Sstevel@tonic-gate 				}
3387c478bd9Sstevel@tonic-gate 			}
3397c478bd9Sstevel@tonic-gate 			free(buf);
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 			if (!int_up) {
3427c478bd9Sstevel@tonic-gate 				close(s);
343c16fc660Ssm 				goto freedata;
3447c478bd9Sstevel@tonic-gate 			}
3457c478bd9Sstevel@tonic-gate 		}
3467c478bd9Sstevel@tonic-gate 		close(s);
3477c478bd9Sstevel@tonic-gate 	}
3487c478bd9Sstevel@tonic-gate #endif  /* SUNW_INITCHKIF */
3497c478bd9Sstevel@tonic-gate 
3509525b14bSRao Shoaib #ifdef	SOLARIS2
3519525b14bSRao Shoaib 	/*
3529525b14bSRao Shoaib 	 * The old libresolv derived the defaultdomain from NIS/NIS+.
3539525b14bSRao Shoaib 	 * We want to keep this behaviour
3549525b14bSRao Shoaib 	 */
3559525b14bSRao Shoaib 	{
3569525b14bSRao Shoaib 		char buf[sizeof(statp->defdname)], *cp;
3579525b14bSRao Shoaib 		int ret;
3589525b14bSRao Shoaib 
3599525b14bSRao Shoaib 		if ((ret = sysinfo(SI_SRPC_DOMAIN, buf, sizeof(buf))) > 0 &&
3609525b14bSRao Shoaib 			(unsigned int)ret <= sizeof(buf)) {
3619525b14bSRao Shoaib 			if (buf[0] == '+')
3629525b14bSRao Shoaib 				buf[0] = '.';
3639525b14bSRao Shoaib 			cp = strchr(buf, '.');
3649525b14bSRao Shoaib 			cp = (cp == NULL) ? buf : (cp + 1);
3659525b14bSRao Shoaib 			strncpy(statp->defdname, cp,
3669525b14bSRao Shoaib 				sizeof(statp->defdname) - 1);
3679525b14bSRao Shoaib 			statp->defdname[sizeof(statp->defdname) - 1] = '\0';
3689525b14bSRao Shoaib 		}
3699525b14bSRao Shoaib 	}
3709525b14bSRao Shoaib #endif	/* SOLARIS2 */
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	/* Allow user to override the local domain definition */
3737c478bd9Sstevel@tonic-gate 	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
3747c478bd9Sstevel@tonic-gate 		(void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
3757c478bd9Sstevel@tonic-gate 		statp->defdname[sizeof(statp->defdname) - 1] = '\0';
3767c478bd9Sstevel@tonic-gate 		haveenv++;
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 		/*
3797c478bd9Sstevel@tonic-gate 		 * Set search list to be blank-separated strings
3807c478bd9Sstevel@tonic-gate 		 * from rest of env value.  Permits users of LOCALDOMAIN
3817c478bd9Sstevel@tonic-gate 		 * to still have a search list, and anyone to set the
3827c478bd9Sstevel@tonic-gate 		 * one that they want to use as an individual (even more
3837c478bd9Sstevel@tonic-gate 		 * important now that the rfc1535 stuff restricts searches)
3847c478bd9Sstevel@tonic-gate 		 */
3857c478bd9Sstevel@tonic-gate 		cp = statp->defdname;
3867c478bd9Sstevel@tonic-gate 		pp = statp->dnsrch;
3877c478bd9Sstevel@tonic-gate 		*pp++ = cp;
3887c478bd9Sstevel@tonic-gate 		for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
3899525b14bSRao Shoaib 			if (*cp == '\n')	/*%< silly backwards compat */
3907c478bd9Sstevel@tonic-gate 				break;
3917c478bd9Sstevel@tonic-gate 			else if (*cp == ' ' || *cp == '\t') {
3927c478bd9Sstevel@tonic-gate 				*cp = 0;
3937c478bd9Sstevel@tonic-gate 				n = 1;
3947c478bd9Sstevel@tonic-gate 			} else if (n) {
3957c478bd9Sstevel@tonic-gate 				*pp++ = cp;
3967c478bd9Sstevel@tonic-gate 				n = 0;
3977c478bd9Sstevel@tonic-gate 				havesearch = 1;
3987c478bd9Sstevel@tonic-gate 			}
3997c478bd9Sstevel@tonic-gate 		}
4007c478bd9Sstevel@tonic-gate 		/* null terminate last domain if there are excess */
4017c478bd9Sstevel@tonic-gate 		while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
4027c478bd9Sstevel@tonic-gate 			cp++;
4037c478bd9Sstevel@tonic-gate 		*cp = '\0';
4047c478bd9Sstevel@tonic-gate 		*pp++ = 0;
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate #define	MATCH(line, name) \
4087c478bd9Sstevel@tonic-gate 	(!strncmp(line, name, sizeof(name) - 1) && \
4097c478bd9Sstevel@tonic-gate 	(line[sizeof(name) - 1] == ' ' || \
4107c478bd9Sstevel@tonic-gate 	 line[sizeof(name) - 1] == '\t'))
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	nserv = 0;
4137c478bd9Sstevel@tonic-gate 	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
4147c478bd9Sstevel@tonic-gate 	    /* read the config file */
4157c478bd9Sstevel@tonic-gate 	    while (fgets(buf, sizeof(buf), fp) != NULL) {
4167c478bd9Sstevel@tonic-gate 		/* skip comments */
4177c478bd9Sstevel@tonic-gate 		if (*buf == ';' || *buf == '#')
4187c478bd9Sstevel@tonic-gate 			continue;
4197c478bd9Sstevel@tonic-gate 		/* read default domain name */
4207c478bd9Sstevel@tonic-gate 		if (MATCH(buf, "domain")) {
4219525b14bSRao Shoaib 		    if (haveenv)	/*%< skip if have from environ */
4227c478bd9Sstevel@tonic-gate 			    continue;
4237c478bd9Sstevel@tonic-gate 		    cp = buf + sizeof("domain") - 1;
4247c478bd9Sstevel@tonic-gate 		    while (*cp == ' ' || *cp == '\t')
4257c478bd9Sstevel@tonic-gate 			    cp++;
4267c478bd9Sstevel@tonic-gate 		    if ((*cp == '\0') || (*cp == '\n'))
4277c478bd9Sstevel@tonic-gate 			    continue;
4287c478bd9Sstevel@tonic-gate 		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
4297c478bd9Sstevel@tonic-gate 		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
4307c478bd9Sstevel@tonic-gate 		    if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL)
4317c478bd9Sstevel@tonic-gate 			    *cp = '\0';
4327c478bd9Sstevel@tonic-gate 		    havesearch = 0;
4337c478bd9Sstevel@tonic-gate 		    continue;
4347c478bd9Sstevel@tonic-gate 		}
4357c478bd9Sstevel@tonic-gate 		/* set search list */
4367c478bd9Sstevel@tonic-gate 		if (MATCH(buf, "search")) {
4379525b14bSRao Shoaib 		    if (haveenv)	/*%< skip if have from environ */
4387c478bd9Sstevel@tonic-gate 			    continue;
4397c478bd9Sstevel@tonic-gate 		    cp = buf + sizeof("search") - 1;
4407c478bd9Sstevel@tonic-gate 		    while (*cp == ' ' || *cp == '\t')
4417c478bd9Sstevel@tonic-gate 			    cp++;
4427c478bd9Sstevel@tonic-gate 		    if ((*cp == '\0') || (*cp == '\n'))
4437c478bd9Sstevel@tonic-gate 			    continue;
4447c478bd9Sstevel@tonic-gate 		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
4457c478bd9Sstevel@tonic-gate 		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
4467c478bd9Sstevel@tonic-gate 		    if ((cp = strchr(statp->defdname, '\n')) != NULL)
4477c478bd9Sstevel@tonic-gate 			    *cp = '\0';
4487c478bd9Sstevel@tonic-gate 		    /*
4497c478bd9Sstevel@tonic-gate 		     * Set search list to be blank-separated strings
4507c478bd9Sstevel@tonic-gate 		     * on rest of line.
4517c478bd9Sstevel@tonic-gate 		     */
4527c478bd9Sstevel@tonic-gate 		    cp = statp->defdname;
4537c478bd9Sstevel@tonic-gate 		    pp = statp->dnsrch;
4547c478bd9Sstevel@tonic-gate 		    *pp++ = cp;
4557c478bd9Sstevel@tonic-gate 		    for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
4567c478bd9Sstevel@tonic-gate 			    if (*cp == ' ' || *cp == '\t') {
4577c478bd9Sstevel@tonic-gate 				    *cp = 0;
4587c478bd9Sstevel@tonic-gate 				    n = 1;
4597c478bd9Sstevel@tonic-gate 			    } else if (n) {
4607c478bd9Sstevel@tonic-gate 				    *pp++ = cp;
4617c478bd9Sstevel@tonic-gate 				    n = 0;
4627c478bd9Sstevel@tonic-gate 			    }
4637c478bd9Sstevel@tonic-gate 		    }
4647c478bd9Sstevel@tonic-gate 		    /* null terminate last domain if there are excess */
4657c478bd9Sstevel@tonic-gate 		    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
4667c478bd9Sstevel@tonic-gate 			    cp++;
4677c478bd9Sstevel@tonic-gate 		    *cp = '\0';
4687c478bd9Sstevel@tonic-gate 		    *pp++ = 0;
4697c478bd9Sstevel@tonic-gate 		    havesearch = 1;
4707c478bd9Sstevel@tonic-gate 		    continue;
4717c478bd9Sstevel@tonic-gate 		}
4727c478bd9Sstevel@tonic-gate 		/* read nameservers to query */
4739525b14bSRao Shoaib 		if (MATCH(buf, "nameserver") && nserv < maxns) {
4747c478bd9Sstevel@tonic-gate 		    struct addrinfo hints, *ai;
4757c478bd9Sstevel@tonic-gate 		    char sbuf[NI_MAXSERV];
4767c478bd9Sstevel@tonic-gate 		    const size_t minsiz =
4777c478bd9Sstevel@tonic-gate 		        sizeof(statp->_u._ext.ext->nsaddrs[0]);
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate 		    cp = buf + sizeof("nameserver") - 1;
4807c478bd9Sstevel@tonic-gate 		    while (*cp == ' ' || *cp == '\t')
4817c478bd9Sstevel@tonic-gate 			cp++;
4827c478bd9Sstevel@tonic-gate 		    cp[strcspn(cp, ";# \t\n")] = '\0';
4837c478bd9Sstevel@tonic-gate 		    if ((*cp != '\0') && (*cp != '\n')) {
4847c478bd9Sstevel@tonic-gate 			memset(&hints, 0, sizeof(hints));
4857c478bd9Sstevel@tonic-gate 			hints.ai_family = PF_UNSPEC;
4867c478bd9Sstevel@tonic-gate 			hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
4877c478bd9Sstevel@tonic-gate 			hints.ai_flags = AI_NUMERICHOST;
4887c478bd9Sstevel@tonic-gate 			sprintf(sbuf, "%u", NAMESERVER_PORT);
4897c478bd9Sstevel@tonic-gate 			if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
4907c478bd9Sstevel@tonic-gate 			    ai->ai_addrlen <= minsiz) {
4917c478bd9Sstevel@tonic-gate 			    if (statp->_u._ext.ext != NULL) {
4927c478bd9Sstevel@tonic-gate 				memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
4937c478bd9Sstevel@tonic-gate 				    ai->ai_addr, ai->ai_addrlen);
4947c478bd9Sstevel@tonic-gate 			    }
4957c478bd9Sstevel@tonic-gate 			    if (ai->ai_addrlen <=
4967c478bd9Sstevel@tonic-gate 			        sizeof(statp->nsaddr_list[nserv])) {
4977c478bd9Sstevel@tonic-gate 				memcpy(&statp->nsaddr_list[nserv],
4987c478bd9Sstevel@tonic-gate 				    ai->ai_addr, ai->ai_addrlen);
4997c478bd9Sstevel@tonic-gate 			    } else
5007c478bd9Sstevel@tonic-gate 				statp->nsaddr_list[nserv].sin_family = 0;
5017c478bd9Sstevel@tonic-gate 			    freeaddrinfo(ai);
5027c478bd9Sstevel@tonic-gate 			    nserv++;
5037c478bd9Sstevel@tonic-gate 			}
5047c478bd9Sstevel@tonic-gate 		    }
5057c478bd9Sstevel@tonic-gate 		    continue;
5067c478bd9Sstevel@tonic-gate 		}
5077c478bd9Sstevel@tonic-gate #ifdef RESOLVSORT
5087c478bd9Sstevel@tonic-gate 		if (MATCH(buf, "sortlist")) {
5097c478bd9Sstevel@tonic-gate 		    struct in_addr a;
5107c478bd9Sstevel@tonic-gate 
5117c478bd9Sstevel@tonic-gate 		    cp = buf + sizeof("sortlist") - 1;
5127c478bd9Sstevel@tonic-gate 		    while (nsort < MAXRESOLVSORT) {
5137c478bd9Sstevel@tonic-gate 			while (*cp == ' ' || *cp == '\t')
5147c478bd9Sstevel@tonic-gate 			    cp++;
5157c478bd9Sstevel@tonic-gate 			if (*cp == '\0' || *cp == '\n' || *cp == ';')
5167c478bd9Sstevel@tonic-gate 			    break;
5177c478bd9Sstevel@tonic-gate 			net = cp;
5187c478bd9Sstevel@tonic-gate 			while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
5197c478bd9Sstevel@tonic-gate 			       isascii(*cp) && !isspace((unsigned char)*cp))
5207c478bd9Sstevel@tonic-gate 				cp++;
5217c478bd9Sstevel@tonic-gate 			n = *cp;
5227c478bd9Sstevel@tonic-gate 			*cp = 0;
5237c478bd9Sstevel@tonic-gate 			if (inet_aton(net, &a)) {
5247c478bd9Sstevel@tonic-gate 			    statp->sort_list[nsort].addr = a;
5257c478bd9Sstevel@tonic-gate 			    if (ISSORTMASK(n)) {
5267c478bd9Sstevel@tonic-gate 				*cp++ = n;
5277c478bd9Sstevel@tonic-gate 				net = cp;
5287c478bd9Sstevel@tonic-gate 				while (*cp && *cp != ';' &&
5297c478bd9Sstevel@tonic-gate 					isascii(*cp) &&
5307c478bd9Sstevel@tonic-gate 					!isspace((unsigned char)*cp))
5317c478bd9Sstevel@tonic-gate 				    cp++;
5327c478bd9Sstevel@tonic-gate 				n = *cp;
5337c478bd9Sstevel@tonic-gate 				*cp = 0;
5347c478bd9Sstevel@tonic-gate 				if (inet_aton(net, &a)) {
5357c478bd9Sstevel@tonic-gate 				    statp->sort_list[nsort].mask = a.s_addr;
5367c478bd9Sstevel@tonic-gate 				} else {
537*55fea89dSDan Cross 				    statp->sort_list[nsort].mask =
5387c478bd9Sstevel@tonic-gate 					net_mask(statp->sort_list[nsort].addr);
5397c478bd9Sstevel@tonic-gate 				}
5407c478bd9Sstevel@tonic-gate 			    } else {
541*55fea89dSDan Cross 				statp->sort_list[nsort].mask =
5427c478bd9Sstevel@tonic-gate 				    net_mask(statp->sort_list[nsort].addr);
5437c478bd9Sstevel@tonic-gate 			    }
5447c478bd9Sstevel@tonic-gate 			    nsort++;
5457c478bd9Sstevel@tonic-gate 			}
5467c478bd9Sstevel@tonic-gate 			*cp = n;
5477c478bd9Sstevel@tonic-gate 		    }
5487c478bd9Sstevel@tonic-gate 		    continue;
5497c478bd9Sstevel@tonic-gate 		}
5507c478bd9Sstevel@tonic-gate #endif
5517c478bd9Sstevel@tonic-gate 		if (MATCH(buf, "options")) {
5527c478bd9Sstevel@tonic-gate 		    res_setoptions(statp, buf + sizeof("options") - 1, "conf");
5537c478bd9Sstevel@tonic-gate 		    continue;
5547c478bd9Sstevel@tonic-gate 		}
5557c478bd9Sstevel@tonic-gate 	    }
556*55fea89dSDan Cross 	    if (nserv > 0)
5577c478bd9Sstevel@tonic-gate 		statp->nscount = nserv;
5587c478bd9Sstevel@tonic-gate #ifdef RESOLVSORT
5597c478bd9Sstevel@tonic-gate 	    statp->nsort = nsort;
5607c478bd9Sstevel@tonic-gate #endif
5619525b14bSRao Shoaib 	    (void) fclose(fp);
5627c478bd9Sstevel@tonic-gate 	}
5637c478bd9Sstevel@tonic-gate /*
5647c478bd9Sstevel@tonic-gate  * Last chance to get a nameserver.  This should not normally
5657c478bd9Sstevel@tonic-gate  * be necessary
5667c478bd9Sstevel@tonic-gate  */
5677c478bd9Sstevel@tonic-gate #ifdef NO_RESOLV_CONF
5687c478bd9Sstevel@tonic-gate 	if(nserv == 0)
5697c478bd9Sstevel@tonic-gate 		nserv = get_nameservers(statp);
5707c478bd9Sstevel@tonic-gate #endif
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 	if (statp->defdname[0] == 0 &&
5737c478bd9Sstevel@tonic-gate 	    gethostname(buf, sizeof(statp->defdname) - 1) == 0 &&
5747c478bd9Sstevel@tonic-gate 	    (cp = strchr(buf, '.')) != NULL)
5757c478bd9Sstevel@tonic-gate 		strcpy(statp->defdname, cp + 1);
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate 	/* find components of local domain that might be searched */
5787c478bd9Sstevel@tonic-gate 	if (havesearch == 0) {
5797c478bd9Sstevel@tonic-gate 		pp = statp->dnsrch;
5807c478bd9Sstevel@tonic-gate 		*pp++ = statp->defdname;
5817c478bd9Sstevel@tonic-gate 		*pp = NULL;
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate 		dots = 0;
5847c478bd9Sstevel@tonic-gate 		for (cp = statp->defdname; *cp; cp++)
5857c478bd9Sstevel@tonic-gate 			dots += (*cp == '.');
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 		cp = statp->defdname;
5887c478bd9Sstevel@tonic-gate 		while (pp < statp->dnsrch + MAXDFLSRCH) {
5897c478bd9Sstevel@tonic-gate 			if (dots < LOCALDOMAINPARTS)
5907c478bd9Sstevel@tonic-gate 				break;
5919525b14bSRao Shoaib 			cp = strchr(cp, '.') + 1;    /*%< we know there is one */
5927c478bd9Sstevel@tonic-gate 			*pp++ = cp;
5937c478bd9Sstevel@tonic-gate 			dots--;
5947c478bd9Sstevel@tonic-gate 		}
5957c478bd9Sstevel@tonic-gate 		*pp = NULL;
5967c478bd9Sstevel@tonic-gate #ifdef DEBUG
5977c478bd9Sstevel@tonic-gate 		if (statp->options & RES_DEBUG) {
5987c478bd9Sstevel@tonic-gate 			printf(";; res_init()... default dnsrch list:\n");
5997c478bd9Sstevel@tonic-gate 			for (pp = statp->dnsrch; *pp; pp++)
6007c478bd9Sstevel@tonic-gate 				printf(";;\t%s\n", *pp);
6017c478bd9Sstevel@tonic-gate 			printf(";;\t..END..\n");
6027c478bd9Sstevel@tonic-gate 		}
6037c478bd9Sstevel@tonic-gate #endif
6047c478bd9Sstevel@tonic-gate 	}
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	if ((cp = getenv("RES_OPTIONS")) != NULL)
6077c478bd9Sstevel@tonic-gate 		res_setoptions(statp, cp, "env");
6087c478bd9Sstevel@tonic-gate 	statp->options |= RES_INIT;
6099525b14bSRao Shoaib 	return (statp->res_h_errno);
610c16fc660Ssm #ifdef  SUNW_INITCHKIF
611c16fc660Ssm freedata:
6124e567b44SStacey Marshall 	RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
613c16fc660Ssm 	if (statp->_u._ext.ext != NULL) {
614c16fc660Ssm 		free(statp->_u._ext.ext);
615c16fc660Ssm 		statp->_u._ext.ext = NULL;
616c16fc660Ssm 	}
617c16fc660Ssm 	return (-1);
618c16fc660Ssm #endif  /* SUNW_INITCHKIF */
6199525b14bSRao Shoaib 
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate static void
res_setoptions(res_state statp,const char * options,const char * source)6237c478bd9Sstevel@tonic-gate res_setoptions(res_state statp, const char *options, const char *source)
6247c478bd9Sstevel@tonic-gate {
6257c478bd9Sstevel@tonic-gate 	const char *cp = options;
6267c478bd9Sstevel@tonic-gate 	int i;
6277c478bd9Sstevel@tonic-gate 	struct __res_state_ext *ext = statp->_u._ext.ext;
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate #ifdef DEBUG
6307c478bd9Sstevel@tonic-gate 	if (statp->options & RES_DEBUG)
6317c478bd9Sstevel@tonic-gate 		printf(";; res_setoptions(\"%s\", \"%s\")...\n",
6327c478bd9Sstevel@tonic-gate 		       options, source);
6337c478bd9Sstevel@tonic-gate #endif
6347c478bd9Sstevel@tonic-gate 	while (*cp) {
6357c478bd9Sstevel@tonic-gate 		/* skip leading and inner runs of spaces */
6367c478bd9Sstevel@tonic-gate 		while (*cp == ' ' || *cp == '\t')
6377c478bd9Sstevel@tonic-gate 			cp++;
6387c478bd9Sstevel@tonic-gate 		/* search for and process individual options */
6397c478bd9Sstevel@tonic-gate 		if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
6407c478bd9Sstevel@tonic-gate 			i = atoi(cp + sizeof("ndots:") - 1);
6417c478bd9Sstevel@tonic-gate 			if (i <= RES_MAXNDOTS)
6427c478bd9Sstevel@tonic-gate 				statp->ndots = i;
6437c478bd9Sstevel@tonic-gate 			else
6447c478bd9Sstevel@tonic-gate 				statp->ndots = RES_MAXNDOTS;
6457c478bd9Sstevel@tonic-gate #ifdef DEBUG
6467c478bd9Sstevel@tonic-gate 			if (statp->options & RES_DEBUG)
6477c478bd9Sstevel@tonic-gate 				printf(";;\tndots=%d\n", statp->ndots);
6487c478bd9Sstevel@tonic-gate #endif
6497c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) {
6507c478bd9Sstevel@tonic-gate 			i = atoi(cp + sizeof("timeout:") - 1);
6517c478bd9Sstevel@tonic-gate 			if (i <= RES_MAXRETRANS)
6527c478bd9Sstevel@tonic-gate 				statp->retrans = i;
6537c478bd9Sstevel@tonic-gate 			else
6547c478bd9Sstevel@tonic-gate 				statp->retrans = RES_MAXRETRANS;
6559525b14bSRao Shoaib #ifdef DEBUG
6569525b14bSRao Shoaib 			if (statp->options & RES_DEBUG)
6579525b14bSRao Shoaib 				printf(";;\ttimeout=%d\n", statp->retrans);
6589525b14bSRao Shoaib #endif
6599525b14bSRao Shoaib #ifdef	SOLARIS2
6607c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "retrans:", sizeof("retrans:") - 1)) {
6617c478bd9Sstevel@tonic-gate 			/*
6629525b14bSRao Shoaib 		 	 * For backward compatibility, 'retrans' is
6639525b14bSRao Shoaib 		 	 * supported as an alias for 'timeout', though
6649525b14bSRao Shoaib 		 	 * without an imposed maximum.
6659525b14bSRao Shoaib 		 	 */
6667c478bd9Sstevel@tonic-gate 			statp->retrans = atoi(cp + sizeof("retrans:") - 1);
6677c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "retry:", sizeof("retry:") - 1)){
6687c478bd9Sstevel@tonic-gate 			/*
6697c478bd9Sstevel@tonic-gate 			 * For backward compatibility, 'retry' is
6707c478bd9Sstevel@tonic-gate 			 * supported as an alias for 'attempts', though
6717c478bd9Sstevel@tonic-gate 			 * without an imposed maximum.
6727c478bd9Sstevel@tonic-gate 			 */
6737c478bd9Sstevel@tonic-gate 			statp->retry = atoi(cp + sizeof("retry:") - 1);
6749525b14bSRao Shoaib #endif	/* SOLARIS2 */
6759525b14bSRao Shoaib 		} else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
6769525b14bSRao Shoaib 			i = atoi(cp + sizeof("attempts:") - 1);
6779525b14bSRao Shoaib 			if (i <= RES_MAXRETRY)
6789525b14bSRao Shoaib 				statp->retry = i;
6799525b14bSRao Shoaib 			else
6809525b14bSRao Shoaib 				statp->retry = RES_MAXRETRY;
6819525b14bSRao Shoaib #ifdef DEBUG
6829525b14bSRao Shoaib 			if (statp->options & RES_DEBUG)
6839525b14bSRao Shoaib 				printf(";;\tattempts=%d\n", statp->retry);
6849525b14bSRao Shoaib #endif
6857c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
6867c478bd9Sstevel@tonic-gate #ifdef DEBUG
6877c478bd9Sstevel@tonic-gate 			if (!(statp->options & RES_DEBUG)) {
6887c478bd9Sstevel@tonic-gate 				printf(";; res_setoptions(\"%s\", \"%s\")..\n",
6897c478bd9Sstevel@tonic-gate 				       options, source);
6907c478bd9Sstevel@tonic-gate 				statp->options |= RES_DEBUG;
6917c478bd9Sstevel@tonic-gate 			}
6927c478bd9Sstevel@tonic-gate 			printf(";;\tdebug\n");
6937c478bd9Sstevel@tonic-gate #endif
6947c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "no_tld_query",
6957c478bd9Sstevel@tonic-gate 				    sizeof("no_tld_query") - 1) ||
6967c478bd9Sstevel@tonic-gate 			   !strncmp(cp, "no-tld-query",
6977c478bd9Sstevel@tonic-gate 				    sizeof("no-tld-query") - 1)) {
6987c478bd9Sstevel@tonic-gate 			statp->options |= RES_NOTLDQUERY;
6997c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
7007c478bd9Sstevel@tonic-gate 			statp->options |= RES_USE_INET6;
7017c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
7027c478bd9Sstevel@tonic-gate 			statp->options |= RES_ROTATE;
7037c478bd9Sstevel@tonic-gate 		} else if (!strncmp(cp, "no-check-names",
7047c478bd9Sstevel@tonic-gate 				    sizeof("no-check-names") - 1)) {
7057c478bd9Sstevel@tonic-gate 			statp->options |= RES_NOCHECKNAME;
7067c478bd9Sstevel@tonic-gate 		}
7077c478bd9Sstevel@tonic-gate #ifdef RES_USE_EDNS0
7087c478bd9Sstevel@tonic-gate 		else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
7097c478bd9Sstevel@tonic-gate 			statp->options |= RES_USE_EDNS0;
7107c478bd9Sstevel@tonic-gate 		}
7117c478bd9Sstevel@tonic-gate #endif
7127c478bd9Sstevel@tonic-gate 		else if (!strncmp(cp, "dname", sizeof("dname") - 1)) {
7137c478bd9Sstevel@tonic-gate 			statp->options |= RES_USE_DNAME;
7147c478bd9Sstevel@tonic-gate 		}
7157c478bd9Sstevel@tonic-gate 		else if (!strncmp(cp, "nibble:", sizeof("nibble:") - 1)) {
7167c478bd9Sstevel@tonic-gate 			if (ext == NULL)
7177c478bd9Sstevel@tonic-gate 				goto skip;
7187c478bd9Sstevel@tonic-gate 			cp += sizeof("nibble:") - 1;
7197c478bd9Sstevel@tonic-gate 			i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1);
7207c478bd9Sstevel@tonic-gate 			strncpy(ext->nsuffix, cp, i);
7217c478bd9Sstevel@tonic-gate 			ext->nsuffix[i] = '\0';
7227c478bd9Sstevel@tonic-gate 		}
7237c478bd9Sstevel@tonic-gate 		else if (!strncmp(cp, "nibble2:", sizeof("nibble2:") - 1)) {
7247c478bd9Sstevel@tonic-gate 			if (ext == NULL)
7257c478bd9Sstevel@tonic-gate 				goto skip;
7267c478bd9Sstevel@tonic-gate 			cp += sizeof("nibble2:") - 1;
7277c478bd9Sstevel@tonic-gate 			i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix2) - 1);
7287c478bd9Sstevel@tonic-gate 			strncpy(ext->nsuffix2, cp, i);
7297c478bd9Sstevel@tonic-gate 			ext->nsuffix2[i] = '\0';
7307c478bd9Sstevel@tonic-gate 		}
7317c478bd9Sstevel@tonic-gate 		else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) {
7327c478bd9Sstevel@tonic-gate 			cp += sizeof("v6revmode:") - 1;
7337c478bd9Sstevel@tonic-gate 			/* "nibble" and "bitstring" used to be valid */
7347c478bd9Sstevel@tonic-gate 			if (!strncmp(cp, "single", sizeof("single") - 1)) {
7357c478bd9Sstevel@tonic-gate 				statp->options |= RES_NO_NIBBLE2;
7367c478bd9Sstevel@tonic-gate 			} else if (!strncmp(cp, "both", sizeof("both") - 1)) {
7377c478bd9Sstevel@tonic-gate 				statp->options &=
7387c478bd9Sstevel@tonic-gate 					 ~RES_NO_NIBBLE2;
7397c478bd9Sstevel@tonic-gate 			}
7407c478bd9Sstevel@tonic-gate 		}
7417c478bd9Sstevel@tonic-gate 		else {
7427c478bd9Sstevel@tonic-gate 			/* XXX - print a warning here? */
7437c478bd9Sstevel@tonic-gate 		}
7447c478bd9Sstevel@tonic-gate    skip:
7457c478bd9Sstevel@tonic-gate 		/* skip to next run of spaces */
7467c478bd9Sstevel@tonic-gate 		while (*cp && *cp != ' ' && *cp != '\t')
7477c478bd9Sstevel@tonic-gate 			cp++;
7487c478bd9Sstevel@tonic-gate 	}
7497c478bd9Sstevel@tonic-gate }
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate #ifdef RESOLVSORT
7527c478bd9Sstevel@tonic-gate /* XXX - should really support CIDR which means explicit masks always. */
7537c478bd9Sstevel@tonic-gate static u_int32_t
net_mask(in)7549525b14bSRao Shoaib net_mask(in)		/*!< XXX - should really use system's version of this  */
7557c478bd9Sstevel@tonic-gate 	struct in_addr in;
7567c478bd9Sstevel@tonic-gate {
7577c478bd9Sstevel@tonic-gate 	register u_int32_t i = ntohl(in.s_addr);
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 	if (IN_CLASSA(i))
7607c478bd9Sstevel@tonic-gate 		return (htonl(IN_CLASSA_NET));
7617c478bd9Sstevel@tonic-gate 	else if (IN_CLASSB(i))
7627c478bd9Sstevel@tonic-gate 		return (htonl(IN_CLASSB_NET));
7637c478bd9Sstevel@tonic-gate 	return (htonl(IN_CLASSC_NET));
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate #endif
7667c478bd9Sstevel@tonic-gate 
7679525b14bSRao Shoaib void
res_rndinit(res_state statp)7689525b14bSRao Shoaib res_rndinit(res_state statp)
7699525b14bSRao Shoaib {
7709525b14bSRao Shoaib 	struct timeval now;
7719525b14bSRao Shoaib 	u_int32_t u32;
7729525b14bSRao Shoaib 	u_int16_t u16;
7739525b14bSRao Shoaib 
7749525b14bSRao Shoaib 	gettimeofday(&now, NULL);
7759525b14bSRao Shoaib 	u32 = now.tv_sec;
7769525b14bSRao Shoaib 	memcpy(statp->_u._ext._rnd, &u32, 4);
7779525b14bSRao Shoaib 	u32 = now.tv_usec;
7789525b14bSRao Shoaib 	memcpy(statp->_u._ext._rnd + 4, &u32, 4);
7799525b14bSRao Shoaib 	u32 += now.tv_sec;
7809525b14bSRao Shoaib 	memcpy(statp->_u._ext._rnd + 8, &u32, 4);
7819525b14bSRao Shoaib 	u16 = getpid();
7829525b14bSRao Shoaib 	memcpy(statp->_u._ext._rnd + 12, &u16, 2);
7839525b14bSRao Shoaib 
7849525b14bSRao Shoaib }
7859525b14bSRao Shoaib 
7867c478bd9Sstevel@tonic-gate u_int
res_nrandomid(res_state statp)7879525b14bSRao Shoaib res_nrandomid(res_state statp) {
7887c478bd9Sstevel@tonic-gate 	struct timeval now;
7899525b14bSRao Shoaib 	u_int16_t u16;
7909525b14bSRao Shoaib 	MD5_CTX ctx;
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate 	gettimeofday(&now, NULL);
7939525b14bSRao Shoaib 	u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec);
7949525b14bSRao Shoaib 
7959525b14bSRao Shoaib 	memcpy(statp->_u._ext._rnd + 14, &u16, 2);
7969525b14bSRao Shoaib #ifndef HAVE_MD5
7979525b14bSRao Shoaib 	MD5_Init(&ctx);
7989525b14bSRao Shoaib 	MD5_Update(&ctx, statp->_u._ext._rnd, 16);
7999525b14bSRao Shoaib 	MD5_Final(statp->_u._ext._rnd, &ctx);
8009525b14bSRao Shoaib #else
8019525b14bSRao Shoaib 	MD5Init(&ctx);
8029525b14bSRao Shoaib 	MD5Update(&ctx, statp->_u._ext._rnd, 16);
8039525b14bSRao Shoaib 	MD5Final(statp->_u._ext._rnd, &ctx);
8049525b14bSRao Shoaib #endif
8059525b14bSRao Shoaib 	memcpy(&u16, statp->_u._ext._rnd + 14, 2);
8069525b14bSRao Shoaib 	return ((u_int) u16);
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate 
8099525b14bSRao Shoaib /*%
8107c478bd9Sstevel@tonic-gate  * This routine is for closing the socket if a virtual circuit is used and
8117c478bd9Sstevel@tonic-gate  * the program wants to close it.  This provides support for endhostent()
8127c478bd9Sstevel@tonic-gate  * which expects to close the socket.
8137c478bd9Sstevel@tonic-gate  *
8147c478bd9Sstevel@tonic-gate  * This routine is not expected to be user visible.
8157c478bd9Sstevel@tonic-gate  */
8167c478bd9Sstevel@tonic-gate void
res_nclose(res_state statp)8177c478bd9Sstevel@tonic-gate res_nclose(res_state statp) {
8187c478bd9Sstevel@tonic-gate 	int ns;
8197c478bd9Sstevel@tonic-gate 
820*55fea89dSDan Cross 	if (statp->_vcsock >= 0) {
8217c478bd9Sstevel@tonic-gate 		(void) close(statp->_vcsock);
8227c478bd9Sstevel@tonic-gate 		statp->_vcsock = -1;
8237c478bd9Sstevel@tonic-gate 		statp->_flags &= ~(RES_F_VC | RES_F_CONN);
8247c478bd9Sstevel@tonic-gate 	}
8257c478bd9Sstevel@tonic-gate 	for (ns = 0; ns < statp->_u._ext.nscount; ns++) {
8267c478bd9Sstevel@tonic-gate 		if (statp->_u._ext.nssocks[ns] != -1) {
8277c478bd9Sstevel@tonic-gate 			(void) close(statp->_u._ext.nssocks[ns]);
8287c478bd9Sstevel@tonic-gate 			statp->_u._ext.nssocks[ns] = -1;
8297c478bd9Sstevel@tonic-gate 		}
8307c478bd9Sstevel@tonic-gate 	}
8317c478bd9Sstevel@tonic-gate }
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate void
res_ndestroy(res_state statp)8347c478bd9Sstevel@tonic-gate res_ndestroy(res_state statp) {
8357c478bd9Sstevel@tonic-gate 	res_nclose(statp);
8367c478bd9Sstevel@tonic-gate 	if (statp->_u._ext.ext != NULL)
8377c478bd9Sstevel@tonic-gate 		free(statp->_u._ext.ext);
8387c478bd9Sstevel@tonic-gate 	statp->options &= ~RES_INIT;
8397c478bd9Sstevel@tonic-gate 	statp->_u._ext.ext = NULL;
8407c478bd9Sstevel@tonic-gate }
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate const char *
res_get_nibblesuffix(res_state statp)8437c478bd9Sstevel@tonic-gate res_get_nibblesuffix(res_state statp) {
8447c478bd9Sstevel@tonic-gate 	if (statp->_u._ext.ext)
8457c478bd9Sstevel@tonic-gate 		return (statp->_u._ext.ext->nsuffix);
8467c478bd9Sstevel@tonic-gate 	return ("ip6.arpa");
8477c478bd9Sstevel@tonic-gate }
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate const char *
res_get_nibblesuffix2(res_state statp)8507c478bd9Sstevel@tonic-gate res_get_nibblesuffix2(res_state statp) {
8517c478bd9Sstevel@tonic-gate 	if (statp->_u._ext.ext)
8527c478bd9Sstevel@tonic-gate 		return (statp->_u._ext.ext->nsuffix2);
8537c478bd9Sstevel@tonic-gate 	return ("ip6.int");
8547c478bd9Sstevel@tonic-gate }
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate void
res_setservers(res_state statp,const union res_sockaddr_union * set,int cnt)8577c478bd9Sstevel@tonic-gate res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) {
8587c478bd9Sstevel@tonic-gate 	int i, nserv;
8597c478bd9Sstevel@tonic-gate 	size_t size;
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 	/* close open servers */
8627c478bd9Sstevel@tonic-gate 	res_nclose(statp);
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 	/* cause rtt times to be forgotten */
8657c478bd9Sstevel@tonic-gate 	statp->_u._ext.nscount = 0;
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 	nserv = 0;
8687c478bd9Sstevel@tonic-gate 	for (i = 0; i < cnt && nserv < MAXNS; i++) {
8697c478bd9Sstevel@tonic-gate 		switch (set->sin.sin_family) {
8707c478bd9Sstevel@tonic-gate 		case AF_INET:
8717c478bd9Sstevel@tonic-gate 			size = sizeof(set->sin);
8727c478bd9Sstevel@tonic-gate 			if (statp->_u._ext.ext)
8737c478bd9Sstevel@tonic-gate 				memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
8747c478bd9Sstevel@tonic-gate 					&set->sin, size);
8757c478bd9Sstevel@tonic-gate 			if (size <= sizeof(statp->nsaddr_list[nserv]))
8767c478bd9Sstevel@tonic-gate 				memcpy(&statp->nsaddr_list[nserv],
8777c478bd9Sstevel@tonic-gate 					&set->sin, size);
8787c478bd9Sstevel@tonic-gate 			else
8797c478bd9Sstevel@tonic-gate 				statp->nsaddr_list[nserv].sin_family = 0;
8807c478bd9Sstevel@tonic-gate 			nserv++;
8817c478bd9Sstevel@tonic-gate 			break;
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate #ifdef HAS_INET6_STRUCTS
8847c478bd9Sstevel@tonic-gate 		case AF_INET6:
8857c478bd9Sstevel@tonic-gate 			size = sizeof(set->sin6);
8867c478bd9Sstevel@tonic-gate 			if (statp->_u._ext.ext)
8877c478bd9Sstevel@tonic-gate 				memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
8887c478bd9Sstevel@tonic-gate 					&set->sin6, size);
8897c478bd9Sstevel@tonic-gate 			if (size <= sizeof(statp->nsaddr_list[nserv]))
8907c478bd9Sstevel@tonic-gate 				memcpy(&statp->nsaddr_list[nserv],
8917c478bd9Sstevel@tonic-gate 					&set->sin6, size);
8927c478bd9Sstevel@tonic-gate 			else
8937c478bd9Sstevel@tonic-gate 				statp->nsaddr_list[nserv].sin_family = 0;
8947c478bd9Sstevel@tonic-gate 			nserv++;
8957c478bd9Sstevel@tonic-gate 			break;
8967c478bd9Sstevel@tonic-gate #endif
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 		default:
8997c478bd9Sstevel@tonic-gate 			break;
9007c478bd9Sstevel@tonic-gate 		}
9017c478bd9Sstevel@tonic-gate 		set++;
9027c478bd9Sstevel@tonic-gate 	}
9037c478bd9Sstevel@tonic-gate 	statp->nscount = nserv;
904*55fea89dSDan Cross 
9057c478bd9Sstevel@tonic-gate }
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate int
res_getservers(res_state statp,union res_sockaddr_union * set,int cnt)9087c478bd9Sstevel@tonic-gate res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) {
9097c478bd9Sstevel@tonic-gate 	int i;
9107c478bd9Sstevel@tonic-gate 	size_t size;
9117c478bd9Sstevel@tonic-gate 	u_int16_t family;
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	for (i = 0; i < statp->nscount && i < cnt; i++) {
9147c478bd9Sstevel@tonic-gate 		if (statp->_u._ext.ext)
9157c478bd9Sstevel@tonic-gate 			family = statp->_u._ext.ext->nsaddrs[i].sin.sin_family;
916*55fea89dSDan Cross 		else
9177c478bd9Sstevel@tonic-gate 			family = statp->nsaddr_list[i].sin_family;
9187c478bd9Sstevel@tonic-gate 
9197c478bd9Sstevel@tonic-gate 		switch (family) {
9207c478bd9Sstevel@tonic-gate 		case AF_INET:
9217c478bd9Sstevel@tonic-gate 			size = sizeof(set->sin);
9227c478bd9Sstevel@tonic-gate 			if (statp->_u._ext.ext)
9237c478bd9Sstevel@tonic-gate 				memcpy(&set->sin,
9247c478bd9Sstevel@tonic-gate 				       &statp->_u._ext.ext->nsaddrs[i],
9257c478bd9Sstevel@tonic-gate 				       size);
9267c478bd9Sstevel@tonic-gate 			else
9277c478bd9Sstevel@tonic-gate 				memcpy(&set->sin, &statp->nsaddr_list[i],
9287c478bd9Sstevel@tonic-gate 				       size);
9297c478bd9Sstevel@tonic-gate 			break;
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate #ifdef HAS_INET6_STRUCTS
9327c478bd9Sstevel@tonic-gate 		case AF_INET6:
9337c478bd9Sstevel@tonic-gate 			size = sizeof(set->sin6);
9347c478bd9Sstevel@tonic-gate 			if (statp->_u._ext.ext)
9357c478bd9Sstevel@tonic-gate 				memcpy(&set->sin6,
9367c478bd9Sstevel@tonic-gate 				       &statp->_u._ext.ext->nsaddrs[i],
9377c478bd9Sstevel@tonic-gate 				       size);
9387c478bd9Sstevel@tonic-gate 			else
9397c478bd9Sstevel@tonic-gate 				memcpy(&set->sin6, &statp->nsaddr_list[i],
9407c478bd9Sstevel@tonic-gate 				       size);
9417c478bd9Sstevel@tonic-gate 			break;
9427c478bd9Sstevel@tonic-gate #endif
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate 		default:
9457c478bd9Sstevel@tonic-gate 			set->sin.sin_family = 0;
9467c478bd9Sstevel@tonic-gate 			break;
9477c478bd9Sstevel@tonic-gate 		}
9487c478bd9Sstevel@tonic-gate 		set++;
9497c478bd9Sstevel@tonic-gate 	}
9507c478bd9Sstevel@tonic-gate 	return (statp->nscount);
9517c478bd9Sstevel@tonic-gate }
9529525b14bSRao Shoaib 
9539525b14bSRao Shoaib /*! \file */
954