17c478bd9Sstevel@tonic-gate /*
2*d67944fbSScott Rotondo * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
37257d1b4Sraf * Use is subject to license terms.
47257d1b4Sraf */
57257d1b4Sraf
67257d1b4Sraf /*
77c478bd9Sstevel@tonic-gate * Copyright (c) 1985, 1988 Regents of the University of California.
87c478bd9Sstevel@tonic-gate * All rights reserved.
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted
117c478bd9Sstevel@tonic-gate * provided that this notice is preserved and that due credit is given
127c478bd9Sstevel@tonic-gate * to the University of California at Berkeley. The name of the University
137c478bd9Sstevel@tonic-gate * may not be used to endorse or promote products derived from this
147c478bd9Sstevel@tonic-gate * software without specific prior written permission. This software
157c478bd9Sstevel@tonic-gate * is provided ``as is'' without express or implied warranty.
167c478bd9Sstevel@tonic-gate *
177c478bd9Sstevel@tonic-gate */
187c478bd9Sstevel@tonic-gate
197c478bd9Sstevel@tonic-gate #include <sys/param.h>
207c478bd9Sstevel@tonic-gate #include <sys/socket.h>
217c478bd9Sstevel@tonic-gate #include <netinet/in.h>
227c478bd9Sstevel@tonic-gate #include <ctype.h>
237c478bd9Sstevel@tonic-gate #include <netdb.h>
247c478bd9Sstevel@tonic-gate #include <stdio.h>
257c478bd9Sstevel@tonic-gate #include <errno.h>
267c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
277c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
287c478bd9Sstevel@tonic-gate #include <resolv.h>
297c478bd9Sstevel@tonic-gate #include <syslog.h>
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate * When the name service switch calls libresolv, it doesn't want fallback
337c478bd9Sstevel@tonic-gate * to /etc/hosts, so we provide a method to turn it off.
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate static int no_hosts_fallback = 0;
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate void
__res_set_no_hosts_fallback(void)387c478bd9Sstevel@tonic-gate __res_set_no_hosts_fallback(void) {
397c478bd9Sstevel@tonic-gate no_hosts_fallback = 1;
407c478bd9Sstevel@tonic-gate }
417c478bd9Sstevel@tonic-gate
427c478bd9Sstevel@tonic-gate static int
__res_no_hosts_fallback(void)437c478bd9Sstevel@tonic-gate __res_no_hosts_fallback(void) {
447c478bd9Sstevel@tonic-gate return(no_hosts_fallback);
457c478bd9Sstevel@tonic-gate }
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate static char *h_addr_ptrs[MAXADDRS + 1];
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate static struct hostent host;
507c478bd9Sstevel@tonic-gate static char *host_aliases[MAXALIASES];
517c478bd9Sstevel@tonic-gate static char hostbuf[BUFSIZ+1];
527c478bd9Sstevel@tonic-gate static struct in_addr host_addr;
537c478bd9Sstevel@tonic-gate static char HOSTDB[] = "/etc/hosts";
547c478bd9Sstevel@tonic-gate static FILE *hostf = NULL;
557c478bd9Sstevel@tonic-gate static char hostaddr[MAXADDRS];
567c478bd9Sstevel@tonic-gate static char *host_addrs[2];
577c478bd9Sstevel@tonic-gate static int stayopen = 0;
587c478bd9Sstevel@tonic-gate static char *any();
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate #if PACKETSZ > 1024
617c478bd9Sstevel@tonic-gate #define MAXPACKET PACKETSZ
627c478bd9Sstevel@tonic-gate #else
637c478bd9Sstevel@tonic-gate #define MAXPACKET 1024
647c478bd9Sstevel@tonic-gate #endif
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate typedef union {
677c478bd9Sstevel@tonic-gate HEADER hdr;
687c478bd9Sstevel@tonic-gate u_char buf[MAXPACKET];
697c478bd9Sstevel@tonic-gate } querybuf;
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate static union {
727c478bd9Sstevel@tonic-gate long al;
737c478bd9Sstevel@tonic-gate char ac;
747c478bd9Sstevel@tonic-gate } align;
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate int h_errno;
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate static struct hostent *
getanswer(answer,anslen,iquery)807c478bd9Sstevel@tonic-gate getanswer(answer, anslen, iquery)
817c478bd9Sstevel@tonic-gate querybuf *answer;
827c478bd9Sstevel@tonic-gate int anslen;
837c478bd9Sstevel@tonic-gate int iquery;
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate register HEADER *hp;
867c478bd9Sstevel@tonic-gate register u_char *cp;
877c478bd9Sstevel@tonic-gate register int n;
887c478bd9Sstevel@tonic-gate u_char *eom;
897c478bd9Sstevel@tonic-gate char *bp, **ap;
907c478bd9Sstevel@tonic-gate int type, class, buflen, ancount, qdcount;
917c478bd9Sstevel@tonic-gate int haveanswer, getclass = C_ANY;
927c478bd9Sstevel@tonic-gate char **hap;
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate eom = answer->buf + anslen;
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate * find first satisfactory answer
977c478bd9Sstevel@tonic-gate */
987c478bd9Sstevel@tonic-gate hp = &answer->hdr;
997c478bd9Sstevel@tonic-gate ancount = ntohs(hp->ancount);
1007c478bd9Sstevel@tonic-gate qdcount = ntohs(hp->qdcount);
1017c478bd9Sstevel@tonic-gate bp = hostbuf;
1027c478bd9Sstevel@tonic-gate buflen = sizeof (hostbuf);
1037c478bd9Sstevel@tonic-gate cp = answer->buf + sizeof (HEADER);
1047c478bd9Sstevel@tonic-gate if (qdcount) {
1057c478bd9Sstevel@tonic-gate if (iquery) {
1067c478bd9Sstevel@tonic-gate if ((n = dn_expand((char *)answer->buf, eom,
1077c478bd9Sstevel@tonic-gate cp, bp, buflen)) < 0) {
1087c478bd9Sstevel@tonic-gate h_errno = NO_RECOVERY;
1097c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate cp += n + QFIXEDSZ;
1127c478bd9Sstevel@tonic-gate host.h_name = bp;
1137c478bd9Sstevel@tonic-gate n = strlen(bp) + 1;
1147c478bd9Sstevel@tonic-gate bp += n;
1157c478bd9Sstevel@tonic-gate buflen -= n;
1167c478bd9Sstevel@tonic-gate } else
1177c478bd9Sstevel@tonic-gate cp += dn_skipname(cp, eom) + QFIXEDSZ;
1187c478bd9Sstevel@tonic-gate while (--qdcount > 0)
1197c478bd9Sstevel@tonic-gate cp += dn_skipname(cp, eom) + QFIXEDSZ;
1207c478bd9Sstevel@tonic-gate } else if (iquery) {
1217c478bd9Sstevel@tonic-gate if (hp->aa)
1227c478bd9Sstevel@tonic-gate h_errno = HOST_NOT_FOUND;
1237c478bd9Sstevel@tonic-gate else
1247c478bd9Sstevel@tonic-gate h_errno = TRY_AGAIN;
1257c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate ap = host_aliases;
1287c478bd9Sstevel@tonic-gate host.h_aliases = host_aliases;
1297c478bd9Sstevel@tonic-gate hap = h_addr_ptrs;
1307c478bd9Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
1317c478bd9Sstevel@tonic-gate host.h_addr_list = h_addr_ptrs;
1327c478bd9Sstevel@tonic-gate #endif
1337c478bd9Sstevel@tonic-gate haveanswer = 0;
1347c478bd9Sstevel@tonic-gate while (--ancount >= 0 && cp < eom && haveanswer < MAXADDRS) {
1357c478bd9Sstevel@tonic-gate if ((n = dn_expand((char *)answer->buf, eom,
1367c478bd9Sstevel@tonic-gate cp, bp, buflen)) < 0)
1377c478bd9Sstevel@tonic-gate break;
1387c478bd9Sstevel@tonic-gate cp += n;
1397c478bd9Sstevel@tonic-gate type = _getshort(cp);
1407c478bd9Sstevel@tonic-gate cp += sizeof (u_short);
1417c478bd9Sstevel@tonic-gate class = _getshort(cp);
1427c478bd9Sstevel@tonic-gate cp += sizeof (u_short) + sizeof (u_long);
1437c478bd9Sstevel@tonic-gate n = _getshort(cp);
1447c478bd9Sstevel@tonic-gate cp += sizeof (u_short);
1457c478bd9Sstevel@tonic-gate if (type == T_CNAME) {
1467c478bd9Sstevel@tonic-gate cp += n;
1477c478bd9Sstevel@tonic-gate if (ap >= &host_aliases[MAXALIASES-1])
1487c478bd9Sstevel@tonic-gate continue;
1497c478bd9Sstevel@tonic-gate *ap++ = bp;
1507c478bd9Sstevel@tonic-gate n = strlen(bp) + 1;
1517c478bd9Sstevel@tonic-gate bp += n;
1527c478bd9Sstevel@tonic-gate buflen -= n;
1537c478bd9Sstevel@tonic-gate continue;
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate if (iquery && type == T_PTR) {
1567c478bd9Sstevel@tonic-gate if ((n = dn_expand((char *)answer->buf, eom,
1577c478bd9Sstevel@tonic-gate cp, bp, buflen)) < 0) {
1587c478bd9Sstevel@tonic-gate cp += n;
1597c478bd9Sstevel@tonic-gate continue;
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate cp += n;
1627c478bd9Sstevel@tonic-gate host.h_name = bp;
1637c478bd9Sstevel@tonic-gate return (&host);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate if (iquery || type != T_A) {
1667c478bd9Sstevel@tonic-gate #ifdef DEBUG
1677c478bd9Sstevel@tonic-gate if (_res.options & RES_DEBUG)
1687c478bd9Sstevel@tonic-gate printf("unexpected answer type %d, size %d\n",
1697c478bd9Sstevel@tonic-gate type, n);
1707c478bd9Sstevel@tonic-gate #endif
1717c478bd9Sstevel@tonic-gate cp += n;
1727c478bd9Sstevel@tonic-gate continue;
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate if (haveanswer) {
1757c478bd9Sstevel@tonic-gate if (n != host.h_length) {
1767c478bd9Sstevel@tonic-gate cp += n;
1777c478bd9Sstevel@tonic-gate continue;
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate if (class != getclass) {
1807c478bd9Sstevel@tonic-gate cp += n;
1817c478bd9Sstevel@tonic-gate continue;
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate } else {
1847c478bd9Sstevel@tonic-gate host.h_length = n;
1857c478bd9Sstevel@tonic-gate getclass = class;
1867c478bd9Sstevel@tonic-gate host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
1877c478bd9Sstevel@tonic-gate if (!iquery) {
1887c478bd9Sstevel@tonic-gate host.h_name = bp;
1897c478bd9Sstevel@tonic-gate bp += strlen(bp) + 1;
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate
1937c478bd9Sstevel@tonic-gate bp += sizeof (align) - ((u_long)bp % sizeof (align));
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate if (bp + n >= &hostbuf[sizeof (hostbuf)]) {
1967c478bd9Sstevel@tonic-gate #ifdef DEBUG
1977c478bd9Sstevel@tonic-gate if (_res.options & RES_DEBUG)
1987c478bd9Sstevel@tonic-gate printf("size (%d) too big\n", n);
1997c478bd9Sstevel@tonic-gate #endif
2007c478bd9Sstevel@tonic-gate break;
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate #ifdef SYSV
2037c478bd9Sstevel@tonic-gate memcpy((void *)(*hap++ = bp), (void *)cp, n);
2047c478bd9Sstevel@tonic-gate #else
2057c478bd9Sstevel@tonic-gate bcopy(cp, *hap++ = bp, n);
2067c478bd9Sstevel@tonic-gate #endif
2077c478bd9Sstevel@tonic-gate bp += n;
2087c478bd9Sstevel@tonic-gate cp += n;
2097c478bd9Sstevel@tonic-gate haveanswer++;
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate if (haveanswer) {
2127c478bd9Sstevel@tonic-gate *ap = NULL;
2137c478bd9Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
2147c478bd9Sstevel@tonic-gate *hap = NULL;
2157c478bd9Sstevel@tonic-gate #else
2167c478bd9Sstevel@tonic-gate host.h_addr = h_addr_ptrs[0];
2177c478bd9Sstevel@tonic-gate #endif
2187c478bd9Sstevel@tonic-gate return (&host);
2197c478bd9Sstevel@tonic-gate } else {
2207c478bd9Sstevel@tonic-gate h_errno = TRY_AGAIN;
2217c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate
225*d67944fbSScott Rotondo static struct hostent *_gethtbyname();
226*d67944fbSScott Rotondo
2277c478bd9Sstevel@tonic-gate struct hostent *
res_gethostbyname(name)2287c478bd9Sstevel@tonic-gate res_gethostbyname(name)
2297c478bd9Sstevel@tonic-gate char *name;
2307c478bd9Sstevel@tonic-gate {
2317c478bd9Sstevel@tonic-gate querybuf buf;
2327c478bd9Sstevel@tonic-gate register char *cp;
2337c478bd9Sstevel@tonic-gate int n;
2347c478bd9Sstevel@tonic-gate struct hostent *hp, *gethostdomain();
2357c478bd9Sstevel@tonic-gate
2367c478bd9Sstevel@tonic-gate /*
2377c478bd9Sstevel@tonic-gate * disallow names consisting only of digits/dots, unless
2387c478bd9Sstevel@tonic-gate * they end in a dot.
2397c478bd9Sstevel@tonic-gate */
2407c478bd9Sstevel@tonic-gate if (isdigit(name[0]))
2417c478bd9Sstevel@tonic-gate for (cp = name; /*EMPTY*/; ++cp) {
2427c478bd9Sstevel@tonic-gate if (!*cp) {
2437c478bd9Sstevel@tonic-gate if (*--cp == '.')
2447c478bd9Sstevel@tonic-gate break;
2457c478bd9Sstevel@tonic-gate h_errno = HOST_NOT_FOUND;
2467c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate if (!isdigit(*cp) && *cp != '.')
2497c478bd9Sstevel@tonic-gate break;
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof (buf))) < 0) {
2537c478bd9Sstevel@tonic-gate #ifdef DEBUG
2547c478bd9Sstevel@tonic-gate if (_res.options & RES_DEBUG)
2557c478bd9Sstevel@tonic-gate printf("res_search failed\n");
2567c478bd9Sstevel@tonic-gate #endif
2577c478bd9Sstevel@tonic-gate if (errno == ECONNREFUSED)
2587c478bd9Sstevel@tonic-gate return (_gethtbyname(name));
2597c478bd9Sstevel@tonic-gate else
2607c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate return (getanswer(&buf, n, 0));
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate
265*d67944fbSScott Rotondo static struct hostent *_gethtbyaddr();
266*d67944fbSScott Rotondo
2677c478bd9Sstevel@tonic-gate static struct hostent *
_getrhbyaddr(addr,len,type)2687c478bd9Sstevel@tonic-gate _getrhbyaddr(addr, len, type)
2697c478bd9Sstevel@tonic-gate char *addr;
2707c478bd9Sstevel@tonic-gate int len, type;
2717c478bd9Sstevel@tonic-gate {
2727c478bd9Sstevel@tonic-gate int n;
2737c478bd9Sstevel@tonic-gate querybuf buf;
2747c478bd9Sstevel@tonic-gate register struct hostent *hp;
2757c478bd9Sstevel@tonic-gate char qbuf[MAXDNAME];
2767c478bd9Sstevel@tonic-gate
2777c478bd9Sstevel@tonic-gate if (type != AF_INET)
2787c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
2797c478bd9Sstevel@tonic-gate (void) sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
2807c478bd9Sstevel@tonic-gate ((unsigned)addr[3] & 0xff),
2817c478bd9Sstevel@tonic-gate ((unsigned)addr[2] & 0xff),
2827c478bd9Sstevel@tonic-gate ((unsigned)addr[1] & 0xff),
2837c478bd9Sstevel@tonic-gate ((unsigned)addr[0] & 0xff));
2847c478bd9Sstevel@tonic-gate n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof (buf));
2857c478bd9Sstevel@tonic-gate if (n < 0) {
2867c478bd9Sstevel@tonic-gate #ifdef DEBUG
2877c478bd9Sstevel@tonic-gate if (_res.options & RES_DEBUG)
2887c478bd9Sstevel@tonic-gate printf("res_query failed\n");
2897c478bd9Sstevel@tonic-gate #endif
2907c478bd9Sstevel@tonic-gate if (errno == ECONNREFUSED)
2917c478bd9Sstevel@tonic-gate return (_gethtbyaddr(addr, len, type));
2927c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate hp = getanswer(&buf, n, 1);
2957c478bd9Sstevel@tonic-gate if (hp == NULL)
2967c478bd9Sstevel@tonic-gate return ((struct hostent *) NULL);
2977c478bd9Sstevel@tonic-gate hp->h_addrtype = type;
2987c478bd9Sstevel@tonic-gate hp->h_length = len;
2997c478bd9Sstevel@tonic-gate h_addr_ptrs[0] = (char *)&host_addr;
3007c478bd9Sstevel@tonic-gate h_addr_ptrs[1] = (char *)0;
3017c478bd9Sstevel@tonic-gate host_addr = *(struct in_addr *)addr;
3027c478bd9Sstevel@tonic-gate return (hp);
3037c478bd9Sstevel@tonic-gate }
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate /*
3067c478bd9Sstevel@tonic-gate * First we get what the PTR record says, but do an extra call
3077c478bd9Sstevel@tonic-gate * to gethostbyname() to make sure that someone is not trying to
3087c478bd9Sstevel@tonic-gate * spoof us. Hopefully this is not done that often, so good
3097c478bd9Sstevel@tonic-gate * performance is not really an issue.
3107c478bd9Sstevel@tonic-gate */
3117c478bd9Sstevel@tonic-gate struct hostent *
res_gethostbyaddr(addr,len,type)3127c478bd9Sstevel@tonic-gate res_gethostbyaddr(addr, len, type)
3137c478bd9Sstevel@tonic-gate char *addr;
3147c478bd9Sstevel@tonic-gate int len;
3157c478bd9Sstevel@tonic-gate int type;
3167c478bd9Sstevel@tonic-gate {
3177c478bd9Sstevel@tonic-gate char **a, hbuf[MAXHOSTNAMELEN];
3187c478bd9Sstevel@tonic-gate struct hostent *hp, *hp2;
3197c478bd9Sstevel@tonic-gate
3207c478bd9Sstevel@tonic-gate if ((hp = _getrhbyaddr(addr, len, type)) == (struct hostent *)NULL)
3217c478bd9Sstevel@tonic-gate return ((struct hostent *)NULL);
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate /* hang on to what we got as an answer */
3247c478bd9Sstevel@tonic-gate (void) strcpy(hbuf, hp->h_name);
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate /* check to make sure by doing a forward query */
3277c478bd9Sstevel@tonic-gate if ((hp2 = res_gethostbyname(hbuf)) != (struct hostent *)NULL)
3287c478bd9Sstevel@tonic-gate for (a = hp2->h_addr_list; *a; a++)
3297c478bd9Sstevel@tonic-gate #ifdef SYSV
3307c478bd9Sstevel@tonic-gate if (memcmp(*a, addr, hp2->h_length) == 0)
3317c478bd9Sstevel@tonic-gate #else
3327c478bd9Sstevel@tonic-gate if (bcmp(*a, addr, hp2->h_length) == 0)
3337c478bd9Sstevel@tonic-gate #endif
3347c478bd9Sstevel@tonic-gate return (hp2);
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate /*
3377c478bd9Sstevel@tonic-gate * we've been spoofed, make sure to log it.
3387c478bd9Sstevel@tonic-gate * XXX - syslog needs a security priority level.
3397c478bd9Sstevel@tonic-gate */
3407c478bd9Sstevel@tonic-gate syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", hbuf,
3417c478bd9Sstevel@tonic-gate inet_ntoa(*(struct in_addr *)addr));
3427c478bd9Sstevel@tonic-gate return ((struct hostent *)NULL);
3437c478bd9Sstevel@tonic-gate }
3447c478bd9Sstevel@tonic-gate
3456a1c6faaSanay static void
_sethtent(int f)3466a1c6faaSanay _sethtent(int f)
3477c478bd9Sstevel@tonic-gate {
3486a1c6faaSanay if (__res_no_hosts_fallback()) return;
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate if (hostf == NULL)
3517c478bd9Sstevel@tonic-gate hostf = fopen(HOSTDB, "r");
3527c478bd9Sstevel@tonic-gate else
3537c478bd9Sstevel@tonic-gate rewind(hostf);
3547c478bd9Sstevel@tonic-gate stayopen |= f;
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate
3576a1c6faaSanay static void
_endhtent(void)3586a1c6faaSanay _endhtent(void)
3597c478bd9Sstevel@tonic-gate {
3606a1c6faaSanay if (__res_no_hosts_fallback()) return;
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate if (hostf && !stayopen) {
3637c478bd9Sstevel@tonic-gate (void) fclose(hostf);
3647c478bd9Sstevel@tonic-gate hostf = NULL;
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate }
3677c478bd9Sstevel@tonic-gate
3687c478bd9Sstevel@tonic-gate static struct hostent *
_gethtent()3697c478bd9Sstevel@tonic-gate _gethtent()
3707c478bd9Sstevel@tonic-gate {
3717c478bd9Sstevel@tonic-gate char *p;
3727c478bd9Sstevel@tonic-gate register char *cp, **q;
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate if (__res_no_hosts_fallback()) return(NULL);
3757c478bd9Sstevel@tonic-gate
3767c478bd9Sstevel@tonic-gate if (hostf == NULL && (hostf = fopen(HOSTDB, "r")) == NULL)
3777c478bd9Sstevel@tonic-gate return (NULL);
3787c478bd9Sstevel@tonic-gate again:
3797c478bd9Sstevel@tonic-gate if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
3807c478bd9Sstevel@tonic-gate return (NULL);
3817c478bd9Sstevel@tonic-gate if (*p == '#')
3827c478bd9Sstevel@tonic-gate goto again;
3837c478bd9Sstevel@tonic-gate cp = any(p, "#\n");
3847c478bd9Sstevel@tonic-gate if (cp == NULL)
3857c478bd9Sstevel@tonic-gate goto again;
3867c478bd9Sstevel@tonic-gate *cp = '\0';
3877c478bd9Sstevel@tonic-gate cp = any(p, " \t");
3887c478bd9Sstevel@tonic-gate if (cp == NULL)
3897c478bd9Sstevel@tonic-gate goto again;
3907c478bd9Sstevel@tonic-gate *cp++ = '\0';
3917c478bd9Sstevel@tonic-gate /* THIS STUFF IS INTERNET SPECIFIC */
3927c478bd9Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
3937c478bd9Sstevel@tonic-gate host.h_addr_list = host_addrs;
3947c478bd9Sstevel@tonic-gate #endif
3957c478bd9Sstevel@tonic-gate host.h_addr = hostaddr;
3967c478bd9Sstevel@tonic-gate *((u_long *)host.h_addr) = inet_addr(p);
3977c478bd9Sstevel@tonic-gate host.h_length = sizeof (u_long);
3987c478bd9Sstevel@tonic-gate host.h_addrtype = AF_INET;
3997c478bd9Sstevel@tonic-gate while (*cp == ' ' || *cp == '\t')
4007c478bd9Sstevel@tonic-gate cp++;
4017c478bd9Sstevel@tonic-gate host.h_name = cp;
4027c478bd9Sstevel@tonic-gate q = host.h_aliases = host_aliases;
4037c478bd9Sstevel@tonic-gate cp = any(cp, " \t");
4047c478bd9Sstevel@tonic-gate if (cp != NULL)
4057c478bd9Sstevel@tonic-gate *cp++ = '\0';
4067c478bd9Sstevel@tonic-gate while (cp && *cp) {
4077c478bd9Sstevel@tonic-gate if (*cp == ' ' || *cp == '\t') {
4087c478bd9Sstevel@tonic-gate cp++;
4097c478bd9Sstevel@tonic-gate continue;
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate if (q < &host_aliases[MAXALIASES - 1])
4127c478bd9Sstevel@tonic-gate *q++ = cp;
4137c478bd9Sstevel@tonic-gate cp = any(cp, " \t");
4147c478bd9Sstevel@tonic-gate if (cp != NULL)
4157c478bd9Sstevel@tonic-gate *cp++ = '\0';
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate *q = NULL;
4187c478bd9Sstevel@tonic-gate return (&host);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate
4217c478bd9Sstevel@tonic-gate static char *
any(cp,match)4227c478bd9Sstevel@tonic-gate any(cp, match)
4237c478bd9Sstevel@tonic-gate register char *cp;
4247c478bd9Sstevel@tonic-gate char *match;
4257c478bd9Sstevel@tonic-gate {
4267c478bd9Sstevel@tonic-gate register char *mp, c;
4277c478bd9Sstevel@tonic-gate
4287c478bd9Sstevel@tonic-gate while (c = *cp) {
4297c478bd9Sstevel@tonic-gate for (mp = match; *mp; mp++)
4307c478bd9Sstevel@tonic-gate if (*mp == c)
4317c478bd9Sstevel@tonic-gate return (cp);
4327c478bd9Sstevel@tonic-gate cp++;
4337c478bd9Sstevel@tonic-gate }
4347c478bd9Sstevel@tonic-gate return ((char *)0);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate static struct hostent *
_gethtbyname(name)4387c478bd9Sstevel@tonic-gate _gethtbyname(name)
4397c478bd9Sstevel@tonic-gate char *name;
4407c478bd9Sstevel@tonic-gate {
4417c478bd9Sstevel@tonic-gate register struct hostent *p;
4427c478bd9Sstevel@tonic-gate register char **cp;
4437c478bd9Sstevel@tonic-gate
4447c478bd9Sstevel@tonic-gate _sethtent(0);
4457c478bd9Sstevel@tonic-gate while (p = _gethtent()) {
4467c478bd9Sstevel@tonic-gate if (strcasecmp(p->h_name, name) == 0)
4477c478bd9Sstevel@tonic-gate break;
4487c478bd9Sstevel@tonic-gate for (cp = p->h_aliases; *cp != 0; cp++)
4497c478bd9Sstevel@tonic-gate if (strcasecmp(*cp, name) == 0)
4507c478bd9Sstevel@tonic-gate goto found;
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate found:
4537c478bd9Sstevel@tonic-gate _endhtent();
4547c478bd9Sstevel@tonic-gate return (p);
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate static struct hostent *
_gethtbyaddr(addr,len,type)4587c478bd9Sstevel@tonic-gate _gethtbyaddr(addr, len, type)
4597c478bd9Sstevel@tonic-gate char *addr;
4607c478bd9Sstevel@tonic-gate int len, type;
4617c478bd9Sstevel@tonic-gate {
4627c478bd9Sstevel@tonic-gate register struct hostent *p;
4637c478bd9Sstevel@tonic-gate
4647c478bd9Sstevel@tonic-gate _sethtent(0);
4657c478bd9Sstevel@tonic-gate while (p = _gethtent())
4667c478bd9Sstevel@tonic-gate #ifdef SYSV
4677c478bd9Sstevel@tonic-gate if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
4687c478bd9Sstevel@tonic-gate #else
4697c478bd9Sstevel@tonic-gate if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
4707c478bd9Sstevel@tonic-gate #endif
4717c478bd9Sstevel@tonic-gate break;
4727c478bd9Sstevel@tonic-gate _endhtent();
4737c478bd9Sstevel@tonic-gate return (p);
4747c478bd9Sstevel@tonic-gate }
475