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