16812Sraf /*
2*9694SScott.Rotondo@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
36812Sraf * Use is subject to license terms.
46812Sraf */
56812Sraf
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate * Copyright (c) 1985, 1988 Regents of the University of California.
80Sstevel@tonic-gate * All rights reserved.
90Sstevel@tonic-gate *
100Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted
110Sstevel@tonic-gate * provided that this notice is preserved and that due credit is given
120Sstevel@tonic-gate * to the University of California at Berkeley. The name of the University
130Sstevel@tonic-gate * may not be used to endorse or promote products derived from this
140Sstevel@tonic-gate * software without specific prior written permission. This software
150Sstevel@tonic-gate * is provided ``as is'' without express or implied warranty.
160Sstevel@tonic-gate *
170Sstevel@tonic-gate */
180Sstevel@tonic-gate
190Sstevel@tonic-gate #include <sys/param.h>
200Sstevel@tonic-gate #include <sys/socket.h>
210Sstevel@tonic-gate #include <netinet/in.h>
220Sstevel@tonic-gate #include <ctype.h>
230Sstevel@tonic-gate #include <netdb.h>
240Sstevel@tonic-gate #include <stdio.h>
250Sstevel@tonic-gate #include <errno.h>
260Sstevel@tonic-gate #include <arpa/inet.h>
270Sstevel@tonic-gate #include <arpa/nameser.h>
280Sstevel@tonic-gate #include <resolv.h>
290Sstevel@tonic-gate #include <syslog.h>
300Sstevel@tonic-gate
310Sstevel@tonic-gate /*
320Sstevel@tonic-gate * When the name service switch calls libresolv, it doesn't want fallback
330Sstevel@tonic-gate * to /etc/hosts, so we provide a method to turn it off.
340Sstevel@tonic-gate */
350Sstevel@tonic-gate static int no_hosts_fallback = 0;
360Sstevel@tonic-gate
370Sstevel@tonic-gate void
__res_set_no_hosts_fallback(void)380Sstevel@tonic-gate __res_set_no_hosts_fallback(void) {
390Sstevel@tonic-gate no_hosts_fallback = 1;
400Sstevel@tonic-gate }
410Sstevel@tonic-gate
420Sstevel@tonic-gate static int
__res_no_hosts_fallback(void)430Sstevel@tonic-gate __res_no_hosts_fallback(void) {
440Sstevel@tonic-gate return(no_hosts_fallback);
450Sstevel@tonic-gate }
460Sstevel@tonic-gate
470Sstevel@tonic-gate static char *h_addr_ptrs[MAXADDRS + 1];
480Sstevel@tonic-gate
490Sstevel@tonic-gate static struct hostent host;
500Sstevel@tonic-gate static char *host_aliases[MAXALIASES];
510Sstevel@tonic-gate static char hostbuf[BUFSIZ+1];
520Sstevel@tonic-gate static struct in_addr host_addr;
530Sstevel@tonic-gate static char HOSTDB[] = "/etc/hosts";
540Sstevel@tonic-gate static FILE *hostf = NULL;
550Sstevel@tonic-gate static char hostaddr[MAXADDRS];
560Sstevel@tonic-gate static char *host_addrs[2];
570Sstevel@tonic-gate static int stayopen = 0;
580Sstevel@tonic-gate static char *any();
590Sstevel@tonic-gate
600Sstevel@tonic-gate #if PACKETSZ > 1024
610Sstevel@tonic-gate #define MAXPACKET PACKETSZ
620Sstevel@tonic-gate #else
630Sstevel@tonic-gate #define MAXPACKET 1024
640Sstevel@tonic-gate #endif
650Sstevel@tonic-gate
660Sstevel@tonic-gate typedef union {
670Sstevel@tonic-gate HEADER hdr;
680Sstevel@tonic-gate u_char buf[MAXPACKET];
690Sstevel@tonic-gate } querybuf;
700Sstevel@tonic-gate
710Sstevel@tonic-gate static union {
720Sstevel@tonic-gate long al;
730Sstevel@tonic-gate char ac;
740Sstevel@tonic-gate } align;
750Sstevel@tonic-gate
760Sstevel@tonic-gate
770Sstevel@tonic-gate int h_errno;
780Sstevel@tonic-gate
790Sstevel@tonic-gate static struct hostent *
getanswer(answer,anslen,iquery)800Sstevel@tonic-gate getanswer(answer, anslen, iquery)
810Sstevel@tonic-gate querybuf *answer;
820Sstevel@tonic-gate int anslen;
830Sstevel@tonic-gate int iquery;
840Sstevel@tonic-gate {
850Sstevel@tonic-gate register HEADER *hp;
860Sstevel@tonic-gate register u_char *cp;
870Sstevel@tonic-gate register int n;
880Sstevel@tonic-gate u_char *eom;
890Sstevel@tonic-gate char *bp, **ap;
900Sstevel@tonic-gate int type, class, buflen, ancount, qdcount;
910Sstevel@tonic-gate int haveanswer, getclass = C_ANY;
920Sstevel@tonic-gate char **hap;
930Sstevel@tonic-gate
940Sstevel@tonic-gate eom = answer->buf + anslen;
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate * find first satisfactory answer
970Sstevel@tonic-gate */
980Sstevel@tonic-gate hp = &answer->hdr;
990Sstevel@tonic-gate ancount = ntohs(hp->ancount);
1000Sstevel@tonic-gate qdcount = ntohs(hp->qdcount);
1010Sstevel@tonic-gate bp = hostbuf;
1020Sstevel@tonic-gate buflen = sizeof (hostbuf);
1030Sstevel@tonic-gate cp = answer->buf + sizeof (HEADER);
1040Sstevel@tonic-gate if (qdcount) {
1050Sstevel@tonic-gate if (iquery) {
1060Sstevel@tonic-gate if ((n = dn_expand((char *)answer->buf, eom,
1070Sstevel@tonic-gate cp, bp, buflen)) < 0) {
1080Sstevel@tonic-gate h_errno = NO_RECOVERY;
1090Sstevel@tonic-gate return ((struct hostent *) NULL);
1100Sstevel@tonic-gate }
1110Sstevel@tonic-gate cp += n + QFIXEDSZ;
1120Sstevel@tonic-gate host.h_name = bp;
1130Sstevel@tonic-gate n = strlen(bp) + 1;
1140Sstevel@tonic-gate bp += n;
1150Sstevel@tonic-gate buflen -= n;
1160Sstevel@tonic-gate } else
1170Sstevel@tonic-gate cp += dn_skipname(cp, eom) + QFIXEDSZ;
1180Sstevel@tonic-gate while (--qdcount > 0)
1190Sstevel@tonic-gate cp += dn_skipname(cp, eom) + QFIXEDSZ;
1200Sstevel@tonic-gate } else if (iquery) {
1210Sstevel@tonic-gate if (hp->aa)
1220Sstevel@tonic-gate h_errno = HOST_NOT_FOUND;
1230Sstevel@tonic-gate else
1240Sstevel@tonic-gate h_errno = TRY_AGAIN;
1250Sstevel@tonic-gate return ((struct hostent *) NULL);
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate ap = host_aliases;
1280Sstevel@tonic-gate host.h_aliases = host_aliases;
1290Sstevel@tonic-gate hap = h_addr_ptrs;
1300Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
1310Sstevel@tonic-gate host.h_addr_list = h_addr_ptrs;
1320Sstevel@tonic-gate #endif
1330Sstevel@tonic-gate haveanswer = 0;
1340Sstevel@tonic-gate while (--ancount >= 0 && cp < eom && haveanswer < MAXADDRS) {
1350Sstevel@tonic-gate if ((n = dn_expand((char *)answer->buf, eom,
1360Sstevel@tonic-gate cp, bp, buflen)) < 0)
1370Sstevel@tonic-gate break;
1380Sstevel@tonic-gate cp += n;
1390Sstevel@tonic-gate type = _getshort(cp);
1400Sstevel@tonic-gate cp += sizeof (u_short);
1410Sstevel@tonic-gate class = _getshort(cp);
1420Sstevel@tonic-gate cp += sizeof (u_short) + sizeof (u_long);
1430Sstevel@tonic-gate n = _getshort(cp);
1440Sstevel@tonic-gate cp += sizeof (u_short);
1450Sstevel@tonic-gate if (type == T_CNAME) {
1460Sstevel@tonic-gate cp += n;
1470Sstevel@tonic-gate if (ap >= &host_aliases[MAXALIASES-1])
1480Sstevel@tonic-gate continue;
1490Sstevel@tonic-gate *ap++ = bp;
1500Sstevel@tonic-gate n = strlen(bp) + 1;
1510Sstevel@tonic-gate bp += n;
1520Sstevel@tonic-gate buflen -= n;
1530Sstevel@tonic-gate continue;
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate if (iquery && type == T_PTR) {
1560Sstevel@tonic-gate if ((n = dn_expand((char *)answer->buf, eom,
1570Sstevel@tonic-gate cp, bp, buflen)) < 0) {
1580Sstevel@tonic-gate cp += n;
1590Sstevel@tonic-gate continue;
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate cp += n;
1620Sstevel@tonic-gate host.h_name = bp;
1630Sstevel@tonic-gate return (&host);
1640Sstevel@tonic-gate }
1650Sstevel@tonic-gate if (iquery || type != T_A) {
1660Sstevel@tonic-gate #ifdef DEBUG
1670Sstevel@tonic-gate if (_res.options & RES_DEBUG)
1680Sstevel@tonic-gate printf("unexpected answer type %d, size %d\n",
1690Sstevel@tonic-gate type, n);
1700Sstevel@tonic-gate #endif
1710Sstevel@tonic-gate cp += n;
1720Sstevel@tonic-gate continue;
1730Sstevel@tonic-gate }
1740Sstevel@tonic-gate if (haveanswer) {
1750Sstevel@tonic-gate if (n != host.h_length) {
1760Sstevel@tonic-gate cp += n;
1770Sstevel@tonic-gate continue;
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate if (class != getclass) {
1800Sstevel@tonic-gate cp += n;
1810Sstevel@tonic-gate continue;
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate } else {
1840Sstevel@tonic-gate host.h_length = n;
1850Sstevel@tonic-gate getclass = class;
1860Sstevel@tonic-gate host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
1870Sstevel@tonic-gate if (!iquery) {
1880Sstevel@tonic-gate host.h_name = bp;
1890Sstevel@tonic-gate bp += strlen(bp) + 1;
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate bp += sizeof (align) - ((u_long)bp % sizeof (align));
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate if (bp + n >= &hostbuf[sizeof (hostbuf)]) {
1960Sstevel@tonic-gate #ifdef DEBUG
1970Sstevel@tonic-gate if (_res.options & RES_DEBUG)
1980Sstevel@tonic-gate printf("size (%d) too big\n", n);
1990Sstevel@tonic-gate #endif
2000Sstevel@tonic-gate break;
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate #ifdef SYSV
2030Sstevel@tonic-gate memcpy((void *)(*hap++ = bp), (void *)cp, n);
2040Sstevel@tonic-gate #else
2050Sstevel@tonic-gate bcopy(cp, *hap++ = bp, n);
2060Sstevel@tonic-gate #endif
2070Sstevel@tonic-gate bp += n;
2080Sstevel@tonic-gate cp += n;
2090Sstevel@tonic-gate haveanswer++;
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate if (haveanswer) {
2120Sstevel@tonic-gate *ap = NULL;
2130Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
2140Sstevel@tonic-gate *hap = NULL;
2150Sstevel@tonic-gate #else
2160Sstevel@tonic-gate host.h_addr = h_addr_ptrs[0];
2170Sstevel@tonic-gate #endif
2180Sstevel@tonic-gate return (&host);
2190Sstevel@tonic-gate } else {
2200Sstevel@tonic-gate h_errno = TRY_AGAIN;
2210Sstevel@tonic-gate return ((struct hostent *) NULL);
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate
225*9694SScott.Rotondo@Sun.COM static struct hostent *_gethtbyname();
226*9694SScott.Rotondo@Sun.COM
2270Sstevel@tonic-gate struct hostent *
res_gethostbyname(name)2280Sstevel@tonic-gate res_gethostbyname(name)
2290Sstevel@tonic-gate char *name;
2300Sstevel@tonic-gate {
2310Sstevel@tonic-gate querybuf buf;
2320Sstevel@tonic-gate register char *cp;
2330Sstevel@tonic-gate int n;
2340Sstevel@tonic-gate struct hostent *hp, *gethostdomain();
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate /*
2370Sstevel@tonic-gate * disallow names consisting only of digits/dots, unless
2380Sstevel@tonic-gate * they end in a dot.
2390Sstevel@tonic-gate */
2400Sstevel@tonic-gate if (isdigit(name[0]))
2410Sstevel@tonic-gate for (cp = name; /*EMPTY*/; ++cp) {
2420Sstevel@tonic-gate if (!*cp) {
2430Sstevel@tonic-gate if (*--cp == '.')
2440Sstevel@tonic-gate break;
2450Sstevel@tonic-gate h_errno = HOST_NOT_FOUND;
2460Sstevel@tonic-gate return ((struct hostent *) NULL);
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate if (!isdigit(*cp) && *cp != '.')
2490Sstevel@tonic-gate break;
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof (buf))) < 0) {
2530Sstevel@tonic-gate #ifdef DEBUG
2540Sstevel@tonic-gate if (_res.options & RES_DEBUG)
2550Sstevel@tonic-gate printf("res_search failed\n");
2560Sstevel@tonic-gate #endif
2570Sstevel@tonic-gate if (errno == ECONNREFUSED)
2580Sstevel@tonic-gate return (_gethtbyname(name));
2590Sstevel@tonic-gate else
2600Sstevel@tonic-gate return ((struct hostent *) NULL);
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate return (getanswer(&buf, n, 0));
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate
265*9694SScott.Rotondo@Sun.COM static struct hostent *_gethtbyaddr();
266*9694SScott.Rotondo@Sun.COM
2670Sstevel@tonic-gate static struct hostent *
_getrhbyaddr(addr,len,type)2680Sstevel@tonic-gate _getrhbyaddr(addr, len, type)
2690Sstevel@tonic-gate char *addr;
2700Sstevel@tonic-gate int len, type;
2710Sstevel@tonic-gate {
2720Sstevel@tonic-gate int n;
2730Sstevel@tonic-gate querybuf buf;
2740Sstevel@tonic-gate register struct hostent *hp;
2750Sstevel@tonic-gate char qbuf[MAXDNAME];
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate if (type != AF_INET)
2780Sstevel@tonic-gate return ((struct hostent *) NULL);
2790Sstevel@tonic-gate (void) sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
2800Sstevel@tonic-gate ((unsigned)addr[3] & 0xff),
2810Sstevel@tonic-gate ((unsigned)addr[2] & 0xff),
2820Sstevel@tonic-gate ((unsigned)addr[1] & 0xff),
2830Sstevel@tonic-gate ((unsigned)addr[0] & 0xff));
2840Sstevel@tonic-gate n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof (buf));
2850Sstevel@tonic-gate if (n < 0) {
2860Sstevel@tonic-gate #ifdef DEBUG
2870Sstevel@tonic-gate if (_res.options & RES_DEBUG)
2880Sstevel@tonic-gate printf("res_query failed\n");
2890Sstevel@tonic-gate #endif
2900Sstevel@tonic-gate if (errno == ECONNREFUSED)
2910Sstevel@tonic-gate return (_gethtbyaddr(addr, len, type));
2920Sstevel@tonic-gate return ((struct hostent *) NULL);
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate hp = getanswer(&buf, n, 1);
2950Sstevel@tonic-gate if (hp == NULL)
2960Sstevel@tonic-gate return ((struct hostent *) NULL);
2970Sstevel@tonic-gate hp->h_addrtype = type;
2980Sstevel@tonic-gate hp->h_length = len;
2990Sstevel@tonic-gate h_addr_ptrs[0] = (char *)&host_addr;
3000Sstevel@tonic-gate h_addr_ptrs[1] = (char *)0;
3010Sstevel@tonic-gate host_addr = *(struct in_addr *)addr;
3020Sstevel@tonic-gate return (hp);
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate /*
3060Sstevel@tonic-gate * First we get what the PTR record says, but do an extra call
3070Sstevel@tonic-gate * to gethostbyname() to make sure that someone is not trying to
3080Sstevel@tonic-gate * spoof us. Hopefully this is not done that often, so good
3090Sstevel@tonic-gate * performance is not really an issue.
3100Sstevel@tonic-gate */
3110Sstevel@tonic-gate struct hostent *
res_gethostbyaddr(addr,len,type)3120Sstevel@tonic-gate res_gethostbyaddr(addr, len, type)
3130Sstevel@tonic-gate char *addr;
3140Sstevel@tonic-gate int len;
3150Sstevel@tonic-gate int type;
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate char **a, hbuf[MAXHOSTNAMELEN];
3180Sstevel@tonic-gate struct hostent *hp, *hp2;
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate if ((hp = _getrhbyaddr(addr, len, type)) == (struct hostent *)NULL)
3210Sstevel@tonic-gate return ((struct hostent *)NULL);
3220Sstevel@tonic-gate
3230Sstevel@tonic-gate /* hang on to what we got as an answer */
3240Sstevel@tonic-gate (void) strcpy(hbuf, hp->h_name);
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate /* check to make sure by doing a forward query */
3270Sstevel@tonic-gate if ((hp2 = res_gethostbyname(hbuf)) != (struct hostent *)NULL)
3280Sstevel@tonic-gate for (a = hp2->h_addr_list; *a; a++)
3290Sstevel@tonic-gate #ifdef SYSV
3300Sstevel@tonic-gate if (memcmp(*a, addr, hp2->h_length) == 0)
3310Sstevel@tonic-gate #else
3320Sstevel@tonic-gate if (bcmp(*a, addr, hp2->h_length) == 0)
3330Sstevel@tonic-gate #endif
3340Sstevel@tonic-gate return (hp2);
3350Sstevel@tonic-gate
3360Sstevel@tonic-gate /*
3370Sstevel@tonic-gate * we've been spoofed, make sure to log it.
3380Sstevel@tonic-gate * XXX - syslog needs a security priority level.
3390Sstevel@tonic-gate */
3400Sstevel@tonic-gate syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", hbuf,
3410Sstevel@tonic-gate inet_ntoa(*(struct in_addr *)addr));
3420Sstevel@tonic-gate return ((struct hostent *)NULL);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate
345237Sanay static void
_sethtent(int f)346237Sanay _sethtent(int f)
3470Sstevel@tonic-gate {
348237Sanay if (__res_no_hosts_fallback()) return;
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate if (hostf == NULL)
3510Sstevel@tonic-gate hostf = fopen(HOSTDB, "r");
3520Sstevel@tonic-gate else
3530Sstevel@tonic-gate rewind(hostf);
3540Sstevel@tonic-gate stayopen |= f;
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate
357237Sanay static void
_endhtent(void)358237Sanay _endhtent(void)
3590Sstevel@tonic-gate {
360237Sanay if (__res_no_hosts_fallback()) return;
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate if (hostf && !stayopen) {
3630Sstevel@tonic-gate (void) fclose(hostf);
3640Sstevel@tonic-gate hostf = NULL;
3650Sstevel@tonic-gate }
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate
3680Sstevel@tonic-gate static struct hostent *
_gethtent()3690Sstevel@tonic-gate _gethtent()
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate char *p;
3720Sstevel@tonic-gate register char *cp, **q;
3730Sstevel@tonic-gate
3740Sstevel@tonic-gate if (__res_no_hosts_fallback()) return(NULL);
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate if (hostf == NULL && (hostf = fopen(HOSTDB, "r")) == NULL)
3770Sstevel@tonic-gate return (NULL);
3780Sstevel@tonic-gate again:
3790Sstevel@tonic-gate if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
3800Sstevel@tonic-gate return (NULL);
3810Sstevel@tonic-gate if (*p == '#')
3820Sstevel@tonic-gate goto again;
3830Sstevel@tonic-gate cp = any(p, "#\n");
3840Sstevel@tonic-gate if (cp == NULL)
3850Sstevel@tonic-gate goto again;
3860Sstevel@tonic-gate *cp = '\0';
3870Sstevel@tonic-gate cp = any(p, " \t");
3880Sstevel@tonic-gate if (cp == NULL)
3890Sstevel@tonic-gate goto again;
3900Sstevel@tonic-gate *cp++ = '\0';
3910Sstevel@tonic-gate /* THIS STUFF IS INTERNET SPECIFIC */
3920Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
3930Sstevel@tonic-gate host.h_addr_list = host_addrs;
3940Sstevel@tonic-gate #endif
3950Sstevel@tonic-gate host.h_addr = hostaddr;
3960Sstevel@tonic-gate *((u_long *)host.h_addr) = inet_addr(p);
3970Sstevel@tonic-gate host.h_length = sizeof (u_long);
3980Sstevel@tonic-gate host.h_addrtype = AF_INET;
3990Sstevel@tonic-gate while (*cp == ' ' || *cp == '\t')
4000Sstevel@tonic-gate cp++;
4010Sstevel@tonic-gate host.h_name = cp;
4020Sstevel@tonic-gate q = host.h_aliases = host_aliases;
4030Sstevel@tonic-gate cp = any(cp, " \t");
4040Sstevel@tonic-gate if (cp != NULL)
4050Sstevel@tonic-gate *cp++ = '\0';
4060Sstevel@tonic-gate while (cp && *cp) {
4070Sstevel@tonic-gate if (*cp == ' ' || *cp == '\t') {
4080Sstevel@tonic-gate cp++;
4090Sstevel@tonic-gate continue;
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate if (q < &host_aliases[MAXALIASES - 1])
4120Sstevel@tonic-gate *q++ = cp;
4130Sstevel@tonic-gate cp = any(cp, " \t");
4140Sstevel@tonic-gate if (cp != NULL)
4150Sstevel@tonic-gate *cp++ = '\0';
4160Sstevel@tonic-gate }
4170Sstevel@tonic-gate *q = NULL;
4180Sstevel@tonic-gate return (&host);
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate static char *
any(cp,match)4220Sstevel@tonic-gate any(cp, match)
4230Sstevel@tonic-gate register char *cp;
4240Sstevel@tonic-gate char *match;
4250Sstevel@tonic-gate {
4260Sstevel@tonic-gate register char *mp, c;
4270Sstevel@tonic-gate
4280Sstevel@tonic-gate while (c = *cp) {
4290Sstevel@tonic-gate for (mp = match; *mp; mp++)
4300Sstevel@tonic-gate if (*mp == c)
4310Sstevel@tonic-gate return (cp);
4320Sstevel@tonic-gate cp++;
4330Sstevel@tonic-gate }
4340Sstevel@tonic-gate return ((char *)0);
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate static struct hostent *
_gethtbyname(name)4380Sstevel@tonic-gate _gethtbyname(name)
4390Sstevel@tonic-gate char *name;
4400Sstevel@tonic-gate {
4410Sstevel@tonic-gate register struct hostent *p;
4420Sstevel@tonic-gate register char **cp;
4430Sstevel@tonic-gate
4440Sstevel@tonic-gate _sethtent(0);
4450Sstevel@tonic-gate while (p = _gethtent()) {
4460Sstevel@tonic-gate if (strcasecmp(p->h_name, name) == 0)
4470Sstevel@tonic-gate break;
4480Sstevel@tonic-gate for (cp = p->h_aliases; *cp != 0; cp++)
4490Sstevel@tonic-gate if (strcasecmp(*cp, name) == 0)
4500Sstevel@tonic-gate goto found;
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate found:
4530Sstevel@tonic-gate _endhtent();
4540Sstevel@tonic-gate return (p);
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate static struct hostent *
_gethtbyaddr(addr,len,type)4580Sstevel@tonic-gate _gethtbyaddr(addr, len, type)
4590Sstevel@tonic-gate char *addr;
4600Sstevel@tonic-gate int len, type;
4610Sstevel@tonic-gate {
4620Sstevel@tonic-gate register struct hostent *p;
4630Sstevel@tonic-gate
4640Sstevel@tonic-gate _sethtent(0);
4650Sstevel@tonic-gate while (p = _gethtent())
4660Sstevel@tonic-gate #ifdef SYSV
4670Sstevel@tonic-gate if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
4680Sstevel@tonic-gate #else
4690Sstevel@tonic-gate if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
4700Sstevel@tonic-gate #endif
4710Sstevel@tonic-gate break;
4720Sstevel@tonic-gate _endhtent();
4730Sstevel@tonic-gate return (p);
4740Sstevel@tonic-gate }
475