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