diff options
author | peter <peter@FreeBSD.org> | 1996-08-29 20:08:19 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-08-29 20:08:19 +0000 |
commit | 1f1fd8028fddf809ce8077697ffa07cb30a1e5d2 (patch) | |
tree | 2cf4d77f1b2f64006b349d61712604ce2acf338e /lib/libc | |
parent | d971f8ba30d6c175abff84fb92fc284744fa18ac (diff) | |
download | FreeBSD-src-1f1fd8028fddf809ce8077697ffa07cb30a1e5d2.zip FreeBSD-src-1f1fd8028fddf809ce8077697ffa07cb30a1e5d2.tar.gz |
Merge in bind-4.9.4-P1 resolver...
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/net/Makefile.inc | 31 | ||||
-rw-r--r-- | lib/libc/net/gethostbydns.c | 233 | ||||
-rw-r--r-- | lib/libc/net/gethostbyht.c | 57 | ||||
-rw-r--r-- | lib/libc/net/gethostbyname.3 | 249 | ||||
-rw-r--r-- | lib/libc/net/gethostbynis.c | 34 | ||||
-rw-r--r-- | lib/libc/net/gethostnamadr.c | 37 | ||||
-rw-r--r-- | lib/libc/net/getnetbydns.c | 8 | ||||
-rw-r--r-- | lib/libc/net/getnetbyht.c | 2 | ||||
-rw-r--r-- | lib/libc/net/getnetbynis.c | 33 | ||||
-rw-r--r-- | lib/libc/net/getnetent.3 | 151 | ||||
-rw-r--r-- | lib/libc/net/getnetnamadr.c | 28 | ||||
-rw-r--r-- | lib/libc/net/inet_ntop.c | 190 | ||||
-rw-r--r-- | lib/libc/net/inet_pton.c | 214 | ||||
-rw-r--r-- | lib/libc/net/map_v4v6.c (renamed from lib/libc/net/res_data.c) | 109 | ||||
-rw-r--r-- | lib/libc/net/nsap_addr.c | 103 | ||||
-rw-r--r-- | lib/libc/net/res_comp.c | 378 | ||||
-rw-r--r-- | lib/libc/net/res_config.h | 4 | ||||
-rw-r--r-- | lib/libc/net/res_debug.c | 806 | ||||
-rw-r--r-- | lib/libc/net/res_init.c | 449 | ||||
-rw-r--r-- | lib/libc/net/res_mkquery.c | 241 | ||||
-rw-r--r-- | lib/libc/net/res_query.c | 383 | ||||
-rw-r--r-- | lib/libc/net/res_send.c | 727 | ||||
-rw-r--r-- | lib/libc/net/resolver.3 | 323 |
23 files changed, 860 insertions, 3930 deletions
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc index a1cb045..7a14855b 100644 --- a/lib/libc/net/Makefile.inc +++ b/lib/libc/net/Makefile.inc @@ -2,15 +2,17 @@ # machine-independent net sources .PATH: ${.CURDIR}/${MACHINE}/net ${.CURDIR}/net +.PATH: ${.CURDIR}/../../contrib/bind/res SRCS+= addr2ascii.c ascii2addr.c \ gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \ getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \ getproto.c getprotoent.c getprotoname.c getservbyname.c \ getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ - inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ - linkaddr.c rcmd.c recv.c res_comp.c res_data.c res_debug.c \ - res_init.c res_mkquery.c res_query.c res_send.c send.c ether_addr.c + inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \ + inet_pton.c linkaddr.c map_v4v6.c nsap_addr.c \ + rcmd.c recv.c res_comp.c res_data.c res_debug.c \ + res_init.c res_mkquery.c res_query.c res_send.c send.c ether_addr.c \ # iso_addr.c # ns_addr.c ns_ntoa.c @@ -19,9 +21,12 @@ SRCS+= addr2ascii.c ascii2addr.c \ .include "${.CURDIR}/${MACHINE}/net/Makefile.inc" MAN3+= net/addr2ascii.3 \ - net/byteorder.3 net/ethers.3 net/gethostbyname.3 net/getnetent.3 \ + net/byteorder.3 net/ethers.3 \ net/getprotoent.3 net/getservent.3 net/inet.3 net/linkaddr.3 \ - net/rcmd.3 net/resolver.3 + net/rcmd.3 + +# not installed from here, see usr.sbin/named/man for huge sed command: +# => gethostbyname.3 getnetent.3 resolver.3 # not installed: net/ns.3 net/iso_addr.3 @@ -30,11 +35,11 @@ MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ byteorder.3 ntohs.3 MLINKS+=ethers.3 ether_line.3 ethers.3 ether_aton.3 ethers.3 ether_ntoa.3 \ ethers.3 ether_ntohost.3 ethers.3 ether_hostton.3 -MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ - gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ - gethostbyname.3 herror.3 -MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ - getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 +#MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ +# gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ +# gethostbyname.3 herror.3 +#MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ +# getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ @@ -45,6 +50,6 @@ MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_lnaof.3 \ MLINKS+=linkaddr.3 link_addr.3 linkaddr.3 link_ntoa.3 #MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3 MLINKS+=rcmd.3 rresvport.3 rcmd.3 iruserok.3 rcmd.3 ruserok.3 -MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ - resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ - resolver.3 res_search.3 +#MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ +# resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ +# resolver.3 res_search.3 diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c index e7e09ab..8fdbd9a 100644 --- a/lib/libc/net/gethostbydns.c +++ b/lib/libc/net/gethostbydns.c @@ -53,9 +53,10 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethostbydns.c,v 1.8 1996/01/13 09:03:40 peter Exp $"; +static char rcsid[] = "$Id: gethostbydns.c,v 1.9 1996/07/12 18:54:33 jkh Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> #include <netinet/in.h> @@ -75,6 +76,8 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.8 1996/01/13 09:03:40 peter Exp $ extern void _res_close __P((void)); +#define SPRINTF(x) ((size_t)sprintf x) + #define MAXALIASES 35 #define MAXADDRS 35 @@ -82,11 +85,12 @@ static const char AskedForGot[] = "gethostby*.gethostanswer: asked for \"%s\", got \"%s\""; static char *h_addr_ptrs[MAXADDRS + 1]; +static struct hostent *gethostbyname_ipv4 __P((const char *)); static struct hostent host; static char *host_aliases[MAXALIASES]; static char hostbuf[8*1024]; -static struct in_addr host_addr; +static u_char host_addr[16]; /* IPv4 or IPv6 */ #ifdef RESOLVSORT static void addrsort __P((char **, int)); @@ -127,13 +131,12 @@ dprintf(msg, num) # define dprintf(msg, num) /*nada*/ #endif - static struct hostent * -gethostanswer(answer, anslen, qname, qclass, qtype) +gethostanswer(answer, anslen, qname, qtype) const querybuf *answer; int anslen; const char *qname; - int qclass, qtype; + int qtype; { register const HEADER *hp; register const u_char *cp; @@ -145,10 +148,23 @@ gethostanswer(answer, anslen, qname, qclass, qtype) int toobig = 0; char tbuf[MAXDNAME+1]; const char *tname; + int (*name_ok) __P((const char *)); tname = qname; host.h_name = NULL; eom = answer->buf + anslen; + switch (qtype) { + case T_A: + case T_AAAA: + name_ok = res_hnok; + break; + case T_PTR: + name_ok = res_dnok; + break; + default: + h_errno = NO_RECOVERY; + return (NULL); /* XXX should be abort(); */ + } /* * find first satisfactory answer */ @@ -162,12 +178,13 @@ gethostanswer(answer, anslen, qname, qclass, qtype) h_errno = NO_RECOVERY; return (NULL); } - if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !(*name_ok)(bp)) { h_errno = NO_RECOVERY; return (NULL); } cp += n + QFIXEDSZ; - if (qtype == T_A) { + if (qtype == T_A || qtype == T_AAAA) { /* res_send() has already verified that the query name is the * same as the one we sent; this just gets the expanded name * (i.e., with the succeeding search-domain tacked on). @@ -184,14 +201,12 @@ gethostanswer(answer, anslen, qname, qclass, qtype) 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; had_error = 0; while (ancount-- > 0 && cp < eom && !had_error) { n = dn_expand(answer->buf, eom, cp, bp, buflen); - if (n < 0) { + if ((n < 0) || !(*name_ok)(bp)) { had_error++; continue; } @@ -202,26 +217,20 @@ gethostanswer(answer, anslen, qname, qclass, qtype) cp += INT16SZ + INT32SZ; /* class, TTL */ n = _getshort(cp); cp += INT16SZ; /* len */ - if (class != qclass) { + if (class != C_IN) { /* XXX - debug? syslog? */ cp += n; continue; /* XXX - had_error++ ? */ } - if (qtype == T_A && type == T_CNAME) { + if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { if (ap >= &host_aliases[MAXALIASES-1]) continue; n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); - if (n < 0) { + if ((n < 0) || !(*name_ok)(tbuf)) { had_error++; continue; } cp += n; - if (host.h_name && strcasecmp(host.h_name, bp) != 0) { - syslog(LOG_NOTICE|LOG_AUTH, - "gethostby*.gethostanswer: asked for \"%s\", got CNAME for \"%s\"", - host.h_name, bp); - continue; /* XXX - had_error++ ? */ - } /* Store alias. */ *ap++ = bp; n = strlen(bp) + 1; /* for the \0 */ @@ -241,7 +250,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype) } if (qtype == T_PTR && type == T_CNAME) { n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); - if (n < 0) { + if ((n < 0) || !res_hnok(tbuf)) { had_error++; continue; } @@ -261,7 +270,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype) if (type != qtype) { syslog(LOG_NOTICE|LOG_AUTH, "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"", - qname, p_class(qclass), p_type(qtype), + qname, p_class(C_IN), p_type(qtype), p_type(type)); cp += n; continue; /* XXX - had_error++ ? */ @@ -275,11 +284,11 @@ gethostanswer(answer, anslen, qname, qclass, qtype) continue; /* XXX - had_error++ ? */ } n = dn_expand(answer->buf, eom, cp, bp, buflen); - if (n < 0) { + if ((n < 0) || !res_hnok(bp)) { had_error++; break; } -#ifdef MULTI_PTRS_ARE_ALIASES +#if MULTI_PTRS_ARE_ALIASES cp += n; if (!haveanswer) host.h_name = bp; @@ -295,10 +304,17 @@ gethostanswer(answer, anslen, qname, qclass, qtype) break; #else host.h_name = bp; + if (_res.options & RES_USE_INET6) { + n = strlen(bp) + 1; /* for the \0 */ + bp += n; + buflen -= n; + _map_v4v6_hostent(&host, &bp, &buflen); + } h_errno = NETDB_SUCCESS; return (&host); #endif case T_A: + case T_AAAA: if (strcasecmp(host.h_name, bp) != 0) { syslog(LOG_NOTICE|LOG_AUTH, AskedForGot, host.h_name, bp); @@ -313,10 +329,6 @@ gethostanswer(answer, anslen, qname, qclass, qtype) } else { register int nn; - host.h_length = n; - host.h_addrtype = (class == C_IN) - ? AF_INET - : AF_UNSPEC; host.h_name = bp; nn = strlen(bp) + 1; /* for the \0 */ bp += nn; @@ -339,6 +351,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype) } bcopy(cp, *hap++ = bp, n); bp += n; + buflen -= n; cp += n; break; default: @@ -358,41 +371,61 @@ gethostanswer(answer, anslen, qname, qclass, qtype) * in its return structures - should give it the "best" * address in that case, not some random one */ - if (_res.nsort && haveanswer > 1 && - qclass == C_IN && qtype == T_A) + if (_res.nsort && haveanswer > 1 && qtype == T_A) addrsort(h_addr_ptrs, haveanswer); # endif /*RESOLVSORT*/ -#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ - /* nothing */ -#else - host.h_addr = h_addr_ptrs[0]; -#endif /*BSD*/ if (!host.h_name) { n = strlen(qname) + 1; /* for the \0 */ + if (n > buflen) + goto try_again; strcpy(bp, qname); host.h_name = bp; + bp += n; + buflen -= n; } + if (_res.options & RES_USE_INET6) + _map_v4v6_hostent(&host, &bp, &buflen); h_errno = NETDB_SUCCESS; return (&host); - } else { - h_errno = TRY_AGAIN; - return (NULL); } + try_again: + h_errno = TRY_AGAIN; + return (NULL); } struct hostent * -_gethostbydnsname(name) +_gethostbydnsname(name, af) const char *name; + int af; { querybuf buf; register const char *cp; - int n; + char *bp; + int n, size, type, len; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return (NULL); } + switch (af) { + case AF_INET: + size = INADDRSZ; + type = T_A; + break; + case AF_INET6: + size = IN6ADDRSZ; + type = T_AAAA; + break; + default: + h_errno = NETDB_INTERNAL; + errno = EAFNOSUPPORT; + return (NULL); + } + + host.h_addrtype = af; + host.h_length = size; + /* * if there aren't any dots, it could be a user-level alias. * this is also done in res_query() since we are not the only @@ -415,24 +448,22 @@ _gethostbydnsname(name) * Fake up a hostent as if we'd actually * done a lookup. */ - if (!inet_aton(name, &host_addr)) { + if (inet_pton(af, name, host_addr) <= 0) { h_errno = HOST_NOT_FOUND; return (NULL); } strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; + bp = hostbuf + MAXDNAME; + len = sizeof hostbuf - MAXDNAME; host.h_name = hostbuf; host.h_aliases = host_aliases; host_aliases[0] = NULL; - host.h_addrtype = AF_INET; - host.h_length = INT32SZ; - h_addr_ptrs[0] = (char *)&host_addr; + h_addr_ptrs[0] = (char *)host_addr; h_addr_ptrs[1] = NULL; -#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 + if (_res.options & RES_USE_INET6) + _map_v4v6_hostent(&host, &bp, &len); h_errno = NETDB_SUCCESS; return (&host); } @@ -440,22 +471,25 @@ _gethostbydnsname(name) break; } - if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) { + if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { dprintf("res_search failed (%d)\n", n); return (NULL); } - return (gethostanswer(&buf, n, name, C_IN, T_A)); + return (gethostanswer(&buf, n, name, type)); } struct hostent * -_gethostbydnsaddr(addr, len, type) - const char *addr; - int len, type; +_gethostbydnsaddr(addr, len, af) + const char *addr; /* XXX should have been def'd as u_char! */ + int len, af; { - int n; + const u_char *uaddr = (const u_char *)addr; + static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; + static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; + int n, size; querybuf buf; register struct hostent *hp; - char qbuf[MAXDNAME+1]; + char qbuf[MAXDNAME+1], *qp; #ifdef SUNSECURITY register struct hostent *rhp; char **haddr; @@ -467,58 +501,101 @@ _gethostbydnsaddr(addr, len, type) h_errno = NETDB_INTERNAL; return (NULL); } - if (type != AF_INET) { + if (af == AF_INET6 && len == IN6ADDRSZ && + (!bcmp(uaddr, mapped, sizeof mapped) || + !bcmp(uaddr, tunnelled, sizeof tunnelled))) { + /* Unmap. */ + addr += sizeof mapped; + uaddr += sizeof mapped; + af = AF_INET; + len = INADDRSZ; + } + switch (af) { + case AF_INET: + size = INADDRSZ; + break; + case AF_INET6: + size = IN6ADDRSZ; + break; + default: errno = EAFNOSUPPORT; h_errno = NETDB_INTERNAL; return (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)); + if (size != len) { + errno = EINVAL; + h_errno = NETDB_INTERNAL; + return (NULL); + } + switch (af) { + case AF_INET: + (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", + (uaddr[3] & 0xff), + (uaddr[2] & 0xff), + (uaddr[1] & 0xff), + (uaddr[0] & 0xff)); + break; + case AF_INET6: + qp = qbuf; + for (n = IN6ADDRSZ - 1; n >= 0; n--) { + qp += SPRINTF((qp, "%x.%x.", + uaddr[n] & 0xf, + (uaddr[n] >> 4) & 0xf)); + } + strcpy(qp, "ip6.int"); + break; + default: + abort(); + } n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); if (n < 0) { dprintf("res_query failed (%d)\n", n); return (NULL); } - if (!(hp = gethostanswer(&buf, n, qbuf, C_IN, T_PTR))) + if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR))) return (NULL); /* h_errno was set by gethostanswer() */ #ifdef SUNSECURITY - /* - * turn off search as the name should be absolute, - * 'localhost' should be matched by defnames - */ - strncpy(hname2, hp->h_name, MAXDNAME); - hname2[MAXDNAME] = '\0'; - old_options = _res.options; - _res.options &= ~RES_DNSRCH; - _res.options |= RES_DEFNAMES; - if (!(rhp = gethostbyname(hname2))) { + if (af == AF_INET) { + /* + * turn off search as the name should be absolute, + * 'localhost' should be matched by defnames + */ + strncpy(hname2, hp->h_name, MAXDNAME); + hname2[MAXDNAME] = '\0'; + old_options = _res.options; + _res.options &= ~RES_DNSRCH; + _res.options |= RES_DEFNAMES; + if (!(rhp = gethostbyname(hname2))) { syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: No A record for %s (verifying [%s])", hname2, inet_ntoa(*((struct in_addr *)addr))); _res.options = old_options; h_errno = HOST_NOT_FOUND; return (NULL); - } - _res.options = old_options; - for (haddr = rhp->h_addr_list; *haddr; haddr++) + } + _res.options = old_options; + for (haddr = rhp->h_addr_list; *haddr; haddr++) if (!memcmp(*haddr, addr, INADDRSZ)) break; - if (!*haddr) { + if (!*haddr) { syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: A record of %s != PTR record [%s]", hname2, inet_ntoa(*((struct in_addr *)addr))); h_errno = HOST_NOT_FOUND; return (NULL); + } } #endif /*SUNSECURITY*/ - hp->h_addrtype = type; + hp->h_addrtype = af; hp->h_length = len; - h_addr_ptrs[0] = (char *)&host_addr; + bcopy(addr, host_addr, len); + h_addr_ptrs[0] = (char *)host_addr; h_addr_ptrs[1] = NULL; - host_addr = *(struct in_addr *)addr; + if (af == AF_INET && (_res.options & RES_USE_INET6)) { + _map_v4v6_address((char*)host_addr, (char*)host_addr); + hp->h_addrtype = AF_INET6; + hp->h_length = IN6ADDRSZ; + } h_errno = NETDB_SUCCESS; return (hp); } diff --git a/lib/libc/net/gethostbyht.c b/lib/libc/net/gethostbyht.c index a4b2203..7c6fe2c 100644 --- a/lib/libc/net/gethostbyht.c +++ b/lib/libc/net/gethostbyht.c @@ -53,7 +53,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethostbyht.c,v 1.3 1996/01/13 09:03:45 peter Exp $"; +static char rcsid[] = "$Id: gethostbyht.c,v 1.4 1996/07/12 18:54:34 jkh Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -65,6 +65,8 @@ static char rcsid[] = "$Id: gethostbyht.c,v 1.3 1996/01/13 09:03:45 peter Exp $" #include <ctype.h> #include <errno.h> #include <string.h> +#include <arpa/nameser.h> /* XXX */ +#include <resolv.h> /* XXX */ #define MAXALIASES 35 @@ -72,7 +74,7 @@ static struct hostent host; static char *host_aliases[MAXALIASES]; static char hostbuf[BUFSIZ+1]; static FILE *hostf = NULL; -static struct in_addr host_addr; +static u_char host_addr[16]; /* IPv4 or IPv6 */ static char *h_addr_ptrs[2]; static int stayopen = 0; @@ -101,12 +103,13 @@ gethostent() { char *p; register char *cp, **q; + int af, len; if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { h_errno = NETDB_INTERNAL; return (NULL); } -again: + again: if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { h_errno = HOST_NOT_FOUND; return (NULL); @@ -119,23 +122,32 @@ again: if (!(cp = strpbrk(p, " \t"))) goto again; *cp++ = '\0'; - /* THIS STUFF IS INTERNET SPECIFIC */ - if (!inet_aton(p, &host_addr)) + if ((_res.options & RES_USE_INET6) && + inet_pton(AF_INET6, p, host_addr) > 0) { + af = AF_INET6; + len = IN6ADDRSZ; + } else if (inet_pton(AF_INET, p, host_addr) > 0) { + if (_res.options & RES_USE_INET6) { + _map_v4v6_address((char*)host_addr, (char*)host_addr); + af = AF_INET6; + len = IN6ADDRSZ; + } else { + af = AF_INET; + len = INADDRSZ; + } + } else { goto again; - h_addr_ptrs[0] = (char *)&host_addr; + } + h_addr_ptrs[0] = (char *)host_addr; h_addr_ptrs[1] = NULL; -#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 - host.h_length = sizeof(u_int32_t); - host.h_addrtype = AF_INET; + host.h_length = len; + host.h_addrtype = af; while (*cp == ' ' || *cp == '\t') cp++; host.h_name = cp; q = host.h_aliases = host_aliases; - if ( (cp = strpbrk(cp, " \t")) ) + if (cp = strpbrk(cp, " \t")) *cp++ = '\0'; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { @@ -144,23 +156,32 @@ again: } if (q < &host_aliases[MAXALIASES - 1]) *q++ = cp; - if ( (cp = strpbrk(cp, " \t")) ) + if (cp = strpbrk(cp, " \t")) *cp++ = '\0'; } *q = NULL; + if (_res.options & RES_USE_INET6) { + char *bp = hostbuf; + int buflen = sizeof hostbuf; + + _map_v4v6_hostent(&host, &bp, &buflen); + } h_errno = NETDB_SUCCESS; return (&host); } struct hostent * -_gethostbyhtname(name) +_gethostbyhtname2(name, af) char *name; + int af; { register struct hostent *p; register char **cp; sethostent(0); while ( (p = gethostent()) ) { + if (p->h_addrtype != af) + continue; if (strcasecmp(p->h_name, name) == 0) break; for (cp = p->h_aliases; *cp != 0; cp++) @@ -173,15 +194,15 @@ found: } struct hostent * -_gethostbyhtaddr(addr, len, type) +_gethostbyhtaddr(addr, len, af) const char *addr; - int len, type; + int len, af; { register struct hostent *p; sethostent(0); while ( (p = gethostent()) ) - if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) + if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len)) break; endhostent(); return (p); diff --git a/lib/libc/net/gethostbyname.3 b/lib/libc/net/gethostbyname.3 deleted file mode 100644 index 702a116..0000000 --- a/lib/libc/net/gethostbyname.3 +++ /dev/null @@ -1,249 +0,0 @@ -.\" Copyright (c) 1983, 1987, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 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 -.\" 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 -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" 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. -.\" -.\" @(#)gethostbyname.3 8.2 (Berkeley) 4/19/94 -.\" -.Dd April 19, 1994 -.Dt GETHOSTBYNAME 3 -.Os BSD 4.2 -.Sh NAME -.Nm gethostbyname , -.Nm gethostbyaddr , -.Nm gethostent , -.Nm sethostent , -.Nm endhostent , -.Nm herror -.Nd get network host entry -.Sh SYNOPSIS -.Fd #include <netdb.h> -.Fd extern struct h_errno; -.Ft struct hostent * -.Fn gethostbyname "char *name" -.Ft struct hostent * -.Fn gethostbyaddr "char *addr" "int len" "int type" -.Ft struct hostent * -.Fn gethostent void -.Fn sethostent "int stayopen" -.Fn endhostent void -.Fn herror "char *string" -.Sh DESCRIPTION -The -.Fn gethostbyname -and -.Fn gethostbyaddr -functions -each return a pointer to an object with the -following structure describing an internet host -referenced by name or by address, respectively. -This structure contains either the information obtained from the name server, -.Xr named 8 , -or broken-out fields from a line in -.Pa /etc/hosts . -If the local name server is not running these routines do a lookup in -.Pa /etc/hosts . -.Bd -literal -struct hostent { - char *h_name; /* official name of host */ - char **h_aliases; /* alias list */ - int h_addrtype; /* host address type */ - int h_length; /* length of address */ - char **h_addr_list; /* list of addresses from name server */ -}; -#define h_addr h_addr_list[0] /* address, for backward compatibility */ -.Ed -.Pp -The members of this structure are: -.Bl -tag -width h_addr_list -.It Fa h_name -Official name of the host. -.It Fa h_aliases -A zero terminated array of alternate names for the host. -.It Fa h_addrtype -The type of address being returned; currently always -.Dv AF_INET . -.It Fa h_length -The length, in bytes, of the address. -.It Fa h_addr_list -A zero terminated array of network addresses for the host. -Host addresses are returned in network byte order. -.It Fa h_addr -The first address in -.Fa h_addr_list ; -this is for backward compatibility. -.Pp -When using the nameserver, -.Fn gethostbyname -will search for the named host in the current domain and its parents -unless the name ends in a dot. -If the name contains no dot, and if the environment variable -.Dq Ev HOSTALIASES -contains the name of an alias file, the alias file will first be searched -for an alias matching the input name. -See -.Xr hostname 7 -for the domain search procedure and the alias file format. -.Pp -The -.Fn sethostent -function -may be used to request the use of a connected -.Tn TCP -socket for queries. -If the -.Fa stayopen -flag is non-zero, -this sets the option to send all queries to the name server using -.Tn TCP -and to retain the connection after each call to -.Fn gethostbyname -or -.Fn gethostbyaddr . -Otherwise, queries are performed using -.Tn UDP -datagrams. -.Pp -The -.Fn endhostent -function -closes the -.Tn TCP -connection. -.Sh FILES -.Bl -tag -width /etc/hosts -compact -.It Pa /etc/hosts -.El -.Sh DIAGNOSTICS -Error return status from -.Fn gethostbyname -and -.Fn gethostbyaddr -is indicated by return of a null pointer. -The external integer -.Va h_errno -may then be checked to see whether this is a temporary failure -or an invalid or unknown host. -The routine -.Fn herror -can be used to print an error message describing the failure. -If its argument -.Fa string -is -.Pf non Dv -NULL , -it is printed, followed by a colon and a space. -The error message is printed with a trailing newline. -.Pp -The variable -.Va h_errno -can have the following values: -.Bl -tag -width HOST_NOT_FOUND -.It Dv HOST_NOT_FOUND -No such host is known. -.It Dv TRY_AGAIN -This is usually a temporary error -and means that the local server did not receive -a response from an authoritative server. -A retry at some later time may succeed. -.It Dv NO_RECOVERY -Some unexpected server failure was encountered. -This is a non-recoverable error. -.It Dv NO_DATA -The requested name is valid but does not have an IP address; -this is not a temporary error. -This means that the name is known to the name server but there is no address -associated with this name. -Another type of request to the name server using this domain name -will result in an answer; -for example, a mail-forwarder may be registered for this domain. -.El -.Sh SEE ALSO -.Xr resolver 3 , -.Xr hosts 5 , -.Xr hostname 7 , -.Xr named 8 -.Sh CAVEAT -The -.Fn gethostent -function -is defined, and -.Fn sethostent -and -.Fn endhostent -are redefined, -when -.Xr libc 3 -is built to use only the routines to lookup in -.Pa /etc/hosts -and not the name server. -.Pp -The -.Fn gethostent -function -reads the next line of -.Pa /etc/hosts , -opening the file if necessary. -.Pp -The -.Fn sethostent -function -opens and/or rewinds the file -.Pa /etc/hosts . -If the -.Fa stayopen -argument is non-zero, -the file will not be closed after each call to -.Fn gethostbyname -or -.Fn gethostbyaddr . -.Pp -The -.Fn endhostent -function -closes the file. -.Sh HISTORY -The -.Fn herror -function appeared in -.Bx 4.3 . -The -.Fn endhostent , -.Fn gethostbyaddr , -.Fn gethostbyname , -.Fn gethostent , -and -.Fn sethostent -functions appeared in -.Bx 4.2 . -.Sh BUGS -These functions use static data storage; -if the data is needed for future use, it should be -copied before any subsequent calls overwrite it. -Only the Internet -address format is currently understood. diff --git a/lib/libc/net/gethostbynis.c b/lib/libc/net/gethostbynis.c index 2f012b8..24be897 100644 --- a/lib/libc/net/gethostbynis.c +++ b/lib/libc/net/gethostbynis.c @@ -24,8 +24,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)$Id: gethostbynis.c,v 1.2 1996/03/16 21:25:58 wpaul Exp $"; -static char rcsid[] = "$Id: gethostbynis.c,v 1.2 1996/03/16 21:25:58 wpaul Exp $"; +static char sccsid[] = "@(#)$Id: gethostbynis.c,v 1.3 1996/07/12 18:54:35 jkh Exp $"; +static char rcsid[] = "$Id: gethostbynis.c,v 1.3 1996/07/12 18:54:35 jkh Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -54,8 +54,10 @@ static char *host_addrs[2]; #endif /* YP */ static struct hostent * -_gethostbynis(name, map) - char *name, *map; +_gethostbynis(name, map, af) + const char *name; + char *map; + int af; { #ifdef YP register char *cp, **q; @@ -65,6 +67,15 @@ _gethostbynis(name, map) static char *domain = (char *)NULL; static char ypbuf[YPMAXRECORD]; + switch(af) { + case AF_INET: + break; + default: + case AF_INET6: + errno = EAFNOSUPPORT; + return NULL; + } + if (domain == (char *)NULL) if (yp_get_default_domain (&domain)) return ((struct hostent *)NULL); @@ -113,17 +124,18 @@ _gethostbynis(name, map) } struct hostent * -_gethostbynisname(name) - char *name; +_gethostbynisname(name, af) + const char *name; + int af; { - return _gethostbynis(name, "hosts.byname"); + return _gethostbynis(name, "hosts.byname", af); } struct hostent * -_gethostbynisaddr(addr, len, type) - char *addr; +_gethostbynisaddr(addr, len, af) + const char *addr; int len; - int type; + int af; { - return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr"); + return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af); } diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c index d274365..95f00e3 100644 --- a/lib/libc/net/gethostnamadr.c +++ b/lib/libc/net/gethostnamadr.c @@ -24,8 +24,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.8 1996/07/12 18:54:36 jkh Exp $"; -static char rcsid[] = "$Id: gethostnamadr.c,v 1.8 1996/07/12 18:54:36 jkh Exp $"; +static char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.9 1996/08/20 08:20:21 julian Exp $"; +static char rcsid[] = "$Id: gethostnamadr.c,v 1.9 1996/08/20 08:20:21 julian Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -37,18 +37,8 @@ static char rcsid[] = "$Id: gethostnamadr.c,v 1.8 1996/07/12 18:54:36 jkh Exp $" #include <ctype.h> #include <errno.h> #include <string.h> - -extern void _sethosthtent __P(( int )); -extern void _endhosthtent __P(( void )); -extern void _sethostdnsent __P(( int )); -extern void _endhostdnsent __P(( void )); - -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)); +#include <arpa/nameser.h> /* XXX hack for _res */ +#include <resolv.h> /* XXX hack for _res */ #define _PATH_HOSTCONF "/etc/host.conf" @@ -131,6 +121,19 @@ init_services() struct hostent * gethostbyname(const char *name) { + struct hostent *hp; + + if (_res.options & RES_USE_INET6) { /* XXX */ + hp = gethostbyname2(name, AF_INET6); /* XXX */ + if (hp) /* XXX */ + return (hp); /* XXX */ + } /* XXX */ + return (gethostbyname2(name, AF_INET)); +} + +struct hostent * +gethostbyname2(const char *name, int type) +{ struct hostent *hp = 0; int nserv = 0; @@ -142,13 +145,13 @@ gethostbyname(const char *name) case SERVICE_NONE: return NULL; case SERVICE_HOSTS: - hp = _gethostbyhtname(name); + hp = _gethostbyhtname(name, type); break; case SERVICE_BIND: - hp = _gethostbydnsname(name); + hp = _gethostbydnsname(name, type); break; case SERVICE_NIS: - hp = _gethostbynisname(name); + hp = _gethostbynisname(name, type); break; } nserv++; diff --git a/lib/libc/net/getnetbydns.c b/lib/libc/net/getnetbydns.c index 14fe5d6..1f7607b 100644 --- a/lib/libc/net/getnetbydns.c +++ b/lib/libc/net/getnetbydns.c @@ -60,7 +60,7 @@ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: getnetbydns.c,v 1.5 1996/01/13 09:03:51 peter Exp $"; +static char rcsid[] = "$Id: getnetbydns.c,v 1.6 1996/07/12 18:54:37 jkh Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -156,7 +156,7 @@ static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; haveanswer = 0; while (--ancount >= 0 && cp < eom) { n = dn_expand(answer->buf, eom, cp, bp, buflen); - if (n < 0) + if ((n < 0) || !res_dnok(bp)) break; cp += n; ans[0] = '\0'; @@ -167,7 +167,7 @@ static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; GETSHORT(n, cp); if (class == C_IN && type == T_PTR) { n = dn_expand(answer->buf, eom, cp, bp, buflen); - if (n < 0) { + if ((n < 0) || !res_hnok(bp)) { cp += n; return (NULL); } @@ -219,7 +219,7 @@ static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; struct netent * _getnetbydnsaddr(net, net_type) - register long net; + register unsigned long net; register int net_type; { unsigned int netbr[4]; diff --git a/lib/libc/net/getnetbyht.c b/lib/libc/net/getnetbyht.c index a9707df..cbc45b5 100644 --- a/lib/libc/net/getnetbyht.c +++ b/lib/libc/net/getnetbyht.c @@ -156,7 +156,7 @@ found: struct netent * _getnetbyhtaddr(net, type) - register long net; + register unsigned long net; register int type; { register struct netent *p; diff --git a/lib/libc/net/getnetbynis.c b/lib/libc/net/getnetbynis.c index ac11aa3..7c256e0 100644 --- a/lib/libc/net/getnetbynis.c +++ b/lib/libc/net/getnetbynis.c @@ -24,8 +24,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)$Id: getnetbynis.c,v 1.4 1995/10/22 14:39:06 phk Exp $"; -static char rcsid[] = "$Id: getnetbynis.c,v 1.4 1995/10/22 14:39:06 phk Exp $"; +static char sccsid[] = "@(#)$Id: getnetbynis.c,v 1.5 1996/03/23 22:16:22 wpaul Exp $"; +static char rcsid[] = "$Id: getnetbynis.c,v 1.5 1996/03/23 22:16:22 wpaul Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -53,8 +53,10 @@ static char *host_aliases[MAXALIASES]; #endif /* YP */ static struct netent * -_getnetbynis(name, map) - char *name, *map; +_getnetbynis(name, map, af) + const char *name; + char *map; + int af; { #ifdef YP register char *cp, **q; @@ -64,6 +66,15 @@ _getnetbynis(name, map) static char *domain = (char *)NULL; static char ypbuf[YPMAXRECORD]; + switch(af) { + case AF_INET: + break; + default: + case AF_INET6: + errno = EAFNOSUPPORT; + return NULL; + } + if (domain == (char *)NULL) if (yp_get_default_domain (&domain)) return (NULL); @@ -112,15 +123,15 @@ _getnetbynis(name, map) struct netent * _getnetbynisname(name) - char *name; + const char *name; { return _getnetbynis(name, "networks.byname"); } struct netent * -_getnetbynisaddr(addr, type) - long addr; - int type; +_getnetbynisaddr(addr, af) + unsigned long addr; + int af; { char *str, *cp; unsigned long net2; @@ -128,8 +139,10 @@ _getnetbynisaddr(addr, type) unsigned int netbr[4]; char buf[MAXDNAME]; - if (type != AF_INET) + if (af != AF_INET) { + errno = EAFNOSUPPORT; return (NULL); + } for (nn = 4, net2 = addr; net2; net2 >>= 8) { netbr[--nn] = net2 & 0xff; @@ -159,5 +172,5 @@ _getnetbynisaddr(addr, type) cp = str + (strlen(str) - 2); } - return _getnetbynis(str, "networks.byaddr"); + return _getnetbynis(str, "networks.byaddr", af); } diff --git a/lib/libc/net/getnetent.3 b/lib/libc/net/getnetent.3 deleted file mode 100644 index 7514371c..0000000 --- a/lib/libc/net/getnetent.3 +++ /dev/null @@ -1,151 +0,0 @@ -.\" Copyright (c) 1983, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 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 -.\" 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 -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" 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. -.\" -.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93 -.\" -.Dd June 4, 1993 -.Dt GETNETENT 3 -.Os BSD 4.2 -.Sh NAME -.Nm getnetent , -.Nm getnetbyaddr , -.Nm getnetbyname , -.Nm setnetent , -.Nm endnetent -.Nd get network entry -.Sh SYNOPSIS -.Fd #include <netdb.h> -.Ft struct netent * -.Fn getnetent -.Ft struct netent * -.Fn getnetbyname "char *name" -.Ft struct netent * -.Fn getnetbyaddr "long net" "int type" -.Fn setnetent "int stayopen" -.Fn endnetent -.Sh DESCRIPTION -The -.Fn getnetent , -.Fn getnetbyname , -and -.Fn getnetbyaddr -functions -each return a pointer to an object with the -following structure -containing the broken-out -fields of a line in the network data base, -.Pa /etc/networks . -.Bd -literal -offset indent -struct netent { - char *n_name; /* official name of net */ - char **n_aliases; /* alias list */ - int n_addrtype; /* net number type */ - unsigned long n_net; /* net number */ -}; -.Ed -.Pp -The members of this structure are: -.Bl -tag -width n_addrtype -.It Fa n_name -The official name of the network. -.It Fa n_aliases -A zero terminated list of alternate names for the network. -.It Fa n_addrtype -The type of the network number returned; currently only AF_INET. -.It Fa n_net -The network number. Network numbers are returned in machine byte -order. -.El -.Pp -The -.Fn getnetent -function -reads the next line of the file, opening the file if necessary. -.Pp -The -.Fn setnetent -function -opens and rewinds the file. If the -.Fa stayopen -flag is non-zero, -the net data base will not be closed after each call to -.Fn getnetbyname -or -.Fn getnetbyaddr . -.Pp -The -.Fn endnetent -function -closes the file. -.Pp -The -.Fn getnetbyname -function -and -.Fn getnetbyaddr -sequentially search from the beginning -of the file until a matching -net name or -net address and type is found, -or until -.Dv EOF -is encountered. -Network numbers are supplied in host order. -.Sh FILES -.Bl -tag -width /etc/networks -compact -.It Pa /etc/networks -.El -.Sh DIAGNOSTICS -Null pointer -(0) returned on -.Dv EOF -or error. -.Sh SEE ALSO -.Xr networks 5 -.Sh HISTORY -The -.Fn getnetent , -.Fn getnetbyaddr , -.Fn getnetbyname , -.Fn setnetent , -and -.Fn endnetent -functions appeared in -.Bx 4.2 . -.Sh BUGS -The data space used by -these functions is static; if future use requires the data, it should be -copied before any subsequent calls to these functions overwrite it. -Only Internet network -numbers are currently understood. -Expecting network numbers to fit -in no more than 32 bits is probably -naive. diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c index b522d75..b0e7468 100644 --- a/lib/libc/net/getnetnamadr.c +++ b/lib/libc/net/getnetnamadr.c @@ -24,8 +24,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)$Id: getnetnamadr.c,v 1.4 1995/05/30 05:40:48 rgrimes Exp $"; -static char rcsid[] = "$Id: getnetnamadr.c,v 1.4 1995/05/30 05:40:48 rgrimes Exp $"; +static char sccsid[] = "@(#)$Id: getnetnamadr.c,v 1.5 1996/07/12 18:54:40 jkh Exp $"; +static char rcsid[] = "$Id: getnetnamadr.c,v 1.5 1996/07/12 18:54:40 jkh Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -38,20 +38,6 @@ static char rcsid[] = "$Id: getnetnamadr.c,v 1.4 1995/05/30 05:40:48 rgrimes Exp #include <errno.h> #include <string.h> -extern void _setnetent __P(( int )); -extern void _endnetent __P(( void )); -extern void _setnethtent __P(( int )); -extern void _endnethtent __P(( void )); -extern void _setnetdnsent __P(( int )); -extern void _endnetdnsent __P(( void )); - -extern struct netent * _getnetbyhtname __P((const char *)); -extern struct netent * _getnetbydnsname __P((const char *)); -extern struct netent * _getnetbynisname __P((const char *)); -extern struct netent * _getnetbyhtaddr __P((long, int)); -extern struct netent * _getnetbydnsaddr __P((long, int)); -extern struct netent * _getnetbynisaddr __P((long, int)); - #ifndef _PATH_NETCONF #define _PATH_NETCONF "/etc/host.conf" #endif @@ -160,9 +146,9 @@ getnetbyname(const char *name) } struct netent * -getnetbyaddr(addr, type) +getnetbyaddr(addr, af) long addr; - int type; + int af; { struct netent *hp = 0; int nserv = 0; @@ -175,13 +161,13 @@ getnetbyaddr(addr, type) case SERVICE_NONE: return 0; case SERVICE_TABLE: - hp = _getnetbyhtaddr(addr, type); + hp = _getnetbyhtaddr(addr, af); break; case SERVICE_BIND: - hp = _getnetbydnsaddr(addr, type); + hp = _getnetbydnsaddr(addr, af); break; case SERVICE_NIS: - hp = _getnetbynisaddr(addr, type); + hp = _getnetbynisaddr(addr, af); break; } nserv++; diff --git a/lib/libc/net/inet_ntop.c b/lib/libc/net/inet_ntop.c new file mode 100644 index 0000000..c774acc --- /dev/null +++ b/lib/libc/net/inet_ntop.c @@ -0,0 +1,190 @@ +/* Copyright (c) 1996 by Internet Software Consortium. + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> + +#define SPRINTF(x) ((size_t)sprintf x) + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size)); +static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size)); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop(af, src, dst, size) + int af; + const void *src; + char *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); + case AF_INET6: + return (inet_ntop6(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + + if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + u_int words[IN6ADDRSZ / INT16SZ]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + tp += SPRINTF((tp, "%x", words[i])); + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} diff --git a/lib/libc/net/inet_pton.c b/lib/libc/net/inet_pton.c new file mode 100644 index 0000000..d9fd344 --- /dev/null +++ b/lib/libc/net/inet_pton.c @@ -0,0 +1,214 @@ +/* Copyright (c) 1996 by Internet Software Consortium. + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> +#include <string.h> +#include <errno.h> + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4 __P((const char *src, u_char *dst)); +static int inet_pton6 __P((const char *src, u_char *dst)); + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +inet_pton(af, src, dst) + int af; + const char *src; + void *dst; +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + case AF_INET6: + return (inet_pton6(src, dst)); + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(src, dst) + const char *src; + u_char *dst; +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + u_char tmp[INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + u_int new = *tp * 10 + (pch - digits); + + if (new > 255) + return (0); + *tp = new; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + + memcpy(dst, tmp, INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton6(src, dst) + const char *src; + u_char *dst; +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + u_int val; + + memset((tp = tmp), '\0', IN6ADDRSZ); + endp = tp + IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + INT16SZ > endp) + return (0); + *tp++ = (u_char) (val >> 8) & 0xff; + *tp++ = (u_char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, IN6ADDRSZ); + return (1); +} diff --git a/lib/libc/net/res_data.c b/lib/libc/net/map_v4v6.c index 0d17bc2..f4fdc23 100644 --- a/lib/libc/net/res_data.c +++ b/lib/libc/net/map_v4v6.c @@ -1,7 +1,7 @@ /* - * ++Copyright++ 1995 + * ++Copyright++ 1985, 1988, 1993 * - - * Copyright (c) 1995 + * Copyright (c) 1985, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,61 +54,74 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$Id: res_data.c,v 8.1 1995/12/22 10:21:29 vixie Exp $"; +static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: gethnamaddr.c,v 8.17 1996/08/05 08:31:35 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ +#include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> -#include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/nameser.h> #include <stdio.h> -#include <ctype.h> +#include <netdb.h> #include <resolv.h> -#if defined(BSD) && (BSD >= 199103) -# include <unistd.h> -# include <stdlib.h> -# include <string.h> -#else -# include "../conf/portability.h" -#endif +#include <ctype.h> +#include <errno.h> +#include <syslog.h> + +typedef union { + int32_t al; + char ac; +} align; + +void +_map_v4v6_address(src, dst) + const char *src; + char *dst; +{ + u_char *p = (u_char *)dst; + char tmp[INADDRSZ]; + int i; + + /* Stash a temporary copy so our caller can update in place. */ + bcopy(src, tmp, INADDRSZ); + /* Mark this ipv6 addr as a mapped ipv4. */ + for (i = 0; i < 10; i++) + *p++ = 0x00; + *p++ = 0xff; + *p++ = 0xff; + /* Retrieve the saved copy and we're done. */ + bcopy(tmp, (void*)p, INADDRSZ); +} + +void +_map_v4v6_hostent(hp, bpp, lenp) + struct hostent *hp; + char **bpp; + int *lenp; +{ + char **ap; -const char *_res_opcodes[] = { - "QUERY", - "IQUERY", - "CQUERYM", - "CQUERYU", /* experimental */ - "NOTIFY", /* experimental */ - "5", - "6", - "7", - "8", - "UPDATEA", - "UPDATED", - "UPDATEDA", - "UPDATEM", - "UPDATEMA", - "ZONEINIT", - "ZONEREF", -}; + if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) + return; + hp->h_addrtype = AF_INET6; + hp->h_length = IN6ADDRSZ; + for (ap = hp->h_addr_list; *ap; ap++) { + int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); -const char *_res_resultcodes[] = { - "NOERROR", - "FORMERR", - "SERVFAIL", - "NXDOMAIN", - "NOTIMP", - "REFUSED", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "NOCHANGE", -}; + if (*lenp < (i + IN6ADDRSZ)) { + /* Out of memory. Truncate address list here. XXX */ + *ap = NULL; + return; + } + *bpp += i; + *lenp -= i; + _map_v4v6_address(*ap, *bpp); + *ap = *bpp; + *bpp += IN6ADDRSZ; + *lenp -= IN6ADDRSZ; + } +} diff --git a/lib/libc/net/nsap_addr.c b/lib/libc/net/nsap_addr.c new file mode 100644 index 0000000..fcbbf1e --- /dev/null +++ b/lib/libc/net/nsap_addr.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$Id: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <ctype.h> +#include <resolv.h> + +static char +xtob(c) + register int c; +{ + return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); +} + +u_int +inet_nsap_addr(ascii, binary, maxlen) + const char *ascii; + u_char *binary; + int maxlen; +{ + register u_char c, nib; + u_int len = 0; + + while ((c = *ascii++) != '\0' && len < maxlen) { + if (c == '.' || c == '+' || c == '/') + continue; + if (!isascii(c)) + return (0); + if (islower(c)) + c = toupper(c); + if (isxdigit(c)) { + nib = xtob(c); + if (c = *ascii++) { + c = toupper(c); + if (isxdigit(c)) { + *binary++ = (nib << 4) | xtob(c); + len++; + } else + return (0); + } + else + return (0); + } + else + return (0); + } + return (len); +} + +char * +inet_nsap_ntoa(binlen, binary, ascii) + int binlen; + register const u_char *binary; + register char *ascii; +{ + register int nib; + int i; + static char tmpbuf[255*3]; + char *start; + + if (ascii) + start = ascii; + else { + ascii = tmpbuf; + start = tmpbuf; + } + + if (binlen > 255) + binlen = 255; + + for (i = 0; i < binlen; i++) { + nib = *binary >> 4; + *ascii++ = nib + (nib < 10 ? '0' : '7'); + nib = *binary++ & 0x0f; + *ascii++ = nib + (nib < 10 ? '0' : '7'); + if (((i % 2) == 0 && (i + 1) < binlen)) + *ascii++ = '.'; + } + *ascii = '\0'; + return (start); +} diff --git a/lib/libc/net/res_comp.c b/lib/libc/net/res_comp.c deleted file mode 100644 index 523aa19..0000000 --- a/lib/libc/net/res_comp.c +++ /dev/null @@ -1,378 +0,0 @@ -/*- - * Copyright (c) 1985, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * 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 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_comp.c,v 1.4 1996/01/07 09:14:54 peter Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <stdio.h> -#include <resolv.h> -#include <ctype.h> - -#include <unistd.h> -#include <string.h> - -static int dn_find __P((u_char *exp_dn, u_char *msg, - u_char **dnptrs, u_char **lastdnptr)); - -/* - * Expand compressed domain name 'comp_dn' to full domain name. - * 'msg' is a pointer to the begining of the message, - * 'eomorig' points to the first location after the message, - * 'exp_dn' is a pointer to a buffer of size 'length' for the result. - * Return size of compressed name or -1 if there was an error. - */ -int -dn_expand(msg, eomorig, comp_dn, exp_dn, length) - const u_char *msg, *eomorig, *comp_dn; - char *exp_dn; - int length; -{ - register const u_char *cp; - register char *dn; - register int n, c; - char *eom; - int len = -1, checked = 0; - - dn = exp_dn; - cp = comp_dn; - eom = exp_dn + length; - /* - * fetch next label in domain name - */ - while ( (n = *cp++) ) { - /* - * Check for indirection - */ - switch (n & INDIR_MASK) { - case 0: - if (dn != exp_dn) { - if (dn >= eom) - return (-1); - *dn++ = '.'; - } - if (dn+n >= eom) - return (-1); - checked += n + 1; - while (--n >= 0) { - if (((c = *cp++) == '.') || (c == '\\')) { - if (dn + n + 2 >= eom) - return (-1); - *dn++ = '\\'; - } - *dn++ = c; - if (cp >= eomorig) /* out of range */ - return (-1); - } - break; - - case INDIR_MASK: - if (len < 0) - len = cp - comp_dn + 1; - cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); - if (cp < msg || cp >= eomorig) /* out of range */ - return (-1); - checked += 2; - /* - * Check for loops in the compressed name; - * if we've looked at the whole message, - * there must be a loop. - */ - if (checked >= eomorig - msg) - return (-1); - break; - - default: - return (-1); /* flag error */ - } - } - *dn = '\0'; - for (dn = exp_dn; (c = *dn) != '\0'; dn++) - if (isascii(c) && isspace(c)) - return (-1); - if (len < 0) - len = cp - comp_dn; - return (len); -} - -/* - * Compress domain name 'exp_dn' into 'comp_dn'. - * Return the size of the compressed name or -1. - * 'length' is the size of the array pointed to by 'comp_dn'. - * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] - * is a pointer to the beginning of the message. The list ends with NULL. - * 'lastdnptr' is a pointer to the end of the arrary pointed to - * by 'dnptrs'. Side effect is to update the list of pointers for - * labels inserted into the message as we compress the name. - * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' - * is NULL, we don't update the list. - */ -int -dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) - const char *exp_dn; - u_char *comp_dn, **dnptrs, **lastdnptr; - int length; -{ - register u_char *cp, *dn; - register int c, l; - u_char **cpp, **lpp, *sp, *eob; - u_char *msg; - - dn = (u_char *)exp_dn; - cp = comp_dn; - eob = cp + length; - lpp = cpp = NULL; - if (dnptrs != NULL) { - if ((msg = *dnptrs++) != NULL) { - for (cpp = dnptrs; *cpp != NULL; cpp++) - ; - lpp = cpp; /* end of list to search */ - } - } else - msg = NULL; - for (c = *dn++; c != '\0'; ) { - /* look to see if we can use pointers */ - if (msg != NULL) { - if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) { - if (cp+1 >= eob) - return (-1); - *cp++ = (l >> 8) | INDIR_MASK; - *cp++ = l % 256; - return (cp - comp_dn); - } - /* not found, save it */ - if (lastdnptr != NULL && cpp < lastdnptr-1) { - *cpp++ = cp; - *cpp = NULL; - } - } - sp = cp++; /* save ptr to length byte */ - do { - if (c == '.') { - c = *dn++; - break; - } - if (c == '\\') { - if ((c = *dn++) == '\0') - break; - } - if (cp >= eob) { - if (msg != NULL) - *lpp = NULL; - return (-1); - } - *cp++ = c; - } while ((c = *dn++) != '\0'); - /* catch trailing '.'s but not '..' */ - if ((l = cp - sp - 1) == 0 && c == '\0') { - cp--; - break; - } - if (l <= 0 || l > MAXLABEL) { - if (msg != NULL) - *lpp = NULL; - return (-1); - } - *sp = l; - } - if (cp >= eob) { - if (msg != NULL) - *lpp = NULL; - return (-1); - } - *cp++ = '\0'; - return (cp - comp_dn); -} - -/* - * Skip over a compressed domain name. Return the size or -1. - */ -int -__dn_skipname(comp_dn, eom) - const u_char *comp_dn, *eom; -{ - register const u_char *cp; - register int n; - - cp = comp_dn; - while (cp < eom && (n = *cp++)) { - /* - * check for indirection - */ - switch (n & INDIR_MASK) { - case 0: /* normal case, n == len */ - cp += n; - continue; - case INDIR_MASK: /* indirection */ - cp++; - break; - default: /* illegal type */ - return (-1); - } - break; - } - if (cp > eom) - return (-1); - return (cp - comp_dn); -} - -static int -mklower(ch) - register int ch; -{ - if (isascii(ch) && isupper(ch)) - return (tolower(ch)); - return (ch); -} - -/* - * Search for expanded name from a list of previously compressed names. - * Return the offset from msg if found or -1. - * dnptrs is the pointer to the first name on the list, - * not the pointer to the start of the message. - */ -static int -dn_find(exp_dn, msg, dnptrs, lastdnptr) - u_char *exp_dn, *msg; - u_char **dnptrs, **lastdnptr; -{ - register u_char *dn, *cp, **cpp; - register int n; - u_char *sp; - - for (cpp = dnptrs; cpp < lastdnptr; cpp++) { - dn = exp_dn; - sp = cp = *cpp; - while ( (n = *cp++) ) { - /* - * check for indirection - */ - switch (n & INDIR_MASK) { - case 0: /* normal case, n == len */ - while (--n >= 0) { - if (*dn == '.') - goto next; - if (*dn == '\\') - dn++; - if (mklower(*dn++) != mklower(*cp++)) - goto next; - } - if ((n = *dn++) == '\0' && *cp == '\0') - return (sp - msg); - if (n == '.') - continue; - goto next; - - case INDIR_MASK: /* indirection */ - cp = msg + (((n & 0x3f) << 8) | *cp); - break; - - default: /* illegal type */ - return (-1); - } - } - if (*dn == '\0') - return (sp - msg); - next: ; - } - return (-1); -} - -/* - * Routines to insert/extract short/long's. - */ - -u_int16_t -_getshort(msgp) - register const u_char *msgp; -{ - register u_int16_t u; - - GETSHORT(u, msgp); - return (u); -} - -u_int32_t -_getlong(msgp) - register const u_char *msgp; -{ - register u_int32_t u; - - GETLONG(u, msgp); - return (u); -} - -void -#if defined(__STDC__) || defined(__cplusplus) -__putshort(register u_int16_t s, register u_char *msgp) /* must match proto */ -#else -__putshort(s, msgp) - register u_int16_t s; - register u_char *msgp; -#endif -{ - PUTSHORT(s, msgp); -} - -void -__putlong(l, msgp) - register u_int32_t l; - register u_char *msgp; -{ - PUTLONG(l, msgp); -} diff --git a/lib/libc/net/res_config.h b/lib/libc/net/res_config.h index 7d55664..83c8d29 100644 --- a/lib/libc/net/res_config.h +++ b/lib/libc/net/res_config.h @@ -2,7 +2,7 @@ #undef ALLOW_T_UNSPEC /* enable the "unspec" RR type for old athena */ #define RESOLVSORT /* allow sorting of addresses in gethostbyname */ #define RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/ -#undef ALLOW_UPDATES /* destroy your system security */ #undef USELOOPBACK /* res_init() bind to localhost */ #undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */ -#define MULTI_PTRS_ARE_ALIASES /* fold multiple PTR records into aliases */ +#undef ALLOW_UPDATES /* compile support for update REQUESTS - harmless */ +#define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */ diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c deleted file mode 100644 index ad65fc7..0000000 --- a/lib/libc/net/res_debug.c +++ /dev/null @@ -1,806 +0,0 @@ -/*- - * Copyright (c) 1985, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * 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 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_debug.c,v 1.7 1996/02/06 20:35:48 wollman Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <netinet/in.h> -#ifdef ISO -#include <netiso/iso.h> -#endif - -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <stdio.h> -#include <netdb.h> -#include <resolv.h> -#include <string.h> - -#include "res_config.h" - -extern const char *_res_opcodes[]; -extern const char *_res_resultcodes[]; - -/* XXX: we should use getservbyport() instead. */ -static const char * -dewks(wks) - int wks; -{ - static char nbuf[20]; - - switch (wks) { - case 5: return "rje"; - case 7: return "echo"; - case 9: return "discard"; - case 11: return "systat"; - case 13: return "daytime"; - case 15: return "netstat"; - case 17: return "qotd"; - case 19: return "chargen"; - case 20: return "ftp-data"; - case 21: return "ftp"; - case 23: return "telnet"; - case 25: return "smtp"; - case 37: return "time"; - case 39: return "rlp"; - case 42: return "name"; - case 43: return "whois"; - case 53: return "domain"; - case 57: return "apts"; - case 59: return "apfs"; - case 67: return "bootps"; - case 68: return "bootpc"; - case 69: return "tftp"; - case 77: return "rje"; - case 79: return "finger"; - case 87: return "link"; - case 95: return "supdup"; - case 100: return "newacct"; - case 101: return "hostnames"; - case 102: return "iso-tsap"; - case 103: return "x400"; - case 104: return "x400-snd"; - case 105: return "csnet-ns"; - case 109: return "pop-2"; - case 111: return "sunrpc"; - case 113: return "auth"; - case 115: return "sftp"; - case 117: return "uucp-path"; - case 119: return "nntp"; - case 121: return "erpc"; - case 123: return "ntp"; - case 133: return "statsrv"; - case 136: return "profile"; - case 144: return "NeWS"; - case 161: return "snmp"; - case 162: return "snmp-trap"; - case 170: return "print-srv"; - default: (void) sprintf(nbuf, "%d", wks); return (nbuf); - } -} - -/* XXX: we should use getprotobynumber() instead. */ -static const char * -deproto(protonum) - int protonum; -{ - static char nbuf[20]; - - switch (protonum) { - case 1: return "icmp"; - case 2: return "igmp"; - case 3: return "ggp"; - case 5: return "st"; - case 6: return "tcp"; - case 7: return "ucl"; - case 8: return "egp"; - case 9: return "igp"; - case 11: return "nvp-II"; - case 12: return "pup"; - case 16: return "chaos"; - case 17: return "udp"; - default: (void) sprintf(nbuf, "%d", protonum); return (nbuf); - } -} - -static const u_char * -do_rrset(msg, len, cp, cnt, pflag, file, hs) - int cnt, pflag, len; - const u_char *cp, *msg; - const char *hs; - FILE *file; -{ - int n; - int sflag; - - /* - * Print answer records. - */ - sflag = (_res.pfcode & pflag); - if ( (n = ntohs(cnt)) ) { - if ((!_res.pfcode) || - ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) - fprintf(file, hs); - while (--n >= 0) { - if ((!_res.pfcode) || sflag) { - cp = p_rr(cp, msg, file); - } else { - unsigned int dlen; - cp += __dn_skipname(cp, cp + MAXCDNAME); - cp += INT16SZ; - cp += INT16SZ; - cp += INT32SZ; - dlen = _getshort((u_char*)cp); - cp += INT16SZ; - cp += dlen; - } - if ((cp - msg) > len) - return (NULL); - } - if ((!_res.pfcode) || - ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) - putc('\n', file); - } - return (cp); -} - -void -__p_query(msg) - const u_char *msg; -{ - __fp_query(msg, stdout); -} - -/* - * Print the current options. - * This is intended to be primarily a debugging routine. - */ -void -__fp_resstat(statp, file) - struct __res_state *statp; - FILE *file; -{ - register u_long mask; - - fprintf(file, ";; res options:"); - if (!statp) - statp = &_res; - for (mask = 1; mask != 0; mask <<= 1) - if (statp->options & mask) - fprintf(file, " %s", p_option(mask)); - putc('\n', file); -} - -/* - * Print the contents of a query. - * This is intended to be primarily a debugging routine. - */ -void -__fp_nquery(msg, len, file) - const u_char *msg; - int len; - FILE *file; -{ - register const u_char *cp, *endMark; - register const HEADER *hp; - register int n; - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) - return; - -#define TruncTest(x) if (x >= endMark) goto trunc -#define ErrorTest(x) if (x == NULL) goto error - - /* - * Print header fields. - */ - hp = (HEADER *)msg; - cp = msg + HFIXEDSZ; - endMark = cp + len; - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { - fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d", - _res_opcodes[hp->opcode], - _res_resultcodes[hp->rcode], - ntohs(hp->id)); - putc('\n', file); - } - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX)) - putc(';', file); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { - fprintf(file, "; flags:"); - if (hp->qr) - fprintf(file, " qr"); - if (hp->aa) - fprintf(file, " aa"); - if (hp->tc) - fprintf(file, " tc"); - if (hp->rd) - fprintf(file, " rd"); - if (hp->ra) - fprintf(file, " ra"); - } - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { - fprintf(file, "; Ques: %d", ntohs(hp->qdcount)); - fprintf(file, ", Ans: %d", ntohs(hp->ancount)); - fprintf(file, ", Auth: %d", ntohs(hp->nscount)); - fprintf(file, ", Addit: %d", ntohs(hp->arcount)); - } - if ((!_res.pfcode) || (_res.pfcode & - (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { - putc('\n',file); - } - /* - * Print question records. - */ - if ( (n = ntohs(hp->qdcount)) ) { - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ";; QUESTIONS:\n"); - while (--n >= 0) { - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ";;\t"); - TruncTest(cp); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - cp = p_cdnname(cp, msg, len, file); - else { - int n; - char name[MAXDNAME]; - - if ((n = dn_expand(msg, msg+len, cp, name, - sizeof name)) < 0) - cp = NULL; - else - cp += n; - } - ErrorTest(cp); - TruncTest(cp); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ", type = %s", - __p_type(_getshort((u_char*)cp))); - cp += INT16SZ; - TruncTest(cp); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ", class = %s\n", - __p_class(_getshort((u_char*)cp))); - cp += INT16SZ; - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - putc('\n', file); - } - } - /* - * Print authoritative answer records - */ - TruncTest(cp); - cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file, - ";; ANSWERS:\n"); - ErrorTest(cp); - - /* - * print name server records - */ - TruncTest(cp); - cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file, - ";; AUTHORITY RECORDS:\n"); - ErrorTest(cp); - - TruncTest(cp); - /* - * print additional records - */ - cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file, - ";; ADDITIONAL RECORDS:\n"); - ErrorTest(cp); - return; - trunc: - fprintf(file, "\n;; ...truncated\n"); - return; - error: - fprintf(file, "\n;; ...malformed\n"); -} - -void -__fp_query(msg, file) - const u_char *msg; - FILE *file; -{ - fp_nquery(msg, PACKETSZ, file); -} - -const u_char * -__p_cdnname(cp, msg, len, file) - const u_char *cp, *msg; - int len; - FILE *file; -{ - char name[MAXDNAME]; - int n; - - if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0) - return (NULL); - if (name[0] == '\0') - putc('.', file); - else - fputs(name, file); - return (cp + n); -} - -const u_char * -__p_cdname(cp, msg, file) - const u_char *cp, *msg; - FILE *file; -{ - return (p_cdnname(cp, msg, PACKETSZ, file)); -} - -/* XXX: the rest of these functions need to become length-limited, too. (vix) - */ - -const u_char * -__p_fqname(cp, msg, file) - const u_char *cp, *msg; - FILE *file; -{ - char name[MAXDNAME]; - int n; - - if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0) - return (NULL); - if (name[0] == '\0') { - putc('.', file); - } else { - fputs(name, file); - if (name[strlen(name) - 1] != '.') - putc('.', file); - } - return (cp + n); -} - -/* - * Print resource record fields in human readable form. - */ -const u_char * -__p_rr(cp, msg, file) - const u_char *cp, *msg; - FILE *file; -{ - int type, class, dlen, n, c; - struct in_addr inaddr; -#ifdef ISO - struct iso_addr isoa; -#endif - const u_char *cp1, *cp2; - u_int32_t tmpttl, t; - int lcnt; - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return (NULL); - } - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); /* compression error */ - type = _getshort((u_char*)cp); - cp += INT16SZ; - class = _getshort((u_char*)cp); - cp += INT16SZ; - tmpttl = _getlong((u_char*)cp); - cp += INT32SZ; - dlen = _getshort((u_char*)cp); - cp += INT16SZ; - cp1 = cp; - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) - fprintf(file, "\t%lu", (u_long)tmpttl); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) - fprintf(file, "\t%s", __p_class(class)); - fprintf(file, "\t%s", __p_type(type)); - /* - * Print type specific data, if appropriate - */ - switch (type) { - case T_A: - switch (class) { - case C_IN: - case C_HS: - bcopy(cp, (char *)&inaddr, INADDRSZ); - if (dlen == 4) { - fprintf(file, "\t%s", inet_ntoa(inaddr)); - cp += dlen; - } else if (dlen == 7) { - char *address; - u_char protocol; - u_short port; - - address = inet_ntoa(inaddr); - cp += INADDRSZ; - protocol = *(u_char*)cp; - cp += sizeof(u_char); - port = _getshort((u_char*)cp); - cp += INT16SZ; - fprintf(file, "\t%s\t; proto %d, port %d", - address, protocol, port); - } - break; - default: - cp += dlen; - } - break; - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - putc('\t', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_HINFO: - case T_ISDN: - cp2 = cp + dlen; - if ( (n = *cp++) ) { - fprintf(file, "\t%.*s", n, cp); - cp += n; - } - if ((cp < cp2) && (n = *cp++)) { - fprintf(file, "\t%.*s", n, cp); - cp += n; - } else if (type == T_HINFO) - fprintf(file, "\n;; *** Warning *** OS-type missing"); - break; - - case T_SOA: - putc('\t', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - putc(' ', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - fputs(" (\n", file); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", - (u_long)t, __p_time(t)); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; retry (%s)\n", - (u_long)t, __p_time(t)); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; expire (%s)\n", - (u_long)t, __p_time(t)); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu )\t; minimum (%s)", - (u_long)t, __p_time(t)); - break; - - case T_MX: - case T_AFSDB: - case T_RT: - fprintf(file, "\t%d ", _getshort((u_char*)cp)); - cp += INT16SZ; - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_PX: - fprintf(file, "\t%d ", _getshort((u_char*)cp)); - cp += INT16SZ; - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - putc(' ', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_TXT: - case T_X25: - (void) fputs("\t\"", file); - cp2 = cp1 + dlen; - while (cp < cp2) { - if ( (n = (unsigned char) *cp++) ) { - for (c = n; c > 0 && cp < cp2; c--) - if ((*cp == '\n') || (*cp == '"')) { - (void) putc('\\', file); - (void) putc(*cp++, file); - } else - (void) putc(*cp++, file); - } - } - putc('"', file); - break; - -#ifdef ISO - case T_NSAP: - isoa.isoa_len = dlen; - if (isoa.isoa_len > sizeof(isoa.isoa_genaddr)) - isoa.isoa_len = sizeof(isoa.isoa_genaddr); - bcopy(cp, isoa.isoa_genaddr, isoa.isoa_len); - (void) fprintf(file, "\t%s", iso_ntoa(&isoa)); - cp += dlen; - break; -#endif - - case T_MINFO: - case T_RP: - putc('\t', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - putc(' ', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_UINFO: - putc('\t', file); - fputs((char *)cp, file); - cp += dlen; - break; - - case T_UID: - case T_GID: - if (dlen == 4) { - fprintf(file, "\t%u", _getlong((u_char*)cp)); - cp += INT32SZ; - } - break; - - case T_WKS: - if (dlen < INT32SZ + 1) - break; - bcopy(cp, (char *)&inaddr, INADDRSZ); - cp += INT32SZ; - fprintf(file, "\t%s %s ( ", - inet_ntoa(inaddr), - deproto((int) *cp)); - cp += sizeof(u_char); - n = 0; - lcnt = 0; - while (cp < cp1 + dlen) { - c = *cp++; - do { - if (c & 0200) { - if (lcnt == 0) { - fputs("\n\t\t\t", file); - lcnt = 5; - } - fputs(dewks(n), file); - putc(' ', file); - lcnt--; - } - c <<= 1; - } while (++n & 07); - } - putc(')', file); - break; - -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: - { - int NumBytes = 8; - u_char *DataPtr; - int i; - - if (dlen < NumBytes) NumBytes = dlen; - fprintf(file, "\tFirst %d bytes of hex data:", - NumBytes); - for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) - fprintf(file, " %x", *DataPtr); - cp += dlen; - } - break; -#endif /* ALLOW_T_UNSPEC */ - - default: - fprintf(file, "\t?%d?", type); - cp += dlen; - } -#if 0 - fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl)); -#else - putc('\n', file); -#endif - if (cp - cp1 != dlen) { - fprintf(file, ";; packet size error (found %d, dlen was %d)\n", - cp - cp1, dlen); - cp = NULL; - } - return (cp); -} - -/* - * Return a string for the type - */ -const char * -__p_type(type) - int type; -{ - static char nbuf[20]; - - switch (type) { - case T_A: return "A"; - case T_NS: return "NS"; - case T_CNAME: return "CNAME"; - case T_SOA: return "SOA"; - case T_MB: return "MB"; - case T_MG: return "MG"; - case T_MR: return "MR"; - case T_NULL: return "NULL"; - case T_WKS: return "WKS"; - case T_PTR: return "PTR"; - case T_HINFO: return "HINFO"; - case T_MINFO: return "MINFO"; - case T_MX: return "MX"; - case T_TXT: return "TXT"; - case T_RP: return "RP"; - case T_AFSDB: return "AFSDB"; - case T_X25: return "X25"; - case T_ISDN: return "ISDN"; - case T_RT: return "RT"; - case T_NSAP: return "NSAP"; - case T_NSAP_PTR: return "NSAP_PTR"; - case T_SIG: return "SIG"; - case T_KEY: return "KEY"; - case T_PX: return "PX"; - case T_GPOS: return "GPOS"; - case T_AAAA: return "AAAA"; - case T_LOC: return "LOC"; - case T_AXFR: return "AXFR"; - case T_MAILB: return "MAILB"; - case T_MAILA: return "MAILA"; - case T_ANY: return "ANY"; - case T_UINFO: return "UINFO"; - case T_UID: return "UID"; - case T_GID: return "GID"; -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: return "UNSPEC"; -#endif /* ALLOW_T_UNSPEC */ - default: (void)sprintf(nbuf, "%d", type); return (nbuf); - } -} - -/* - * Return a mnemonic for class - */ -const char * -__p_class(class) - int class; -{ - static char nbuf[20]; - - switch (class) { - case C_IN: return "IN"; - case C_HS: return "HS"; - case C_ANY: return "ANY"; - default: (void)sprintf(nbuf, "%d", class); return (nbuf); - } -} - -/* - * Return a mnemonic for an option - */ -const char * -__p_option(option) - u_long option; -{ - static char nbuf[40]; - - switch (option) { - case RES_INIT: return "init"; - case RES_DEBUG: return "debug"; - case RES_AAONLY: return "aaonly(unimpl)"; - case RES_USEVC: return "usevc"; - case RES_PRIMARY: return "primry(unimpl)"; - case RES_IGNTC: return "igntc"; - case RES_RECURSE: return "recurs"; - case RES_DEFNAMES: return "defnam"; - case RES_STAYOPEN: return "styopn"; - case RES_DNSRCH: return "dnsrch"; - case RES_INSECURE1: return "insecure1"; - case RES_INSECURE2: return "insecure2"; - default: sprintf(nbuf, "?0x%lx?", (u_long)option); - return (nbuf); - } -} - -/* - * Return a mnemonic for a time to live - */ -char * -__p_time(value) - u_int32_t value; -{ - static char nbuf[40]; - int secs, mins, hours, days; - register char *p; - - if (value == 0) { - strcpy(nbuf, "0 secs"); - return (nbuf); - } - - secs = value % 60; - value /= 60; - mins = value % 60; - value /= 60; - hours = value % 24; - value /= 24; - days = value; - value = 0; - -#define PLURALIZE(x) x, (x == 1) ? "" : "s" - p = nbuf; - if (days) { - (void)sprintf(p, "%d day%s", PLURALIZE(days)); - while (*++p); - } - if (hours) { - if (days) - *p++ = ' '; - (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); - while (*++p); - } - if (mins) { - if (days || hours) - *p++ = ' '; - (void)sprintf(p, "%d min%s", PLURALIZE(mins)); - while (*++p); - } - if (secs || ! (days || hours || mins)) { - if (days || hours || mins) - *p++ = ' '; - (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); - } - return (nbuf); -} diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c deleted file mode 100644 index e309d9c..0000000 --- a/lib/libc/net/res_init.c +++ /dev/null @@ -1,449 +0,0 @@ -/*- - * Copyright (c) 1985, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * 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 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; -static char rcsid[] = "$Id: res_init.c,v 1.6 1995/08/21 09:15:36 bde Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <stdio.h> -#include <ctype.h> -#include <resolv.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - -#include "res_config.h" - -static void res_setoptions __P((char *, char *)); - -#ifdef RESOLVSORT -static const char sort_mask[] = "/&"; -#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL) -static u_int32_t net_mask __P((struct in_addr)); -#endif - -/* - * Resolver state default settings. - */ - -struct __res_state _res; - -/* - * Set up default settings. If the configuration file exist, the values - * there will have precedence. Otherwise, the server address is set to - * INADDR_ANY and the default domain name comes from the gethostname(). - * - * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 - * rather than INADDR_ANY ("0.0.0.0") as the default name server address - * since it was noted that INADDR_ANY actually meant ``the first interface - * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, - * it had to be "up" in order for you to reach your own name server. It - * was later decided that since the recommended practice is to always - * install local static routes through 127.0.0.1 for all your network - * interfaces, that we could solve this problem without a code change. - * - * The configuration file should always be used, since it is the only way - * to specify a default domain. If you are running a server on your local - * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" - * in the configuration file. - * - * Return 0 if completes successfully, -1 on error - */ -int -res_init() -{ - register FILE *fp; - register char *cp, **pp; - register int n; - char buf[BUFSIZ]; - int nserv = 0; /* number of nameserver records read from file */ - int haveenv = 0; - int havesearch = 0; -#ifdef RESOLVSORT - int nsort = 0; - char *net; -#endif -#ifndef RFC1535 - int dots; -#endif - - /* - * These three fields used to be statically initialized. This made - * it hard to use this code in a shared library. It is necessary, - * now that we're doing dynamic initialization here, that we preserve - * the old semantics: if an application modifies one of these three - * fields of _res before res_init() is called, res_init() will not - * alter them. Of course, if an application is setting them to - * _zero_ before calling res_init(), hoping to override what used - * to be the static default, we can't detect it and unexpected results - * will follow. Zero for any of these fields would make no sense, - * so one can safely assume that the applications were already getting - * unexpected results. - * - * _res.options is tricky since some apps were known to diddle the bits - * before res_init() was first called. We can't replicate that semantic - * with dynamic initialization (they may have turned bits off that are - * set in RES_DEFAULT). Our solution is to declare such applications - * "broken". They could fool us by setting RES_INIT but none do (yet). - */ - if (!_res.retrans) - _res.retrans = RES_TIMEOUT; - if (!_res.retry) - _res.retry = 4; - if (!(_res.options & RES_INIT)) - _res.options = RES_DEFAULT; - - /* - * This one used to initialize implicitly to zero, so unless the app - * has set it to something in particular, we can randomize it now. - */ - if (!_res.id) - _res.id = res_randomid(); - -#ifdef USELOOPBACK - _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); -#else - _res.nsaddr.sin_addr.s_addr = INADDR_ANY; -#endif - _res.nsaddr.sin_family = AF_INET; - _res.nsaddr.sin_port = htons(NAMESERVER_PORT); - _res.nscount = 1; - _res.ndots = 1; - _res.pfcode = 0; - - /* Allow user to override the local domain definition */ - if ((cp = getenv("LOCALDOMAIN")) != NULL) { - (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); - haveenv++; - - /* - * Set search list to be blank-separated strings - * from rest of env value. Permits users of LOCALDOMAIN - * to still have a search list, and anyone to set the - * one that they want to use as an individual (even more - * important now that the rfc1535 stuff restricts searches) - */ - cp = _res.defdname; - pp = _res.dnsrch; - *pp++ = cp; - for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { - if (*cp == '\n') /* silly backwards compat */ - break; - else if (*cp == ' ' || *cp == '\t') { - *cp = 0; - n = 1; - } else if (n) { - *pp++ = cp; - n = 0; - havesearch = 1; - } - } - /* null terminate last domain if there are excess */ - while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') - cp++; - *cp = '\0'; - *pp++ = 0; - } - -#define MATCH(line, name) \ - (!strncmp(line, name, sizeof(name) - 1) && \ - (line[sizeof(name) - 1] == ' ' || \ - line[sizeof(name) - 1] == '\t')) - - if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { - /* read the config file */ - while (fgets(buf, sizeof(buf), fp) != NULL) { - /* skip comments */ - if (*buf == ';' || *buf == '#') - continue; - /* read default domain name */ - if (MATCH(buf, "domain")) { - if (haveenv) /* skip if have from environ */ - continue; - cp = buf + sizeof("domain") - 1; - while (*cp == ' ' || *cp == '\t') - cp++; - if ((*cp == '\0') || (*cp == '\n')) - continue; - strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); - if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) - *cp = '\0'; - havesearch = 0; - continue; - } - /* set search list */ - if (MATCH(buf, "search")) { - if (haveenv) /* skip if have from environ */ - continue; - cp = buf + sizeof("search") - 1; - while (*cp == ' ' || *cp == '\t') - cp++; - if ((*cp == '\0') || (*cp == '\n')) - continue; - strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); - if ((cp = strchr(_res.defdname, '\n')) != NULL) - *cp = '\0'; - /* - * Set search list to be blank-separated strings - * on rest of line. - */ - cp = _res.defdname; - pp = _res.dnsrch; - *pp++ = cp; - for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { - if (*cp == ' ' || *cp == '\t') { - *cp = 0; - n = 1; - } else if (n) { - *pp++ = cp; - n = 0; - } - } - /* null terminate last domain if there are excess */ - while (*cp != '\0' && *cp != ' ' && *cp != '\t') - cp++; - *cp = '\0'; - *pp++ = 0; - havesearch = 1; - continue; - } - /* read nameservers to query */ - if (MATCH(buf, "nameserver") && nserv < MAXNS) { - struct in_addr a; - - cp = buf + sizeof("nameserver") - 1; - while (*cp == ' ' || *cp == '\t') - cp++; - if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { - _res.nsaddr_list[nserv].sin_addr = a; - _res.nsaddr_list[nserv].sin_family = AF_INET; - _res.nsaddr_list[nserv].sin_port = - htons(NAMESERVER_PORT); - nserv++; - } - continue; - } -#ifdef RESOLVSORT - if (MATCH(buf, "sortlist")) { - struct in_addr a; - - cp = buf + sizeof("sortlist") - 1; - while (nsort < MAXRESOLVSORT) { - while (*cp == ' ' || *cp == '\t') - cp++; - if (*cp == '\0' || *cp == '\n' || *cp == ';') - break; - net = cp; - while (*cp && !ISSORTMASK(*cp) && *cp != ';' && - isascii(*cp) && !isspace(*cp)) - cp++; - n = *cp; - *cp = 0; - if (inet_aton(net, &a)) { - _res.sort_list[nsort].addr = a; - if (ISSORTMASK(n)) { - *cp++ = n; - net = cp; - while (*cp && *cp != ';' && - isascii(*cp) && !isspace(*cp)) - cp++; - n = *cp; - *cp = 0; - if (inet_aton(net, &a)) { - _res.sort_list[nsort].mask = a.s_addr; - } else { - _res.sort_list[nsort].mask = - net_mask(_res.sort_list[nsort].addr); - } - } else { - _res.sort_list[nsort].mask = - net_mask(_res.sort_list[nsort].addr); - } - nsort++; - } - *cp = n; - } - continue; - } -#endif - if (MATCH(buf, "options")) { - res_setoptions(buf + sizeof("options") - 1, "conf"); - continue; - } - } - if (nserv > 1) - _res.nscount = nserv; -#ifdef RESOLVSORT - _res.nsort = nsort; -#endif - (void) fclose(fp); - } - if (_res.defdname[0] == 0 && - gethostname(buf, sizeof(_res.defdname) - 1) == 0 && - (cp = strchr(buf, '.')) != NULL) - strcpy(_res.defdname, cp + 1); - - /* find components of local domain that might be searched */ - if (havesearch == 0) { - pp = _res.dnsrch; - *pp++ = _res.defdname; - *pp = NULL; - -#ifndef RFC1535 - dots = 0; - for (cp = _res.defdname; *cp; cp++) - dots += (*cp == '.'); - - cp = _res.defdname; - while (pp < _res.dnsrch + MAXDFLSRCH) { - if (dots < LOCALDOMAINPARTS) - break; - cp = strchr(cp, '.') + 1; /* we know there is one */ - *pp++ = cp; - dots--; - } - *pp = NULL; -#ifdef DEBUG - if (_res.options & RES_DEBUG) { - printf(";; res_init()... default dnsrch list:\n"); - for (pp = _res.dnsrch; *pp; pp++) - printf(";;\t%s\n", *pp); - printf(";;\t..END..\n"); - } -#endif /* DEBUG */ -#endif /* !RFC1535 */ - } - - if ((cp = getenv("RES_OPTIONS")) != NULL) - res_setoptions(cp, "env"); - _res.options |= RES_INIT; - return (0); -} - -static void -res_setoptions(options, source) - char *options, *source; -{ - char *cp = options; - int i; - -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_setoptions(\"%s\", \"%s\")...\n", - options, source); -#endif - while (*cp) { - /* skip leading and inner runs of spaces */ - while (*cp == ' ' || *cp == '\t') - cp++; - /* search for and process individual options */ - if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) { - i = atoi(cp + sizeof("ndots:") - 1); - if (i <= RES_MAXNDOTS) - _res.ndots = i; - else - _res.ndots = RES_MAXNDOTS; -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";;\tndots=%d\n", _res.ndots); -#endif - } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) { -#ifdef DEBUG - if (!(_res.options & RES_DEBUG)) { - printf(";; res_setoptions(\"%s\", \"%s\")..\n", - options, source); - _res.options |= RES_DEBUG; - } - printf(";;\tdebug\n"); -#endif - } else { - /* XXX - print a warning here? */ - } - /* skip to next run of spaces */ - while (*cp && *cp != ' ' && *cp != '\t') - cp++; - } -} - -#ifdef RESOLVSORT -/* XXX - should really support CIDR which means explicit masks always. */ -static u_int32_t -net_mask(in) /* XXX - should really use system's version of this */ - struct in_addr in; -{ - register u_int32_t i = ntohl(in.s_addr); - - if (IN_CLASSA(i)) - return (htonl(IN_CLASSA_NET)); - else if (IN_CLASSB(i)) - return (htonl(IN_CLASSB_NET)); - return (htonl(IN_CLASSC_NET)); -} -#endif - -u_int16_t -res_randomid() -{ - struct timeval now; - - gettimeofday(&now, NULL); - return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid())); -} diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c deleted file mode 100644 index 75a9a5a..0000000 --- a/lib/libc/net/res_mkquery.c +++ /dev/null @@ -1,241 +0,0 @@ -/*- - * Copyright (c) 1985, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * 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 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_mkquery.c,v 1.6 1995/08/21 09:15:37 bde Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <netinet/in.h> -#include <arpa/nameser.h> - -#include <stdio.h> -#include <netdb.h> -#include <resolv.h> -#include <string.h> - -#include "res_config.h" - -/* - * Form all types of queries. - * Returns the size of the result or -1. - */ -int -res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) - int op; /* opcode of query */ - const char *dname; /* domain name */ - int class, type; /* class and type of query */ - const u_char *data; /* resource record data */ - int datalen; /* length of data */ - const u_char *newrr_in; /* new rr for modify or append */ - u_char *buf; /* buffer to put query */ - int buflen; /* size of buffer */ -{ - register HEADER *hp; - register u_char *cp; - register int n; -#ifdef ALLOW_UPDATES - struct rrec *newrr = (struct rrec *) newrr_in; -#endif - u_char *dnptrs[20], **dpp, **lastdnptr; - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return (-1); - } -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_mkquery(%d, %s, %d, %d)\n", - op, dname, class, type); -#endif - /* - * Initialize header fields. - */ - if ((buf == NULL) || (buflen < HFIXEDSZ)) - return (-1); - bzero(buf, HFIXEDSZ); - hp = (HEADER *) buf; - hp->id = htons(++_res.id); - hp->opcode = op; - hp->rd = (_res.options & RES_RECURSE) != 0; - hp->rcode = NOERROR; - cp = buf + HFIXEDSZ; - buflen -= HFIXEDSZ; - dpp = dnptrs; - *dpp++ = buf; - *dpp++ = NULL; - lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; - /* - * perform opcode specific processing - */ - switch (op) { - case QUERY: /*FALLTHROUGH*/ - case NS_NOTIFY_OP: - if ((buflen -= QFIXEDSZ) < 0) - return (-1); - if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) - return (-1); - cp += n; - buflen -= n; - __putshort(type, cp); - cp += INT16SZ; - __putshort(class, cp); - cp += INT16SZ; - hp->qdcount = htons(1); - if (op == QUERY || data == NULL) - break; - /* - * Make an additional record for completion domain. - */ - buflen -= RRFIXEDSZ; - n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); - if (n < 0) - return (-1); - cp += n; - buflen -= n; - __putshort(T_NULL, cp); - cp += INT16SZ; - __putshort(class, cp); - cp += INT16SZ; - __putlong(0, cp); - cp += INT32SZ; - __putshort(0, cp); - cp += INT16SZ; - hp->arcount = htons(1); - break; - - case IQUERY: - /* - * Initialize answer section - */ - if (buflen < 1 + RRFIXEDSZ + datalen) - return (-1); - *cp++ = '\0'; /* no domain name */ - __putshort(type, cp); - cp += INT16SZ; - __putshort(class, cp); - cp += INT16SZ; - __putlong(0, cp); - cp += INT32SZ; - __putshort(datalen, cp); - cp += INT16SZ; - if (datalen) { - bcopy(data, cp, datalen); - cp += datalen; - } - hp->ancount = htons(1); - break; - -#ifdef ALLOW_UPDATES - /* - * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA - * (Record to be modified is followed by its replacement in msg.) - */ - case UPDATEM: - case UPDATEMA: - - case UPDATED: - /* - * The res code for UPDATED and UPDATEDA is the same; user - * calls them differently: specifies data for UPDATED; server - * ignores data if specified for UPDATEDA. - */ - case UPDATEDA: - buflen -= RRFIXEDSZ + datalen; - if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) - return (-1); - cp += n; - __putshort(type, cp); - cp += INT16SZ; - __putshort(class, cp); - cp += INT16SZ; - __putlong(0, cp); - cp += INT32SZ; - __putshort(datalen, cp); - cp += INT16SZ; - if (datalen) { - bcopy(data, cp, datalen); - cp += datalen; - } - if ( (op == UPDATED) || (op == UPDATEDA) ) { - hp->ancount = htons(0); - break; - } - /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ - - case UPDATEA: /* Add new resource record */ - buflen -= RRFIXEDSZ + datalen; - if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) - return (-1); - cp += n; - __putshort(newrr->r_type, cp); - cp += INT16SZ; - __putshort(newrr->r_class, cp); - cp += INT16SZ; - __putlong(0, cp); - cp += INT32SZ; - __putshort(newrr->r_size, cp); - cp += INT16SZ; - if (newrr->r_size) { - bcopy(newrr->r_data, cp, newrr->r_size); - cp += newrr->r_size; - } - hp->ancount = htons(0); - break; -#endif /* ALLOW_UPDATES */ - default: - return (-1); - } - return (cp - buf); -} diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c deleted file mode 100644 index 77a6950..0000000 --- a/lib/libc/net/res_query.c +++ /dev/null @@ -1,383 +0,0 @@ -/*- - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * 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 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_query.c,v 1.6 1995/08/21 09:15:39 bde Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <sys/param.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <stdio.h> -#include <netdb.h> -#include <resolv.h> -#include <ctype.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include "res_config.h" - -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif - -char *__hostalias __P((const char *)); -int h_errno; - -/* - * Formulate a normal query, send, and await answer. - * Returned answer is placed in supplied buffer "answer". - * Perform preliminary check of answer, returning success only - * if no error is indicated and the answer count is nonzero. - * Return the size of the response on success, -1 on error. - * Error number is left in h_errno. - * - * Caller must parse answer and determine whether it answers the question. - */ -int -res_query(name, class, type, answer, anslen) - const char *name; /* domain name */ - int class, type; /* class and type of query */ - u_char *answer; /* buffer to put answer */ - int anslen; /* size of answer buffer */ -{ - u_char buf[MAXPACKET]; - register HEADER *hp = (HEADER *) answer; - int n; - - hp->rcode = NOERROR; /* default */ - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return (-1); - } -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_query(%s, %d, %d)\n", name, class, type); -#endif - - n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, - buf, sizeof(buf)); - if (n <= 0) { -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_query: mkquery failed\n"); -#endif - h_errno = NO_RECOVERY; - return (n); - } - n = res_send(buf, n, answer, anslen); - if (n < 0) { -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_query: send error\n"); -#endif - h_errno = TRY_AGAIN; - return (n); - } - - if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; rcode = %d, ancount=%d\n", hp->rcode, - ntohs(hp->ancount)); -#endif - switch (hp->rcode) { - case NXDOMAIN: - h_errno = HOST_NOT_FOUND; - break; - case SERVFAIL: - h_errno = TRY_AGAIN; - break; - case NOERROR: - h_errno = NO_DATA; - break; - case FORMERR: - case NOTIMP: - case REFUSED: - default: - h_errno = NO_RECOVERY; - break; - } - return (-1); - } - return (n); -} - -/* - * Formulate a normal query, send, and retrieve answer in supplied buffer. - * Return the size of the response on success, -1 on error. - * If enabled, implement search rules until answer or unrecoverable failure - * is detected. Error code, if any, is left in h_errno. - */ -int -res_search(name, class, type, answer, anslen) - const char *name; /* domain name */ - int class, type; /* class and type of query */ - u_char *answer; /* buffer to put answer */ - int anslen; /* size of answer */ -{ - register const char *cp, * const *domain; - HEADER *hp = (HEADER *) answer; - u_int dots; - int trailing_dot, ret, saved_herrno; - int got_nodata = 0, got_servfail = 0, tried_as_is = 0; - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return (-1); - } - errno = 0; - h_errno = HOST_NOT_FOUND; /* default, if we never query */ - dots = 0; - for (cp = name; *cp; cp++) - dots += (*cp == '.'); - trailing_dot = 0; - if (cp > name && *--cp == '.') - trailing_dot++; - - /* - * if there aren't any dots, it could be a user-level alias - */ - if (!dots && (cp = __hostalias(name)) != NULL) - return (res_query(cp, class, type, answer, anslen)); - - /* - * If there are dots in the name already, let's just give it a try - * 'as is'. The threshold can be set with the "ndots" option. - */ - saved_herrno = -1; - if (dots >= _res.ndots) { - ret = res_querydomain(name, NULL, class, type, answer, anslen); - if (ret > 0) - return (ret); - saved_herrno = h_errno; - tried_as_is++; - } - - /* - * We do at least one level of search if - * - there is no dot and RES_DEFNAME is set, or - * - there is at least one dot, there is no trailing dot, - * and RES_DNSRCH is set. - */ - if ((!dots && (_res.options & RES_DEFNAMES)) || - (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { - int done = 0; - - for (domain = (const char * const *)_res.dnsrch; - *domain && !done; - domain++) { - - ret = res_querydomain(name, *domain, class, type, - answer, anslen); - if (ret > 0) - return (ret); - - /* - * If no server present, give up. - * If name isn't found in this domain, - * keep trying higher domains in the search list - * (if that's enabled). - * On a NO_DATA error, keep trying, otherwise - * a wildcard entry of another type could keep us - * from finding this entry higher in the domain. - * If we get some other error (negative answer or - * server failure), then stop searching up, - * but try the input name below in case it's - * fully-qualified. - */ - if (errno == ECONNREFUSED) { - h_errno = TRY_AGAIN; - return (-1); - } - - switch (h_errno) { - case NO_DATA: - got_nodata++; - /* FALLTHROUGH */ - case HOST_NOT_FOUND: - /* keep trying */ - break; - case TRY_AGAIN: - if (hp->rcode == SERVFAIL) { - /* try next search element, if any */ - got_servfail++; - break; - } - /* FALLTHROUGH */ - default: - /* anything else implies that we're done */ - done++; - } - - /* if we got here for some reason other than DNSRCH, - * we only wanted one iteration of the loop, so stop. - */ - if (!(_res.options & RES_DNSRCH)) - done++; - } - } - - /* if we have not already tried the name "as is", do that now. - * note that we do this regardless of how many dots were in the - * name or whether it ends with a dot. - */ - if (!tried_as_is) { - ret = res_querydomain(name, NULL, class, type, answer, anslen); - if (ret > 0) - return (ret); - } - - /* if we got here, we didn't satisfy the search. - * if we did an initial full query, return that query's h_errno - * (note that we wouldn't be here if that query had succeeded). - * else if we ever got a nodata, send that back as the reason. - * else send back meaningless h_errno, that being the one from - * the last DNSRCH we did. - */ - if (saved_herrno != -1) - h_errno = saved_herrno; - else if (got_nodata) - h_errno = NO_DATA; - else if (got_servfail) - h_errno = TRY_AGAIN; - return (-1); -} - -/* - * Perform a call on res_query on the concatenation of name and domain, - * removing a trailing dot from name if domain is NULL. - */ -int -res_querydomain(name, domain, class, type, answer, anslen) - const char *name, *domain; - int class, type; /* class and type of query */ - u_char *answer; /* buffer to put answer */ - int anslen; /* size of answer */ -{ - char nbuf[2*MAXDNAME+2]; - const char *longname = nbuf; - int n; - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return (-1); - } -#ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_querydomain(%s, %s, %d, %d)\n", - name, domain?domain:"<Nil>", class, type); -#endif - if (domain == NULL) { - /* - * Check for trailing '.'; - * copy without '.' if present. - */ - n = strlen(name) - 1; - if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) { - bcopy(name, nbuf, n); - nbuf[n] = '\0'; - } else - longname = name; - } else - sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); - - return (res_query(longname, class, type, answer, anslen)); -} - -char * -__hostalias(name) - register const char *name; -{ - register char *cp1, *cp2; - FILE *fp; - char *file; - char buf[BUFSIZ]; - static char abuf[MAXDNAME]; - - if (_res.options & RES_NOALIASES) - return (NULL); - file = getenv("HOSTALIASES"); - if (file == NULL || (fp = fopen(file, "r")) == NULL) - return (NULL); - setbuf(fp, NULL); - buf[sizeof(buf) - 1] = '\0'; - while (fgets(buf, sizeof(buf), fp)) { - for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1) - ; - if (!*cp1) - break; - *cp1 = '\0'; - if (!strcasecmp(buf, name)) { - while (isspace(*++cp1)) - ; - if (!*cp1) - break; - for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) - ; - abuf[sizeof(abuf) - 1] = *cp2 = '\0'; - strncpy(abuf, cp1, sizeof(abuf) - 1); - fclose(fp); - return (abuf); - } - } - fclose(fp); - return (NULL); -} diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c deleted file mode 100644 index eb1b321..0000000 --- a/lib/libc/net/res_send.c +++ /dev/null @@ -1,727 +0,0 @@ -/*- - * Copyright (c) 1985, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * 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 - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_send.c,v 1.7 1996/01/07 09:15:02 peter Exp $"; -#endif /* LIBC_SCCS and not lint */ - - /* change this to "0" - * if you talk to a lot - * of multi-homed SunOS - * ("broken") name servers. - */ -#define CHECK_SRVR_ADDR 1 /* XXX - should be in res_config.h */ - -/* - * Send query to name server and wait for reply. - */ - -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/uio.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> - -#include <stdio.h> -#include <errno.h> -#include <resolv.h> -#include <netdb.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "res_config.h" - -void _res_close __P((void)); - -static int s = -1; /* socket used for communications */ -static int connected = 0; /* is the socket connected */ -static int vc = 0; /* is the socket a virtual ciruit? */ - -#ifndef DEBUG -# define Dprint(cond, args) /*empty*/ -# define DprintQ(cond, args, query, size) /*empty*/ -# define Aerror(file, string, error, address) /*empty*/ -# define Perror(file, string, error) /*empty*/ -#else -# define Dprint(cond, args) if (cond) {fprintf args;} else {} -# define DprintQ(cond, args, query, size) if (cond) {\ - fprintf args;\ - __fp_nquery(query, size, stdout);\ - } else {} - static void - Aerror(file, string, error, address) - FILE *file; - char *string; - int error; - struct sockaddr_in address; - { - int save = errno; - - if (_res.options & RES_DEBUG) { - fprintf(file, "res_send: %s ([%s].%u): %s\n", - string, - inet_ntoa(address.sin_addr), - ntohs(address.sin_port), - strerror(error)); - } - errno = save; - } - static void - Perror(file, string, error) - FILE *file; - char *string; - int error; - { - int save = errno; - - if (_res.options & RES_DEBUG) { - fprintf(file, "res_send: %s: %s\n", - string, strerror(error)); - } - errno = save; - } -#endif - -static res_send_qhook Qhook = NULL; -static res_send_rhook Rhook = NULL; - -void -res_send_setqhook(hook) - res_send_qhook hook; -{ - - Qhook = hook; -} - -void -res_send_setrhook(hook) - res_send_rhook hook; -{ - - Rhook = hook; -} - -/* int - * res_isourserver(ina) - * looks up "ina" in _res.ns_addr_list[] - * returns: - * 0 : not found - * >0 : found - * author: - * paul vixie, 29may94 - */ -int -res_isourserver(inp) - const struct sockaddr_in *inp; -{ - struct sockaddr_in ina; - register int ns, ret; - - ina = *inp; - ret = 0; - for (ns = 0; ns < _res.nscount; ns++) { - register const struct sockaddr_in *srv = &_res.nsaddr_list[ns]; - - if (srv->sin_family == ina.sin_family && - srv->sin_port == ina.sin_port && - (srv->sin_addr.s_addr == INADDR_ANY || - srv->sin_addr.s_addr == ina.sin_addr.s_addr)) { - ret++; - break; - } - } - return (ret); -} - -/* int - * res_nameinquery(name, type, class, buf, eom) - * look for (name,type,class) in the query section of packet (buf,eom) - * returns: - * -1 : format error - * 0 : not found - * >0 : found - * author: - * paul vixie, 29may94 - */ -int -res_nameinquery(name, type, class, buf, eom) - const char *name; - register int type, class; - const u_char *buf, *eom; -{ - register const u_char *cp = buf + HFIXEDSZ; - int qdcount = ntohs(((HEADER*)buf)->qdcount); - - while (qdcount-- > 0) { - char tname[MAXDNAME+1]; - register int n, ttype, tclass; - - n = dn_expand(buf, eom, cp, tname, sizeof tname); - if (n < 0) - return (-1); - cp += n; - ttype = _getshort(cp); cp += INT16SZ; - tclass = _getshort(cp); cp += INT16SZ; - if (ttype == type && - tclass == class && - strcasecmp(tname, name) == 0) - return (1); - } - return (0); -} - -/* int - * res_queriesmatch(buf1, eom1, buf2, eom2) - * is there a 1:1 mapping of (name,type,class) - * in (buf1,eom1) and (buf2,eom2)? - * returns: - * -1 : format error - * 0 : not a 1:1 mapping - * >0 : is a 1:1 mapping - * author: - * paul vixie, 29may94 - */ -int -res_queriesmatch(buf1, eom1, buf2, eom2) - const u_char *buf1, *eom1; - const u_char *buf2, *eom2; -{ - register const u_char *cp = buf1 + HFIXEDSZ; - int qdcount = ntohs(((HEADER*)buf1)->qdcount); - - if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) - return (0); - while (qdcount-- > 0) { - char tname[MAXDNAME+1]; - register int n, ttype, tclass; - - n = dn_expand(buf1, eom1, cp, tname, sizeof tname); - if (n < 0) - return (-1); - cp += n; - ttype = _getshort(cp); cp += INT16SZ; - tclass = _getshort(cp); cp += INT16SZ; - if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) - return (0); - } - return (1); -} - -int -res_send(buf, buflen, ans, anssiz) - const u_char *buf; - int buflen; - u_char *ans; - int anssiz; -{ - HEADER *hp = (HEADER *) buf; - HEADER *anhp = (HEADER *) ans; - int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; - register int n; - u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - /* errno should have been set by res_init() in this case. */ - return (-1); - } - DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY), - (stdout, ";; res_send()\n"), buf, buflen); - v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; - gotsomewhere = 0; - connreset = 0; - terrno = ETIMEDOUT; - badns = 0; - - /* - * Send request, RETRY times, or until successful - */ - for (try = 0; try < _res.retry; try++) { - for (ns = 0; ns < _res.nscount; ns++) { - struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; - same_ns: - if (badns & (1 << ns)) { - _res_close(); - goto next_ns; - } - - if (Qhook) { - int done = 0, loops = 0; - - do { - res_sendhookact act; - - act = (*Qhook)(&nsap, &buf, &buflen, - ans, anssiz, &resplen); - switch (act) { - case res_goahead: - done = 1; - break; - case res_nextns: - _res_close(); - goto next_ns; - case res_done: - return (resplen); - case res_modified: - /* give the hook another try */ - if (++loops < 42) /*doug adams*/ - break; - /*FALLTHROUGH*/ - case res_error: - /*FALLTHROUGH*/ - default: - return (-1); - } - } while (!done); - } - - Dprint(_res.options & RES_DEBUG, - (stdout, ";; Querying server (# %d) address = %s\n", - ns + 1, inet_ntoa(nsap->sin_addr))); - - if (v_circuit) { - int truncated; - struct iovec iov[2]; - u_short len; - u_char *cp; - - /* - * Use virtual circuit; - * at most one attempt per server. - */ - try = _res.retry; - truncated = 0; - if ((s < 0) || (!vc)) { - if (s >= 0) - _res_close(); - - s = socket(PF_INET, SOCK_STREAM, 0); - if (s < 0) { - terrno = errno; - Perror(stderr, "socket(vc)", errno); - return (-1); - } - errno = 0; - if (connect(s, (struct sockaddr *)nsap, - sizeof(struct sockaddr)) < 0) { - terrno = errno; - Aerror(stderr, "connect/vc", - errno, *nsap); - badns |= (1 << ns); - _res_close(); - goto next_ns; - } - vc = 1; - } - /* - * Send length & message - */ - putshort((u_short)buflen, (u_char*)&len); - iov[0].iov_base = (caddr_t)&len; - iov[0].iov_len = INT16SZ; - iov[1].iov_base = (caddr_t)buf; - iov[1].iov_len = buflen; - if (writev(s, iov, 2) != (INT16SZ + buflen)) { - terrno = errno; - Perror(stderr, "write failed", errno); - badns |= (1 << ns); - _res_close(); - goto next_ns; - } - /* - * Receive length & response - */ - cp = ans; - len = INT16SZ; - while ((n = read(s, (char *)cp, (int)len)) > 0) { - cp += n; - if ((len -= n) <= 0) - break; - } - if (n <= 0) { - terrno = errno; - Perror(stderr, "read failed", errno); - _res_close(); - /* - * A long running process might get its TCP - * connection reset if the remote server was - * restarted. Requery the server instead of - * trying a new one. When there is only one - * server, this means that a query might work - * instead of failing. We only allow one reset - * per query to prevent looping. - */ - if (terrno == ECONNRESET && !connreset) { - connreset = 1; - _res_close(); - goto same_ns; - } - _res_close(); - goto next_ns; - } - resplen = _getshort(ans); - if (resplen > anssiz) { - Dprint(_res.options & RES_DEBUG, - (stdout, ";; response truncated\n") - ); - truncated = 1; - len = anssiz; - } else - len = resplen; - cp = ans; - while (len != 0 && - (n = read(s, (char *)cp, (int)len)) > 0) { - cp += n; - len -= n; - } - if (n <= 0) { - terrno = errno; - Perror(stderr, "read(vc)", errno); - _res_close(); - goto next_ns; - } - if (truncated) { - /* - * Flush rest of answer - * so connection stays in synch. - */ - anhp->tc = 1; - len = resplen - anssiz; - while (len != 0) { - char junk[PACKETSZ]; - - n = (len > sizeof(junk) - ? sizeof(junk) - : len); - if ((n = read(s, junk, n)) > 0) - len -= n; - else - break; - } - } - } else { - /* - * Use datagrams. - */ - struct timeval timeout; - fd_set dsmask; - struct sockaddr_in from; - int fromlen; - - if ((s < 0) || vc) { - if (vc) - _res_close(); - s = socket(PF_INET, SOCK_DGRAM, 0); - if (s < 0) { - terrno = errno; - Perror(stderr, "socket(dg)", errno); - return (-1); - } - connected = 0; - } - /* - * On a 4.3BSD+ machine (client and server, - * actually), sending to a nameserver datagram - * port with no nameserver will cause an - * ICMP port unreachable message to be returned. - * If our datagram socket is "connected" to the - * server, we get an ECONNREFUSED error on the next - * socket operation, and select returns if the - * error message is received. We can thus detect - * the absence of a nameserver without timing out. - * If we have sent queries to at least two servers, - * however, we don't want to remain connected, - * as we wish to receive answers from the first - * server to respond. - */ - if (_res.nscount == 1 || (try == 0 && ns == 0)) { - /* - * Connect only if we are sure we won't - * receive a response from another server. - */ - if (!connected) { - if (connect(s, (struct sockaddr *)nsap, - sizeof(struct sockaddr) - ) < 0) { - Aerror(stderr, - "connect(dg)", - errno, *nsap); - badns |= (1 << ns); - _res_close(); - goto next_ns; - } - connected = 1; - } - if (send(s, (char*)buf, buflen, 0) != buflen) { - Perror(stderr, "send", errno); - badns |= (1 << ns); - _res_close(); - goto next_ns; - } - } else { - /* - * Disconnect if we want to listen - * for responses from more than one server. - */ - if (connected) { - struct sockaddr_in no_addr; - - no_addr.sin_family = AF_INET; - no_addr.sin_addr.s_addr = INADDR_ANY; - no_addr.sin_port = 0; - (void) connect(s, - (struct sockaddr *) - &no_addr, - sizeof(no_addr)); - connected = 0; - errno = 0; - } - if (sendto(s, (char*)buf, buflen, 0, - (struct sockaddr *)nsap, - sizeof(struct sockaddr)) - != buflen) { - Aerror(stderr, "sendto", errno, *nsap); - badns |= (1 << ns); - _res_close(); - goto next_ns; - } - } - - /* - * Wait for reply - */ - timeout.tv_sec = (_res.retrans << try); - if (try > 0) - timeout.tv_sec /= _res.nscount; - if ((long) timeout.tv_sec <= 0) - timeout.tv_sec = 1; - timeout.tv_usec = 0; - wait: - FD_ZERO(&dsmask); - FD_SET(s, &dsmask); - n = select(s+1, &dsmask, (fd_set *)NULL, - (fd_set *)NULL, &timeout); - if (n < 0) { - Perror(stderr, "select", errno); - _res_close(); - goto next_ns; - } - if (n == 0) { - /* - * timeout - */ - Dprint(_res.options & RES_DEBUG, - (stdout, ";; timeout\n")); - gotsomewhere = 1; - _res_close(); - goto next_ns; - } - errno = 0; - fromlen = sizeof(struct sockaddr_in); - resplen = recvfrom(s, (char*)ans, anssiz, 0, - (struct sockaddr *)&from, &fromlen); - if (resplen <= 0) { - Perror(stderr, "recvfrom", errno); - _res_close(); - goto next_ns; - } - gotsomewhere = 1; - if (hp->id != anhp->id) { - /* - * response from old query, ignore it. - * XXX - potential security hazard could - * be detected here. - */ - DprintQ((_res.options & RES_DEBUG) || - (_res.pfcode & RES_PRF_REPLY), - (stdout, ";; old answer:\n"), - ans, resplen); - goto wait; - } -#if CHECK_SRVR_ADDR - if (!(_res.options & RES_INSECURE1) && - !res_isourserver(&from)) { - /* - * response from wrong server? ignore it. - * XXX - potential security hazard could - * be detected here. - */ - DprintQ((_res.options & RES_DEBUG) || - (_res.pfcode & RES_PRF_REPLY), - (stdout, ";; not our server:\n"), - ans, resplen); - goto wait; - } -#endif - if (!(_res.options & RES_INSECURE2) && - !res_queriesmatch(buf, buf + buflen, - ans, ans + anssiz)) { - /* - * response contains wrong query? ignore it. - * XXX - potential security hazard could - * be detected here. - */ - DprintQ((_res.options & RES_DEBUG) || - (_res.pfcode & RES_PRF_REPLY), - (stdout, ";; wrong query name:\n"), - ans, resplen); - goto wait; - } - if (anhp->rcode == SERVFAIL || - anhp->rcode == NOTIMP || - anhp->rcode == REFUSED) { - DprintQ(_res.options & RES_DEBUG, - (stdout, "server rejected query:\n"), - ans, resplen); - badns |= (1 << ns); - _res_close(); - /* don't retry if called from dig */ - if (!_res.pfcode) - goto next_ns; - } - if (!(_res.options & RES_IGNTC) && anhp->tc) { - /* - * get rest of answer; - * use TCP with same server. - */ - Dprint(_res.options & RES_DEBUG, - (stdout, ";; truncated answer\n")); - v_circuit = 1; - _res_close(); - goto same_ns; - } - } /*if vc/dg*/ - Dprint((_res.options & RES_DEBUG) || - ((_res.pfcode & RES_PRF_REPLY) && - (_res.pfcode & RES_PRF_HEAD1)), - (stdout, ";; got answer:\n")); - DprintQ((_res.options & RES_DEBUG) || - (_res.pfcode & RES_PRF_REPLY), - (stdout, ""), - ans, resplen); - /* - * If using virtual circuits, we assume that the first server - * is preferred over the rest (i.e. it is on the local - * machine) and only keep that one open. - * If we have temporarily opened a virtual circuit, - * or if we haven't been asked to keep a socket open, - * close the socket. - */ - if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || - !(_res.options & RES_STAYOPEN)) { - _res_close(); - } - if (Rhook) { - int done = 0, loops = 0; - - do { - res_sendhookact act; - - act = (*Rhook)(nsap, buf, buflen, - ans, anssiz, &resplen); - switch (act) { - case res_goahead: - case res_done: - done = 1; - break; - case res_nextns: - _res_close(); - goto next_ns; - case res_modified: - /* give the hook another try */ - if (++loops < 42) /*doug adams*/ - break; - /*FALLTHROUGH*/ - case res_error: - /*FALLTHROUGH*/ - default: - return (-1); - } - } while (!done); - - } - return (resplen); - next_ns: ; - } /*foreach ns*/ - } /*foreach retry*/ - _res_close(); - if (!v_circuit) - if (!gotsomewhere) - errno = ECONNREFUSED; /* no nameservers found */ - else - errno = ETIMEDOUT; /* no answer obtained */ - else - errno = terrno; - return (-1); -} - -/* - * This routine is for closing the socket if a virtual circuit is used and - * the program wants to close it. This provides support for endhostent() - * which expects to close the socket. - * - * This routine is not expected to be user visible. - */ -void -_res_close(void) -{ - if (s >= 0) { - (void) close(s); - s = -1; - connected = 0; - vc = 0; - } -} diff --git a/lib/libc/net/resolver.3 b/lib/libc/net/resolver.3 deleted file mode 100644 index 4014c72..0000000 --- a/lib/libc/net/resolver.3 +++ /dev/null @@ -1,323 +0,0 @@ -.\" Copyright (c) 1985, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 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 -.\" 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 -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" 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. -.\" -.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93 -.\" -.Dd June 4, 1993 -.Dt RESOLVER 3 -.Os BSD 4.3 -.Sh NAME -.Nm res_query , -.Nm res_search , -.Nm res_mkquery , -.Nm res_send , -.Nm res_init , -.Nm dn_comp , -.Nm dn_expand -.Nd resolver routines -.Sh SYNOPSIS -.Fd #include <sys/types.h> -.Fd #include <netinet/in.h> -.Fd #include <arpa/nameser.h> -.Fd #include <resolv.h> -.Fo res_query -.Fa "char *dname" -.Fa "int class" -.Fa "int type" -.Fa "u_char *answer" -.Fa "int anslen" -.Fc -.Fo res_search -.Fa "char *dname" -.Fa "int class" -.Fa "int type" -.Fa "u_char *answer" -.Fa "int anslen" -.Fc -.Fo res_mkquery -.Fa "int op" -.Fa "char *dname" -.Fa "int class" -.Fa "int type" -.Fa "char *data" -.Fa "int datalen" -.Fa "struct rrec *newrr" -.Fa "char *buf" -.Fa "int buflen" -.Fc -.Fo res_send -.Fa "char *msg" -.Fa "int msglen" -.Fa "char *answer" -.Fa "int anslen" -.Fc -.Fn res_init -.Fo dn_comp -.Fa "char *exp_dn" -.Fa "char *comp_dn" -.Fa "int length" -.Fa "char **dnptrs" -.Fa "char **lastdnptr" -.Fc -.Fo dn_expand -.Fa "u_char *msg" -.Fa "u_char *eomorig" -.Fa "u_char *comp_dn" -.Fa "u_char *exp_dn" -.Fa "int length" -.Fc -.Sh DESCRIPTION -These routines are used for making, sending and interpreting -query and reply messages with Internet domain name servers. -.Pp -Global configuration and state information that is used by the -resolver routines is kept in the structure -.Em _res . -Most of the values have reasonable defaults and can be ignored. -Options -stored in -.Em _res.options -are defined in -.Pa resolv.h -and are as follows. -Options are stored as a simple bit mask containing the bitwise ``or'' -of the options enabled. -.Bl -tag -width RES_DEFNAMES -.It Dv RES_INIT -True if the initial name server address and default domain name are -initialized (i.e., -.Fn res_init -has been called). -.It Dv RES_DEBUG -Print debugging messages. -.It Dv RES_AAONLY -Accept authoritative answers only. -With this option, -.Fn res_send -should continue until it finds an authoritative answer or finds an error. -Currently this is not implemented. -.It Dv RES_USEVC -Use -.Tn TCP -connections for queries instead of -.Tn UDP -datagrams. -.It Dv RES_STAYOPEN -Used with -.Dv RES_USEVC -to keep the -.Tn TCP -connection open between -queries. -This is useful only in programs that regularly do many queries. -.Tn UDP -should be the normal mode used. -.It Dv RES_IGNTC -Unused currently (ignore truncation errors, i.e., don't retry with -.Tn TCP ) . -.It Dv RES_RECURSE -Set the recursion-desired bit in queries. -This is the default. -.Pf ( Fn res_send -does not do iterative queries and expects the name server -to handle recursion.) -.It Dv RES_DEFNAMES -If set, -.Fn res_search -will append the default domain name to single-component names -(those that do not contain a dot). -This option is enabled by default. -.It Dv RES_DNSRCH -If this option is set, -.Fn res_search -will search for host names in the current domain and in parent domains; see -.Xr hostname 7 . -This is used by the standard host lookup routine -.Xr gethostbyname 3 . -This option is enabled by default. -.El -.Pp -The -.Fn res_init -routine -reads the configuration file (if any; see -.Xr resolver 5 ) -to get the default domain name, -search list and -the Internet address of the local name server(s). -If no server is configured, the host running -the resolver is tried. -The current domain name is defined by the hostname -if not specified in the configuration file; -it can be overridden by the environment variable -.Ev LOCALDOMAIN . -Initialization normally occurs on the first call -to one of the following routines. -.Pp -The -.Fn res_query -function provides an interface to the server query mechanism. -It constructs a query, sends it to the local server, -awaits a response, and makes preliminary checks on the reply. -The query requests information of the specified -.Fa type -and -.Fa class -for the specified fully-qualified domain name -.Fa dname . -The reply message is left in the -.Fa answer -buffer with length -.Fa anslen -supplied by the caller. -.Pp -The -.Fn res_search -routine makes a query and awaits a response like -.Fn res_query , -but in addition, it implements the default and search rules -controlled by the -.Dv RES_DEFNAMES -and -.Dv RES_DNSRCH -options. -It returns the first successful reply. -.Pp -The remaining routines are lower-level routines used by -.Fn res_query . -The -.Fn res_mkquery -function -constructs a standard query message and places it in -.Fa buf . -It returns the size of the query, or \-1 if the query is -larger than -.Fa buflen . -The query type -.Fa op -is usually -.Dv QUERY , -but can be any of the query types defined in -.Aq Pa arpa/nameser.h . -The domain name for the query is given by -.Fa dname . -.Fa Newrr -is currently unused but is intended for making update messages. -.Pp -The -.Fn res_send -routine -sends a pre-formatted query and returns an answer. -It will call -.Fn res_init -if -.Dv RES_INIT -is not set, send the query to the local name server, and -handle timeouts and retries. -The length of the reply message is returned, or -\-1 if there were errors. -.Pp -The -.Fn dn_comp -function -compresses the domain name -.Fa exp_dn -and stores it in -.Fa comp_dn . -The size of the compressed name is returned or \-1 if there were errors. -The size of the array pointed to by -.Fa comp_dn -is given by -.Fa length . -The compression uses -an array of pointers -.Fa dnptrs -to previously-compressed names in the current message. -The first pointer points to -to the beginning of the message and the list ends with -.Dv NULL . -The limit to the array is specified by -.Fa lastdnptr . -A side effect of -.Fn dn_comp -is to update the list of pointers for -labels inserted into the message -as the name is compressed. -If -.Em dnptr -is -.Dv NULL, names are not compressed. -If -.Fa lastdnptr -is -.Dv NULL , -the list of labels is not updated. -.Pp -The -.Fn dn_expand -entry -expands the compressed domain name -.Fa comp_dn -to a full domain name -The compressed name is contained in a query or reply message; -.Fa msg -is a pointer to the beginning of the message. -The uncompressed name is placed in the buffer indicated by -.Fa exp_dn -which is of size -.Fa length . -The size of compressed name is returned or \-1 if there was an error. -.Sh FILES -.Bl -tag -width Pa -/etc/resolv.conf -The configuration file -see -.Xr resolver 5 . -.El -.Sh SEE ALSO -.Xr gethostbyname 3 , -.Xr named 8 , -.Xr resolver 5 , -.Xr hostname 7 , -.Pp -.%T RFC1032 , -.%T RFC1033 , -.%T RFC1034 , -.%T RFC1035 , -.%T RFC974 -.Rs -.%T "Name Server Operations Guide for BIND" -.Re -.Sh HISTORY -The -.Nm -function appeared in -.Bx 4.3 . |