diff options
author | pst <pst@FreeBSD.org> | 1994-09-25 02:12:49 +0000 |
---|---|---|
committer | pst <pst@FreeBSD.org> | 1994-09-25 02:12:49 +0000 |
commit | 4f0d0da86d54d2621713e7d8ccfd0507888f348b (patch) | |
tree | a71412a79b4754c5fb0d8868e5fb690fde4a7fbb /lib/libc/net/gethostnamadr.c | |
parent | 860a10b12f94d28edf8ffa8a4df515be3e1d5f29 (diff) | |
download | FreeBSD-src-4f0d0da86d54d2621713e7d8ccfd0507888f348b.zip FreeBSD-src-4f0d0da86d54d2621713e7d8ccfd0507888f348b.tar.gz |
get* rework and new bind code
Diffstat (limited to 'lib/libc/net/gethostnamadr.c')
-rw-r--r-- | lib/libc/net/gethostnamadr.c | 522 |
1 files changed, 37 insertions, 485 deletions
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c index cbb7d74..1e8672a 100644 --- a/lib/libc/net/gethostnamadr.c +++ b/lib/libc/net/gethostnamadr.c @@ -1,6 +1,5 @@ /*- - * Copyright (c) 1985, 1988, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 1994, Garrett Wollman * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,15 +9,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE @@ -29,49 +21,29 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "From: @(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -/*static char rcsid[] = "From: Id: gethnamaddr.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel ";*/ -static const char rcsid[] = - "$Id: gethostnamadr.c,v 1.3 1994/08/09 22:44:12 wollman Exp $"; +static char sccsid[] = "@(#)$Id$"; +static char rcsid[] = "$Id$"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <arpa/nameser.h> #include <netdb.h> -#include <resolv.h> #include <stdio.h> #include <ctype.h> #include <errno.h> #include <string.h> -#define MAXALIASES 35 -#define MAXADDRS 35 +extern struct hostent * _gethostbyhtname __P((const char *)); +extern struct hostent * _gethostbydnsname __P((const char *)); +extern struct hostent * _gethostbynisname __P((const char *)); +extern struct hostent * _gethostbyhtaddr __P((const char *, int, int)); +extern struct hostent * _gethostbydnsaddr __P((const char *, int, int)); +extern struct hostent * _gethostbynisaddr __P((const char *, int, int)); #define _PATH_HOSTCONF "/etc/host.conf" @@ -102,35 +74,6 @@ static struct { static enum service_type service_order[SERVICE_MAX + 1]; static int service_done = 0; -static char *h_addr_ptrs[MAXADDRS + 1]; - -static struct hostent host; -static char *host_aliases[MAXALIASES]; -static char hostbuf[BUFSIZ+1]; -static struct in_addr host_addr; -static FILE *hostf = NULL; -static char hostaddr[MAXADDRS]; -static char *host_addrs[2]; -static int stayopen = 0; - -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif - -typedef union { - HEADER hdr; - u_char buf[MAXPACKET]; -} querybuf; - -typedef union { - int32_t al; - char ac; -} align; - -extern int h_errno; - static enum service_type get_service_name(const char *name) { int i; @@ -174,429 +117,27 @@ init_services() service_done = 1; } -static struct hostent * -getanswer(answer, anslen, iquery) - querybuf *answer; - int anslen; - int iquery; -{ - register HEADER *hp; - register u_char *cp; - register int n; - u_char *eom; - char *bp, **ap; - int type, class, buflen, ancount, qdcount; - int haveanswer, getclass = C_ANY; - char **hap; - - eom = answer->buf + anslen; - /* - * find first satisfactory answer - */ - hp = &answer->hdr; - ancount = ntohs(hp->ancount); - qdcount = ntohs(hp->qdcount); - bp = hostbuf; - buflen = sizeof(hostbuf); - cp = answer->buf + sizeof(HEADER); - if (qdcount) { - if (iquery) { - if ((n = dn_expand((u_char *)answer->buf, - (u_char *)eom, (u_char *)cp, (u_char *)bp, - buflen)) < 0) { - h_errno = NO_RECOVERY; - return ((struct hostent *) NULL); - } - cp += n + QFIXEDSZ; - host.h_name = bp; - n = strlen(bp) + 1; - bp += n; - buflen -= n; - } else - cp += __dn_skipname(cp, eom) + QFIXEDSZ; - while (--qdcount > 0) - cp += __dn_skipname(cp, eom) + QFIXEDSZ; - } else if (iquery) { - if (hp->aa) - h_errno = HOST_NOT_FOUND; - else - h_errno = TRY_AGAIN; - return ((struct hostent *) NULL); - } - ap = host_aliases; - *ap = NULL; - host.h_aliases = host_aliases; - hap = h_addr_ptrs; - *hap = NULL; -#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ - host.h_addr_list = h_addr_ptrs; -#endif - haveanswer = 0; - while (--ancount >= 0 && cp < eom) { - if ((n = dn_expand((u_char *)answer->buf, (u_char *)eom, - (u_char *)cp, (u_char *)bp, buflen)) < 0) - break; - cp += n; - type = _getshort(cp); - cp += sizeof(u_int16_t); - class = _getshort(cp); - cp += sizeof(u_int16_t) + sizeof(u_int32_t); - n = _getshort(cp); - cp += sizeof(u_int16_t); - if (type == T_CNAME) { - cp += n; - if (ap >= &host_aliases[MAXALIASES-1]) - continue; - *ap++ = bp; - n = strlen(bp) + 1; - bp += n; - buflen -= n; - continue; - } - if (iquery && type == T_PTR) { - if ((n = dn_expand((u_char *)answer->buf, - (u_char *)eom, (u_char *)cp, (u_char *)bp, - buflen)) < 0) - break; - cp += n; - host.h_name = bp; - return(&host); - } - if (iquery || type != T_A) { -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf("unexpected answer type %d, size %d\n", - type, n); -#endif - cp += n; - continue; - } - if (haveanswer) { - if (n != host.h_length) { - cp += n; - continue; - } - if (class != getclass) { - cp += n; - continue; - } - } else { - host.h_length = n; - getclass = class; - host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; - if (!iquery) { - host.h_name = bp; - bp += strlen(bp) + 1; - } - } - - bp += sizeof(align) - ((u_int32_t)bp % sizeof(align)); - - if (bp + n >= &hostbuf[sizeof(hostbuf)]) { -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf("size (%d) too big\n", n); -#endif - break; - } - bcopy(cp, *hap++ = bp, n); - bp +=n; - cp += n; - haveanswer++; - } - if (haveanswer) { - *ap = NULL; -#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ - *hap = NULL; -#else - host.h_addr = h_addr_ptrs[0]; -#endif - return (&host); - } else { - h_errno = TRY_AGAIN; - return ((struct hostent *) NULL); - } -} - -struct hostent * -_getdnsbyname(name) - const char *name; -{ - querybuf buf; - register const char *cp; - int n; - extern struct hostent *_gethtbyname(); - - /* - * disallow names consisting only of digits/dots, unless - * they end in a dot. - */ - if (isdigit(name[0])) - for (cp = name;; ++cp) { - if (!*cp) { - if (*--cp == '.') - break; - /* - * All-numeric, no dot at the end. - * Fake up a hostent as if we'd actually - * done a lookup. - */ - if (!inet_aton(name, &host_addr)) { - h_errno = HOST_NOT_FOUND; - return((struct hostent *) NULL); - } - host.h_name = (char *)name; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - host.h_addrtype = AF_INET; - host.h_length = sizeof(u_int32_t); - h_addr_ptrs[0] = (char *)&host_addr; - h_addr_ptrs[1] = (char *)0; -#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ - host.h_addr_list = h_addr_ptrs; -#else - host.h_addr = h_addr_ptrs[0]; -#endif - return (&host); - } - if (!isdigit(*cp) && *cp != '.') - break; - } - - if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) { -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf("res_search failed\n"); -#endif - return ((struct hostent *) NULL); - } - return (getanswer(&buf, n, 0)); -} - -struct hostent * -_getdnsbyaddr(addr, len, type) - const char *addr; - int len, type; -{ - int n; - querybuf buf; - register struct hostent *hp; - char qbuf[MAXDNAME]; - extern struct hostent *_gethtbyaddr(); - - if (type != AF_INET) - return ((struct hostent *) NULL); - (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", - ((unsigned)addr[3] & 0xff), - ((unsigned)addr[2] & 0xff), - ((unsigned)addr[1] & 0xff), - ((unsigned)addr[0] & 0xff)); - n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf)); - if (n < 0) { -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf("res_query failed\n"); -#endif - return ((struct hostent *) NULL); - } - hp = getanswer(&buf, n, 1); - if (hp == NULL) - return ((struct hostent *) NULL); - hp->h_addrtype = type; - hp->h_length = len; - h_addr_ptrs[0] = (char *)&host_addr; - h_addr_ptrs[1] = (char *)0; - host_addr = *(struct in_addr *)addr; -#if BSD < 43 && !defined(h_addr) /* new-style hostent structure */ - hp->h_addr = h_addr_ptrs[0]; -#endif - return(hp); -} - -void -_sethtent(f) - int f; -{ - if (hostf == NULL) - hostf = fopen(_PATH_HOSTS, "r" ); - else - rewind(hostf); - stayopen |= f; -} - -void -_endhtent() -{ - if (hostf && !stayopen) { - (void) fclose(hostf); - hostf = NULL; - } -} - -struct hostent * -_gethtent() -{ - char *p; - register char *cp, **q; - - if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL) - return (NULL); -again: - if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL) - return (NULL); - if (*p == '#') - goto again; - cp = strpbrk(p, "#\n"); - if (cp == NULL) - goto again; - *cp = '\0'; - cp = strpbrk(p, " \t"); - if (cp == NULL) - goto again; - *cp++ = '\0'; - /* THIS STUFF IS INTERNET SPECIFIC */ -#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ - host.h_addr_list = host_addrs; -#endif - host.h_addr = hostaddr; - *((u_int32_t *)host.h_addr) = inet_addr(p); - host.h_length = sizeof (u_int32_t); - host.h_addrtype = AF_INET; - while (*cp == ' ' || *cp == '\t') - cp++; - host.h_name = cp; - q = host.h_aliases = host_aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - if (q < &host_aliases[MAXALIASES - 1]) - *q++ = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - } - *q = NULL; - return (&host); -} - -struct hostent * -_gethtbyname(name) - char *name; -{ - register struct hostent *p; - register char **cp; - - _sethtent(0); - while (p = _gethtent()) { - if (strcasecmp(p->h_name, name) == 0) - break; - for (cp = p->h_aliases; *cp != 0; cp++) - if (strcasecmp(*cp, name) == 0) - goto found; - } -found: - _endhtent(); - return (p); -} - -struct hostent * -_gethtbyaddr(addr, len, type) - const char *addr; - int len, type; -{ - register struct hostent *p; - - _sethtent(0); - while (p = _gethtent()) - if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) - break; - _endhtent(); - return (p); -} - - -#ifdef YP -struct hostent * -_getnishost(name, map) - char *name, *map; -{ - register char *cp, *dp, **q; - char *result; - int resultlen; - static struct hostent h; - static char *domain = (char *)NULL; - - if (domain == (char *)NULL) - if (yp_get_default_domain (&domain)) - return ((struct hostent *)NULL); - - if (yp_match(domain, map, name, strlen(name), &result, &resultlen)) - return ((struct hostent *)NULL); - - if (cp = index(result, '\n')) - *cp = '\0'; - - cp = strpbrk(result, " \t"); - *cp++ = '\0'; -#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ - h.h_addr_list = host_addrs; -#endif - h.h_addr = hostaddr; - *((u_long *)h.h_addr) = inet_addr(result); - h.h_length = sizeof(u_long); - h.h_addrtype = AF_INET; - while (*cp == ' ' || *cp == '\t') - cp++; - h.h_name = cp; - q = h.h_aliases = host_aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - while (cp && *cp) { - if (*cp == ' ' || *cp == '\t') { - cp++; - continue; - } - if (q < &host_aliases[MAXALIASES - 1]) - *q++ = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) - *cp++ = '\0'; - } - *q = NULL; - return (&h); -} -#endif /* YP */ - struct hostent * gethostbyname(const char *name) { struct hostent *hp = 0; int nserv = 0; - if(!service_done) { + if (!service_done) init_services(); - } - while(!hp) { - switch(service_order[nserv]) { + while (!hp) { + switch (service_order[nserv]) { case SERVICE_NONE: - return 0; + return NULL; case SERVICE_HOSTS: - hp = _gethtbyname(name); + hp = _gethostbyhtname(name); break; case SERVICE_BIND: - hp = _getdnsbyname(name); + hp = _gethostbydnsname(name); break; case SERVICE_NIS: -#ifdef YP - hp = _getnishost(name, "hosts.byname"); -#endif + hp = _gethostbynisname(name); break; } nserv++; @@ -610,24 +151,21 @@ gethostbyaddr(const char *addr, int len, int type) struct hostent *hp = 0; int nserv = 0; - if(!service_done) { + if (!service_done) init_services(); - } - while(!hp) { - switch(service_order[nserv]) { + while (!hp) { + switch (service_order[nserv]) { case SERVICE_NONE: return 0; case SERVICE_HOSTS: - hp = _gethtbyaddr(addr, len, type); + hp = _gethostbyhtaddr(addr, len, type); break; case SERVICE_BIND: - hp = _getdnsbyaddr(addr, len, type); + hp = _gethostbydnsaddr(addr, len, type); break; case SERVICE_NIS: -#ifdef YP - hp = _getnishost(addr, "hosts.byaddr"); -#endif + hp = _gethostbynisaddr(addr, len, type); break; } nserv++; @@ -635,3 +173,17 @@ gethostbyaddr(const char *addr, int len, int type) return hp; } +void +sethostent(stayopen) + int stayopen; +{ + _sethosthtent(stayopen); + _sethostdnsent(stayopen); +} + +void +endhostent() +{ + _endhosthtent(); + _endhostdnsent(); +} |