From: downsj Date: Wed, 12 Mar 1997 10:41:45 +0000 (+0000) Subject: BIND 4.9.5-P1. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ad62c060b7c18b0bb5f0f5e90b3c2a358a278ae9;p=openbsd BIND 4.9.5-P1. libresolv and include are required until the new resolver gets integrated into libc. --- diff --git a/usr.sbin/named/Makefile b/usr.sbin/named/Makefile index 307e4bd4833..2fbb9297fa9 100644 --- a/usr.sbin/named/Makefile +++ b/usr.sbin/named/Makefile @@ -1,8 +1,10 @@ +# $OpenBSD: Makefile,v 1.3 1997/03/12 10:41:45 downsj Exp $ # $NetBSD: Makefile,v 1.7 1996/02/02 15:25:33 mrg Exp $ # from $Id: Makefile,v 8.1 1994/12/15 06:23:43 vixie Exp -SUBDIR= named named-xfer ndc reload restart dig nslookup host dnsquery +SUBDIR= libresolv named named-xfer ndc reload restart dig nslookup \ + host dnsquery -VER= 4.9.3-P1 +VER= 4.9.5-P1 .include diff --git a/usr.sbin/named/Makefile.inc b/usr.sbin/named/Makefile.inc index 5b8cf594e85..76888bd9318 100644 --- a/usr.sbin/named/Makefile.inc +++ b/usr.sbin/named/Makefile.inc @@ -1,3 +1,4 @@ +# $OpenBSD: Makefile.inc,v 1.3 1997/03/12 10:41:46 downsj Exp $ # $NetBSD: Makefile.inc,v 1.1 1996/02/02 15:25:35 mrg Exp $ # from: $Id: Makefile.inc,v 8.3 1995/12/31 23:28:00 vixie Exp @@ -11,4 +12,7 @@ PS= ps IOT= ABRT CONFIG?= -DUSE_OPTIONS_H -INCLUDE?= -I. -I${BIND_DIR} -I${BIND_DIR}/include +INCLUDE?= -I${.CURDIR} -I${BIND_DIR} -I${BIND_DIR}/include + +# we need to use our version of libresolv. +LIBRESOLV= ${BIND_DIR}/libresolv/${__objdir}/libresolv.a diff --git a/usr.sbin/named/conf/options.h b/usr.sbin/named/conf/options.h index c032527d5cc..9fdde960a40 100644 --- a/usr.sbin/named/conf/options.h +++ b/usr.sbin/named/conf/options.h @@ -1,9 +1,7 @@ -/* $NetBSD: options.h,v 1.1 1996/02/02 15:26:11 mrg Exp $ */ - /* options.h - specify the conditionally-compiled features * vix 28mar92 [moved out of the Makefile because they were getting too big] * - * $Id: options.h,v 8.7 1995/12/29 21:08:13 vixie Exp + * $Id: options.h,v 1.2 1997/03/12 10:41:47 downsj Exp $ */ /* @@ -77,7 +75,7 @@ * gns = Greg Shapiro of WPI */ -#define DEBUG /* enable -d flag and SIGUSR[12] support (ucb) */ +/*#define DEBUG /* enable -d flag and SIGUSR[12] support (ucb) */ /*#define ALLOW_T_UNSPEC /* enable the "unspec" RR type for old athena (ucb) */ /*#define INVQ /* enable inverse queries (nslookup) (ucb/vix) */ /*#define DSTORAGE /* debug malloc overruns using storage.o (ucb/vix) */ @@ -95,7 +93,7 @@ #define SLAVE_FORWARD /* use sensible timeouts on slave forwarders (pma) */ #define WANT_PIDFILE /* if you want the named.pid file (ucb/arc) */ #define DOTTED_SERIAL /* if you want to be able to specify dotted serial#s */ -/*#define SENSIBLE_DOTS /* if you want dotted serial#s to make numeric sense */ +#define SENSIBLE_DOTS /* if you want dotted serial#s to make numeric sense */ #define NCACHE /* negative caching (anant@isi.edu) */ /*#define VALIDATE /* validation procedure (anant@isi.edu) (BUGGY!) */ /*#define SHORT_FNAMES /* file names used in named-xfer need to be short */ @@ -109,18 +107,17 @@ #define ADDAUTH /* return NS and glue w/ authorative answers (mpa) */ #define RFC1535 /* use RFC 1535 default for "search" list (vix) */ #define GEN_AXFR /* distinct zones within each class */ -#define DATUMREFCNT /* use reference counts on datums (mpa) */ #define LAME_DELEGATION /* lame delegations (original-del,reworked-bb&del)*/ -#define LAME_LOGGING LOG_WARNING /* log lame delegations, set log level */ +#define LAME_LOGGING LOG_DEBUG /* log lame delegations, set log level */ #define GETSER_LOGGING LOG_INFO /* log errors/timeouts getting serial number */ -/*#define RETURNSOA /* good code that the world isn't ready for yet */ +#define RETURNSOA /* good code that the world might be ready for now */ #define CLEANCACHE /* useful and necessary in the face of NCACHE */ #define PURGE_ZONE /* remove all traces of a zone when reloading (mpa) */ -/*#define STATS /* keep nameserver statistics; uses more memory */ +#define STATS /* keep nameserver statistics; uses more memory */ #define RENICE /* named-xfer should run at normal priority */ /*#define XSTATS /* extended statistics, syslogged periodically (bg) */ /*#define BIND_NOTIFY /* experimental - do not enable in customer products */ -#define LOC_RR /* support for (draft) LOC record parsing (ckd) */ +#define LOC_RR /* support for LOC record parsing (ckd/vix) */ #define SORT_RESPONSE /* should we try to sort responses optimally? (vix) */ /*--------------------------------------------* @@ -152,14 +149,6 @@ # include "dmalloc.h" #endif -/* systems with killall(1M) don't need this - */ -#ifdef __sgi -# ifdef WANT_PIDFILE -# undef WANT_PIDFILE -# endif -#endif - #ifdef LAME_LOGGING # define LAME_DELEGATION #endif diff --git a/usr.sbin/named/conf/portability.h b/usr.sbin/named/conf/portability.h index 3cfc15ae4c9..64228a0d813 100644 --- a/usr.sbin/named/conf/portability.h +++ b/usr.sbin/named/conf/portability.h @@ -1,14 +1,10 @@ -/* $NetBSD: portability.h,v 1.1 1996/02/02 15:26:12 mrg Exp $ */ - /* portability.h - include or define things that aren't present on all systems * vixie@decwrl 26dec92 [new] * - * $Id: portability.h,v 8.11 1995/12/22 10:20:19 vixie Exp + * $Id: portability.h,v 1.2 1997/03/12 10:41:47 downsj Exp $ */ /* - * ++Copyright++ - * - * Copyright (c) * The Regents of the University of California. All rights reserved. * @@ -39,7 +35,9 @@ * 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 @@ -57,21 +55,38 @@ * 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-- */ -/* XXX: this file has become a hopeless morass, and will be redone someday. */ +/* + * Portions 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. + */ + +#ifndef __BIND_PORTABILITY_H +#define __BIND_PORTABILITY_H -#include -#include #include #include +#include +#include #ifndef TIME_H_INCLUDED # include # define TIME_H_INCLUDED #endif +/* (ISC = INTERACTIVE Systems Corporation in the next #ifdef, btw.) */ #ifdef ISC # ifndef _POSIX_SOURCE # define _POSIX_SOURCE @@ -104,7 +119,15 @@ # define setitimer(a,b,c) __setitimer(a,b,c) #endif -/* This is defined in the Makefile for ISC compiles. */ +/* This is for AIX 4.1.x */ +#ifdef _AIX41 +# include +# include +# include +# define vfork fork +#endif + +/* This is defined in the Makefile for INTERACTIVE compiles. */ #if defined(ISC) # define ftruncate(a,b) __ftruncate(a,b) # define USE_MEMCPY @@ -114,17 +137,23 @@ /* SCO UNIX defines only this unique symbol, apparently. */ #if defined(M_UNIX) -/* XXX - why is this POSIX_SOURCE instead of _POSIX_SOURCE? */ -# undef POSIX_SOURCE # define POSIX_SIGNALS -# define HAVE_FCHMOD 0 -# define writev(a,b,c) __writev(a,b,c) -# define ftruncate(a,b) __ftruncate(a,b) +# if !defined(_SCO_DS) +/* This section is for 3.2v4.2/ODT3.0 and maybe also for 3.2v4.1/3.2v4.0 */ +/* XXX - why is this POSIX_SOURCE instead of _POSIX_SOURCE? */ +# undef POSIX_SOURCE +# define HAVE_FCHMOD 0 +# define NEED_WRITEV +# define writev(a,b,c) __writev(a,b,c) +# define ftruncate(a,b) __ftruncate(a,b) +# endif #endif #ifdef NeXT # define NEED_PUTENV # define NEED_SETENV +# define HAVE_STDLIB_H +# define NEED_STRDUP # define inet_addr(a) __inet_addr(a) #endif @@ -135,9 +164,10 @@ #if defined(SUNOS4) # define BSD 43 +# define NEED_STRTOUL #endif -#if defined(__osf__) && defined(__alpha) +#if defined(__osf__) && defined(__alpha) && defined(BSD) && (BSD < 199103) # undef BSD # define BSD 199103 #endif @@ -150,14 +180,16 @@ # define USE_MEMCPY #endif +#if defined(apollo) +# define HAVE_STDLIB_H +#endif #if defined(SVR4) && !defined(SYSV) # define SYSV #endif #if defined(_POSIX_SOURCE) || defined(__sgi) || defined(__ultrix) || \ - defined(__hpux) || (defined(BSD) && (BSD >= 199103)) || \ - (defined(sun) && defined(SYSV)) + defined(__hpux) || (defined(BSD) && (BSD >= 199103)) || defined(sun) # define USE_POSIX #endif @@ -183,7 +215,7 @@ # define NETREAD_BROKEN #endif -#if defined(BSD) && BSD >= 199006 && !defined(i386) && !defined(RISCOS_BSD) +#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) # define HAVE_DAEMON #endif @@ -239,34 +271,43 @@ struct timezoneBSD { # define _TIMEZONE timezone #endif -#if defined(USE_POSIX) +#if defined(USE_POSIX) || defined(HAVE_STDLIB_H) # include -# include -# include +# if defined(__ultrix) +# define NEED_STRDUP +# endif #else -# define NEED_STRTOUL +# if !defined(_SCO_DS) +# define NEED_STRDUP +# define NEED_STRTOUL +# endif -# define STDIN_FILENO 0 -# define STDOUT_FILENO 1 -# define STDERR_FILENO 2 # ifndef NeXT extern char *getenv __P((char *)); # else extern char *getenv __P((const char *)); # endif -extern int errno; # if !defined(DMALLOC) && !defined(NeXT) extern char *malloc(), *realloc(), *calloc(); -# if defined(sun) -extern int free(); -# else extern void free(); -# endif # endif +#endif /*HAVE_STDLIB_H*/ + +#if defined(USE_POSIX) +# include +# include + +#else + +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 +extern int errno; + extern int getdtablesize __P((void)); # ifdef SHORT_FNAMES extern long pathconf __P((const char *path, int name)); @@ -321,13 +362,15 @@ int strcasecmp __P((const char *, const char *)); extern void syslog(); # endif extern char *ctime __P((const time_t *clock)); +# if !defined(M_UNIX) extern int close(), setitimer(), recv(), sendto(), sigsetmask(), atoi(), getpid(), fork(), read(), ioctl(), setsockopt(), socket(), bind(); +# endif #endif #if !defined(bcopy) /* some machines have their own macros for this */ -# if defined(USE_POSIX) || \ +# if (defined(USE_POSIX) && !defined(SUNOS4)) || \ (defined(__STDC__) && !defined(sun) && !defined(sequent) \ && !defined(M_UNIX)) /* use ANSI C3.159-1989 (``ANSI C'') functions if possible; @@ -366,13 +409,15 @@ extern int bcmp(); # endif #endif -#if (!defined(BSD) || (BSD < 43)) +#if (!defined(BSD) || (BSD < 43)) && !defined(__hpux) # define NEED_MKSTEMP # if !defined(__ultrix) && !defined(apollo) -# define NEED_STRCASECMP -# define NEED_MKTEMP -# if !defined(SVR4) -# define NEED_STRPBRK +# if !defined(_SCO_DS) +# define NEED_STRCASECMP +# define NEED_MKTEMP +# if !defined(SVR4) +# define NEED_STRPBRK +# endif # endif # endif #endif @@ -409,8 +454,8 @@ extern int bcmp(); #if !defined(ntohl) && !defined(htonl) && defined(BSD) && (BSD <= 43) /* if these aren't null macros in netinet/in.h, extern them here. */ -extern u_short htons(), ntohs(); -extern u_long htonl(), ntohl(); +extern u_short htons __P((u_short)), ntohs __P((u_short)); +extern u_long htonl __P((u_long)), ntohl __P((u_long)); #endif #if defined(USE_POSIX) && !defined(sun) && !defined(__sgi) \ @@ -553,6 +598,25 @@ extern u_long htonl(), ntohl(); # define HAVE_FCHMOD 1 #endif +/* + * Some systems need _res to be linked into text rather than bss. + */ +#if defined(__m88k__) +# define __BIND_RES_TEXT +#endif + +/* + * We need to know the IPv6 address family number even on IPv4-only systems. + * Note that this is NOT a protocol constant, and that if the system has its + * own AF_INET6, different from ours below, all of BIND's libraries and + * executables will need to be recompiled after the system + * has had this type added. The type number below is correct on most BSD- + * derived systems for which AF_INET6 is defined. + */ +#ifndef AF_INET6 +#define AF_INET6 24 +#endif + /* * Prototype the functions we'll be supplying. */ @@ -567,3 +631,9 @@ extern int gettimeofday __P((struct timeval *, struct _TIMEZONE *)); #if defined(SVR4) && defined(sun) extern int gethostname __P((char *, size_t)); #endif + +#ifdef NEED_STRDUP +extern char *strdup __P((const char *)); +#endif + +#endif /*__BIND_PORTABILITY_H*/ diff --git a/usr.sbin/named/dig/Makefile b/usr.sbin/named/dig/Makefile index c16b9a6dfbd..a44e6404c8b 100644 --- a/usr.sbin/named/dig/Makefile +++ b/usr.sbin/named/dig/Makefile @@ -1,14 +1,16 @@ +# $OpenBSD: Makefile,v 1.3 1997/03/12 10:41:48 downsj Exp $ # $NetBSD: Makefile,v 1.2 1996/03/31 13:55:34 mrg Exp $ # from: $Id: Makefile,v 8.1 1994/12/15 06:23:45 vixie Exp .PATH: ${.CURDIR}/../nslookup \ - ${.CURDIR}/../man \ - ${.CURDIR}/../../../lib/libc/net + ${.CURDIR}/../libresolv \ + ${.CURDIR}/../man PROG= dig -SRCS= dig.c list.c subr.c debug.c send.c gethostnamadr.c res_init.c \ - res_mkquery.c res_query.c res_send.c -CFLAGS+= -I${.CURDIR}/.. -DDEBUG +SRCS= dig.c list.c subr.c debug.c send.c base64.c gethnamaddr.c res_comp.c \ + res_debug.c res_init.c res_mkquery.c res_query.c res_send.c \ + inet_ntop.c inet_pton.c +CFLAGS+=${INCLUDE} ${CONFIG} -DDEBUG .include .include "../../Makefile.inc" diff --git a/usr.sbin/named/dig/dig.c b/usr.sbin/named/dig/dig.c index 25afd2a56fb..13e7feb713f 100644 --- a/usr.sbin/named/dig/dig.c +++ b/usr.sbin/named/dig/dig.c @@ -1,7 +1,11 @@ -/* $NetBSD: dig.c,v 1.1 1996/02/02 15:26:18 mrg Exp $ */ +/* $OpenBSD: dig.c,v 1.2 1997/03/12 10:41:48 downsj Exp $ */ #ifndef lint -static char rcsid[] = "$Id: dig.c,v 8.6 1995/12/29 21:08:13 vixie Exp "; +#if 0 +static char rcsid[] = "$From: dig.c,v 8.8 1996/05/21 07:32:40 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: dig.c,v 1.2 1997/03/12 10:41:48 downsj Exp $"; +#endif #endif /* @@ -142,8 +146,8 @@ static char rcsid[] = "$Id: dig.c,v 8.6 1995/12/29 21:08:13 vixie Exp "; *******************************************************************/ -#define VERSION 21 -#define VSTRING "2.1" +#define VERSION 22 +#define VSTRING "2.2" #include #include @@ -192,6 +196,8 @@ static void Usage(); static int SetOption(), printZone(), printRR(); static struct timeval difftv(); static void prnttime(); +static int xstrtonum(); +static void res_re_init(); /* stuff for nslookup modules */ FILE *filePtr; @@ -212,11 +218,13 @@ char *pager = NULL; ** Take arguments appearing in simple string (from file or command line) ** place in char**. */ +void stackarg(y, l) char *l; char **y; { int done=0; + while (!done) { switch (*l) { case '\t': @@ -241,6 +249,7 @@ stackarg(y, l) char myhostname[MAXHOSTNAMELEN]; +int main(argc, argv) int argc; char **argv; @@ -286,7 +295,6 @@ main(argc, argv) int envset=0, envsave=0; struct __res_state res_x, res_t; char *pp; - time_t t; res_init(); _res.pfcode = PRF_DEF; @@ -506,7 +514,7 @@ main(argc, argv) } /* while argv remains */ if (_res.pfcode & 0x80000) - printf("; pfcode: %08x, options: %08x\n", + printf("; pfcode: %08lx, options: %08lx\n", _res.pfcode, _res.options); /* @@ -627,8 +635,8 @@ main(argc, argv) myhostname, inet_ntoa(_res.nsaddr_list[i] .sin_addr)); - t = exectime.tv_sec; - printf(";; WHEN: %s", ctime(&t)); + printf(";; WHEN: %s", + ctime(&(exectime.tv_sec))); } if (!x) break; /* success */ @@ -682,8 +690,8 @@ main(argc, argv) gettimeofday(&exectime,NULL); printf(";; FROM: %s to SERVER: %s\n", myhostname, srvmsg); - t = exectime.tv_sec; - printf(";; WHEN: %s", ctime(&t)); + printf(";; WHEN: %s", + ctime(&(exectime.tv_sec))); printf(";; MSG SIZE sent: %d rcvd: %d\n", bytes_out, bytes_in); } @@ -902,6 +910,7 @@ SetOption(string) /* * Force a reinitialization when the domain is changed. */ +static void res_re_init() { static char localdomain[] = "LOCALDOMAIN"; @@ -926,7 +935,7 @@ res_re_init() /* * convert char string (decimal, octal, or hex) to integer */ -int +static int xstrtonum(p) char *p; { @@ -987,11 +996,13 @@ printZone(zone, sin) int amtToRead; int numRead; int numAnswers = 0; + int numRecords = 0; int result; int soacnt = 0; int sockFD; + int count, type, class, rlen, done, n; u_short len; - u_char *cp, *nmp; + u_char *cp; char dname[2][NAME_LEN]; char file[NAME_LEN]; static u_char *answer = NULL; @@ -1047,7 +1058,7 @@ printZone(zone, sin) } dname[0][0] = '\0'; - while (1) { + for (done = 0; !done; NULL) { u_int16_t tmp; /* @@ -1101,27 +1112,44 @@ printZone(zone, sin) error = ERR_PRINTING; break; } - + numRecords += htons(((HEADER *)answer)->ancount); numAnswers++; + + /* Header. */ cp = answer + HFIXEDSZ; - if (ntohs(((HEADER *)answer)->qdcount) > 0) - cp += dn_skipname((u_char *)cp, - (u_char *)answer + len) + QFIXEDSZ; - nmp = cp; - cp += dn_skipname((u_char *)cp, (u_char *)answer + len); - if ((_getshort((u_char*)cp) == T_SOA)) { - (void) dn_expand(answer, answer + len, nmp, - dname[soacnt], sizeof dname[0]); - if (soacnt) { - if (strcmp(dname[0], dname[1]) == 0) - break; - } else - soacnt++; + /* Question. */ + for (count = ntohs(((HEADER *)answer)->qdcount); + count > 0; + count--) + cp += dn_skipname(cp, answer + len) + QFIXEDSZ; + /* Answer. */ + for (count = ntohs(((HEADER *)answer)->ancount); + count > 0; + count--) { + n = dn_expand(answer, answer + len, cp, + dname[soacnt], sizeof dname[0]); + if (n < 0) { + error = ERR_PRINTING; + done++; + break; + } + cp += n; + GETSHORT(type, cp); + GETSHORT(class, cp); + cp += INT32SZ; /* ttl */ + GETSHORT(rlen, cp); + cp += rlen; + if (type == T_SOA && soacnt++ && + !strcasecmp(dname[0], dname[1])) { + done++; + break; + } } } - fprintf(stdout, ";; Received %d record%s.\n", - numAnswers, (numAnswers != 1) ? "s" : ""); + printf(";; Received %d answer%s (%d record%s).\n", + numAnswers, (numAnswers != 1) ? "s" : "", + numRecords, (numRecords != 1) ? "s" : ""); (void) close(sockFD); sockFD = -1; @@ -1176,20 +1204,23 @@ printRR(file, msg, eom) if (ntohs(headerPtr->ancount) == 0) { return(NO_INFO); - } else { - if (ntohs(headerPtr->qdcount) > 0) { - nameLen = dn_skipname(cp, eom); - if (nameLen < 0) - return (ERROR); - cp += nameLen + QFIXEDSZ; - } - cp = (u_char*) p_rr(cp, msg, stdout); } + for (n = ntohs(headerPtr->qdcount); n > 0; n--) { + nameLen = dn_skipname(cp, eom); + if (nameLen < 0) + return (ERROR); + cp += nameLen + QFIXEDSZ; + } +#ifdef PROTOCOLDEBUG + printf(";;; (message of %d octets has %d answers)\n", + eom - msg, ntohs(headerPtr->ancount)); +#endif + for (n = ntohs(headerPtr->ancount); n > 0; n--) + cp = (u_char*) p_rr(cp, msg, stdout); return(SUCCESS); } -static -struct timeval +static struct timeval difftv(a, b) struct timeval a, b; { @@ -1203,10 +1234,9 @@ difftv(a, b) return(diff); } -static -void +static void prnttime(t) struct timeval t; { - printf("%u msec", t.tv_sec * 1000 + (t.tv_usec / 1000)); + printf("%lu msec", (u_long)(t.tv_sec * 1000 + (t.tv_usec / 1000))); } diff --git a/usr.sbin/named/dnsquery/Makefile b/usr.sbin/named/dnsquery/Makefile index 7ad58c12460..32cac24778a 100644 --- a/usr.sbin/named/dnsquery/Makefile +++ b/usr.sbin/named/dnsquery/Makefile @@ -1,8 +1,13 @@ +# $OpenBSD: Makefile,v 1.2 1997/03/12 10:41:49 downsj Exp $ # $NetBSD: Makefile,v 1.1 1996/02/02 15:26:21 mrg Exp $ .PATH: ${.CURDIR}/../man +CFLAGS+=${INCLUDE} ${CONFIG} + PROG= dnsquery +LDADD= ${LIBRESOLV} + .include .include "../../Makefile.inc" diff --git a/usr.sbin/named/dnsquery/dnsquery.c b/usr.sbin/named/dnsquery/dnsquery.c index 93478663990..4a8e42bf0ec 100644 --- a/usr.sbin/named/dnsquery/dnsquery.c +++ b/usr.sbin/named/dnsquery/dnsquery.c @@ -1,4 +1,4 @@ -/* $NetBSD: dnsquery.c,v 1.1 1996/02/02 15:26:24 mrg Exp $ */ +/* $OpenBSD: dnsquery.c,v 1.3 1997/03/12 10:41:49 downsj Exp $ */ #include #include @@ -44,7 +44,7 @@ char *argv[]; } /* handle args */ - while ((c = getopt(argc, argv, "c:dh:n:p:r:st:u:v")) != -1) { + while ((c = getopt(argc, argv, "c:dh:n:p:r:st:u:v")) != EOF) { switch (c) { case 'r' : _res.retry = atoi(optarg); @@ -56,82 +56,32 @@ char *argv[]; case 'h' : strcpy(name, optarg); break; - case 'c' : if (!strcasecmp(optarg, "IN")) - class = C_IN; - else if (!strcasecmp(optarg, "HS")) - class = C_HS; - else if (!strcasecmp(optarg, "CHAOS")) - class = C_CHAOS; - else if (!strcasecmp(optarg, "ANY")) - class = C_ANY; + case 'c' : { + int success, proto_class; + + proto_class = sym_ston(__p_class_syms, + optarg, &success); + if (success) + class = proto_class; else { - class = T_ANY; - fprintf(stderr, "optarg=%s\n", optarg); + fprintf(stderr, "Bad class (%s)\n", optarg); + exit(-1); } + } break; - case 't' : if (!strcasecmp(optarg, "A")) - type = T_A; - else if (!strcasecmp(optarg, "NS")) - type = T_NS; - else if (!strcasecmp(optarg, "MD")) - type = T_MD; - else if (!strcasecmp(optarg, "MF")) - type = T_MF; - else if (!strcasecmp(optarg, "CNAME")) - type = T_CNAME; - else if (!strcasecmp(optarg, "SOA")) - type = T_SOA; - else if (!strcasecmp(optarg, "MB")) - type = T_MB; - else if (!strcasecmp(optarg, "MG")) - type = T_MG; - else if (!strcasecmp(optarg, "MR")) - type = T_MR; - else if (!strcasecmp(optarg, "NULL")) - type = T_NULL; - else if (!strcasecmp(optarg, "WKS")) - type = T_WKS; - else if (!strcasecmp(optarg, "PTR")) - type = T_PTR; - else if (!strcasecmp(optarg, "HINFO")) - type = T_HINFO; - else if (!strcasecmp(optarg, "MINFO")) - type = T_MINFO; - else if (!strcasecmp(optarg, "MX")) - type = T_MX; - else if (!strcasecmp(optarg, "TXT")) - type = T_TXT; - else if (!strcasecmp(optarg, "RP")) - type = T_RP; - else if (!strcasecmp(optarg, "AFSDB")) - type = T_AFSDB; - else if (!strcasecmp(optarg, "ANY")) - type = T_ANY; - else if (!strcasecmp(optarg, "X25")) - type = T_X25; - else if (!strcasecmp(optarg, "ISDN")) - type = T_ISDN; - else if (!strcasecmp(optarg, "RT")) - type = T_RT; - else if (!strcasecmp(optarg, "NSAP")) - type = T_NSAP; - else if (!strcasecmp(optarg, "SIG")) - type = T_SIG; - else if (!strcasecmp(optarg, "KEY")) - type = T_KEY; - else if (!strcasecmp(optarg, "PX")) - type = T_PX; - else if (!strcasecmp(optarg, "GPOS")) - type = T_GPOS; - else if (!strcasecmp(optarg, "AAAA")) - type = T_AAAA; - else if (!strcasecmp(optarg, "LOC")) - type = T_LOC; + case 't' : { + int success, proto_type; + + proto_type = sym_ston(__p_type_syms, + optarg, &success); + if (success) + type = proto_type; else { - fprintf(stderr, "Bad type (%s)\n", optarg); + fprintf(stderr, "Bad type (%s)\n", optarg); exit(-1); } + } break; case 'd' : debug++; @@ -189,10 +139,17 @@ char *argv[]; * set these here so they aren't set for a possible call to * gethostbyname above */ - if (debug) - _res.options |= RES_DEBUG; - if (stream) - _res.options |= RES_USEVC; + if (debug || stream) { + if (!(_res.options & RES_INIT)) + if (res_init() == -1) { + fprintf(stderr, "res_init() failed\n"); + exit(-1); + } + if (debug) + _res.options |= RES_DEBUG; + if (stream) + _res.options |= RES_USEVC; + } /* if the -n flag was used, add them to the resolver's list */ if (nameservers != 0) { diff --git a/usr.sbin/named/host/Makefile b/usr.sbin/named/host/Makefile index badbd265d5d..38167c52505 100644 --- a/usr.sbin/named/host/Makefile +++ b/usr.sbin/named/host/Makefile @@ -1,9 +1,14 @@ +# $OpenBSD: Makefile,v 1.3 1997/03/12 10:41:50 downsj Exp $ # $NetBSD: Makefile,v 1.2 1996/05/14 13:55:47 mrg Exp $ +.PATH: ${.CURDIR}/../man + PROG = host SRCS = host.c send.c vers.c -.PATH: ${.CURDIR}/../man +CFLAGS+=${INCLUDE} ${CONFIG} + +LDADD= ${LIBRESOLV} .include "../../Makefile.inc" .include diff --git a/usr.sbin/named/host/RELEASE_NOTES b/usr.sbin/named/host/RELEASE_NOTES index 095114f10ea..5c513db013c 100644 --- a/usr.sbin/named/host/RELEASE_NOTES +++ b/usr.sbin/named/host/RELEASE_NOTES @@ -1,4 +1,5 @@ - @(#)RELEASE_NOTES e07@nikhef.nl (Eric Wassenaar) 951231 +$OpenBSD: RELEASE_NOTES,v 1.2 1997/03/12 10:41:51 downsj Exp $ + @(#)RELEASE_NOTES e07@nikhef.nl (Eric Wassenaar) 961113 yymmdd Description of changes per release TODO Things that still need to be done @@ -10,6 +11,173 @@ MISC Miscellaneous reminders # Description of changes per release # ---------------------------------------------------------------------- +961113 + Portability fix. + Trying to include was a bit over-ambitious + and caused confusion on some platforms. + On certain platforms PAGESIZE is not a constant, but + hides a sysconf() call. This precludes initialization + of static variables in malloc.c + There are no functional changes in this release. + +961013 + Configurable defaults. + Make the compiled-in read timeout during stream I/O + configurable in conf.h. The default value is 60 seconds. + Make the new default _res.retry and _res.retrans values + configurable in conf.h. Note that the _res.retrans value + can be overridden with the -s command line option. + Minor fixes. + Guard against possible interrupts during I/O handling. + +961012 + Multiple answers during zone listing. + Allow multiple resource records per reply buffer packet + during zone transfers. Currently BIND puts each resource + record in a seperate reply buffer, but there are other + implementations which behave differently. Important fix. + +961010 + New resource records and query types. + Add support for T_NAPTR resource records. + Define T_EID/T_NIMLOC/T_ATMA resource record types, but + they have no support yet. + Minor fixes. + When comparing domain names in routines indomain() or + samedomain(), properly handle embedded quoted dots. + This is just a generalization. Currently these modules + are used only in those cases where embedded quoted dots + are not valid. + Miscellaneous changes. + Attempt to further reduce lint clutter. It is difficult + to eliminate this altogether. There are too many subtle + differences between various platforms. + +960929 + New resource records and query types. + Define the new IXFR type as per RFC 1995. No support + for this yet, however. + Add support for T_KEY and T_SIG resource records. + These require some new utility functions. + Recognize T_NXT and T_SRV which still have draft status. + Extra safety checks. + After a positive return from an ordinary gethostbyname + or gethostbyaddr we cannot be absolutely sure that the + size of the canonical h_name is within bounds. + Note that this is guaranteed by host's internal modules. + Minor fixes. + Be more restrictive with respect to wildcard checking. + Make sure it is really specified as the first label. + Construct reverse in-addr.arpa name without trailing dot + if we know that this is already an absolute name. + Miscellaneous changes. + Print also the input name we are going to hostalias(). + Rename a few variables for better readability. + Add various definitions that might be missing in the + default include files on some weird platforms. + Use a configurable limit for the number of recursive + chain lookups. + Some cleanup to avoid lint warnings on some platforms. + Revised manual page. + Some items needed an update. + Extend the list of related RFCs. + Several layout changes, suggested by Greg Woods. + +960921 + Extend functionality of -A option. + If the -A flag is specified along with any explicit + list mode option, it not only enables reversed address + checking, it also enables those special checks that are + normally suppressed during recursive listings, such as + checks for canonical host names and invalid underscores. + Revise -p option plus explicit server. + Consider the set of NS servers gotten from an explicit + server as authoritative if the -p option is also given. + This affects whether or not to print lame delegation + warnings in case the SOA record could not be retrieved. + Suppress lame delegation warnings in case the A records + for NS servers could not be retrieved and an explicit + server is specified. The latter was an oversight. + Indicated by Peter Koch + Improve error reporting. + After a negative return from an ordinary gethostbyname + or gethostbyaddr we don't know whether or not the answer + was authoritative. Perform an extra lookup in some few + cases where we really want to distinguish between them. + This is kludgy, and needs improvement. + Revise additional checking during RR printout. + This prevents possible recursive loops in some cases. + Requires adapting the way state information is passed + via print_info() and print_rrec(). + Make query section consistency checks. + When retrieving certain crucial information, such as + SOA or NS records, make sure the qdcount is exactly one + as it should be. + The values in the query section in a reply should match + those in the original query. This is already enforced + by the BIND 4.9 res_send(). An error is reported when a + mismatch is detected, but results are processed anyway. + Make sure response comes from a known server. + When using datagrams, compare the source address of the + response to the list of known servers. Ignore the answer + if there is a mismatch. Was missing for HOST_RES_SEND. + Minor bug fixes. + When retrieving SOA records, make sure they belong to + the requested domain. + Must properly set h_errno in some obscure circumstances. + Miscellaneous changes. + Clear the entire sockaddr_in before filling in the + relevant entries. Some platforms seem to rely on + sin_zero being actually zero. + +960808 + Conform to BIND 4.9.5 interpretation of TXT strings. + When multiple strings are encoded, they are now treated + and printed as individual quoted strings, separated by + whitespace. Formerly, they were concatenated and printed + as one single quoted string. + Note that this interpretation makes the TXT data field + multi-valued, and precludes the use of strings that are + longer than 255 characters. + +960512 + Allocate list of host data dynamically. + This avoids the MAXHOSTS static limit, and keeps the + initial BSS of the executable to a reasonable size. + Mentioned by Greg Woods + The list will be expanded in chunks as needed during + zone transfers, but will not shrink again. + Escape special characters within quoted strings. + Data fields of TXT/HINFO/UINFO records are printed as + quoted strings. Some special embedded characters should + be backslash-escaped in the output format. + Properly handle tcp packet overflow. + If the supplied answer buffer space is insufficient to + store the entire answer, res_send() is supposed to + return the length of the entire untruncated answer, not + the number of bytes that are actually available. + Increase MAXPACKET packet buffer size. + This is now set to the maximum value used internally + by the BIND named. The same value is used by dig. + Although still static, it should be sufficient. + Miscellaneous changes. + Show the length of the received answer in various debug + messages. This gives some insight in case of truncation. + +960417 + Rudimentary support for AAAA RR. + Just decode and print the ip v6 address during regular + RR type processing, in the most straightforward way. + No provisions for reverse lookups yet. + Increase MAXPACKET packet buffer size. + The traditional value 1024 for the (tcp) packet size is + no longer sufficient (see moderators.uu.net MX records). + Miscellaneous changes. + In verbose mode, show the number of bytes in the answer + if it exceeds the (udp) packet size PACKETSZ (512), or + in case the answer is truncated. Print the truncation + indication at a more appropriate position. + 951231 Cosmetic changes. Print all relevant messages in debug mode to stdout, @@ -106,7 +274,7 @@ MISC Miscellaneous reminders 950427 Fix glitch in host name lookup. New entry would be inadvertently added to the hash - lish in case the MAXHOSTS limit was reached. + list in case the MAXHOSTS limit was reached. Miscellaneous changes. Speedup comparison of zone names and host names by looking up zone names in the host name hash list. @@ -674,15 +842,21 @@ MISC Miscellaneous reminders # TODO # ---------------------------------------------------------------------- - Documentation changes. - References to BIND 4.9, not only 4.8. - Enhance reverse mapping. The new BIND 4.9.* gethostbyaddr() can be configured to return host aliases in case multiple PTR records were encountered during the reverse lookup. It is unclear what the official host name should be. Should perhaps abandon the idea of official host name. + However, the PTR records are still exempt from the new + round-robin scheduling, and are returned in the order + in which they are defined in the zone file. + + Enhance error reporting. + After a negative return from gethostbyname/gethostbyaddr + we want to know whether the answer was authoritative or + not. In a few places we are able to find out, but this + is a kludge and needs to be reimplemented. # ---------------------------------------------------------------------- # WISHLIST @@ -729,6 +903,15 @@ MISC Miscellaneous reminders to prevent gethostbyname/gethostbyaddr querying the YP/NIS. SUN will probably implement BIND 4.9.3 after its release. + Multiple answers during zone listing. + During zone transfers BIND encapsulates every resource + record in a seperate reply buffer containing a HEADER + and an answer section (ancount == 1). The authority and + additional section are empty. The query section is also + empty except in the very first reply buffer. + Some non-BIND implementations may send multiple answers + per reply buffer (ancount > 1). + # ---------------------------------------------------------------------- # MISC # ---------------------------------------------------------------------- diff --git a/usr.sbin/named/host/conf.h b/usr.sbin/named/host/conf.h index d9812ccfb9d..2c6bfef8bc5 100644 --- a/usr.sbin/named/host/conf.h +++ b/usr.sbin/named/host/conf.h @@ -1,7 +1,9 @@ +/* $OpenBSD: conf.h,v 1.2 1997/03/12 10:41:51 downsj Exp $ */ + /* ** Various configuration definitions. ** -** @(#)conf.h e07@nikhef.nl (Eric Wassenaar) 951230 +** @(#)conf.h e07@nikhef.nl (Eric Wassenaar) 961013 */ /* @@ -10,11 +12,13 @@ */ #if !defined(HOST_RES_SEND) && !defined(BIND_RES_SEND) + #if defined(BIND_49) #define BIND_RES_SEND /* use the default BIND res_send() */ #else #define HOST_RES_SEND /* use the special host res_send() */ #endif + #endif /* @@ -23,6 +27,14 @@ #define ARPA_ROOT "in-addr.arpa" +/* + * The root domain for the IP v6 reversed mapping zones as per RFC 1886. + */ + +#ifndef IPNG_ROOT +#define IPNG_ROOT "ip6.int" +#endif + /* * The root domain for the NSAP reversed mapping zones as per RFC 1637. */ @@ -37,20 +49,46 @@ #define MAXNSAP 20 /* maximum size of encoded NSAP address */ +/* + * Version number of T_LOC resource record. + */ + +#define T_LOC_VERSION 0 /* must be zero */ + +/* + * Various constants related to MD5 keys and signatures. + */ + +#define MAXMD5BITS 2552 +#define MAXMD5SIZE (2*((MAXMD5BITS+7)/8)+3) +#define MAXB64SIZE (4*((MAXMD5SIZE+2)/3)) + +/* + * The standard nameserver port. + */ + +#ifndef NAMESERVER_PORT +#define NAMESERVER_PORT 53 +#endif + /* * Miscellaneous constants. */ -#define MAXADDRS 35 /* max address count from gethostnamadr.c */ +#define MAXCHAIN 10 /* maximum count of recursive chain lookups */ +#define MAXALIAS 35 /* maximum aliases count from gethnamaddr.c */ +#define MAXADDRS 35 /* maximum address count from gethnamaddr.c */ #define MAXNSNAME 16 /* maximum count of nameservers per zone */ #define MAXIPADDR 10 /* maximum count of addresses per nameserver */ -#define MAXHOSTS 65536 /* maximum count of hostnames per zone */ /* - * Version number of T_LOC resource record. + * Default timeout values. */ -#define T_LOC_VERSION 0 /* must be zero */ +#define DEF_RETRIES 2 /* number of datagram retries per nameserver */ +#define DEF_RETRANS 5 /* timeout (seconds) between datagram retries */ +#define CONNTIMEOUT 5 /* connect timeout (value _res.retrans used) */ +#define READTIMEOUT 60 /* read timeout (seconds) during stream I/O */ /* * Prefix for messages on stdout in debug mode. diff --git a/usr.sbin/named/host/defs.h b/usr.sbin/named/host/defs.h index 8ff850b3940..8f01243b60e 100644 --- a/usr.sbin/named/host/defs.h +++ b/usr.sbin/named/host/defs.h @@ -1,14 +1,15 @@ +/* $OpenBSD: defs.h,v 1.2 1997/03/12 10:41:52 downsj Exp $ */ + /* ** Declaration of functions. ** -** @(#)defs.h e07@nikhef.nl (Eric Wassenaar) 951015 +** @(#)defs.h e07@nikhef.nl (Eric Wassenaar) 961113 */ /* ** Internal modules of the host utility ** ------------------------------------ */ - /* main.c */ int main PROTO((int, char **)); @@ -25,18 +26,16 @@ void set_logfile PROTO((char *)); void fatal PROTO((char *, ...)); void errmsg PROTO((char *, ...)); - /* info.c */ bool get_hostinfo PROTO((char *, bool)); bool get_domaininfo PROTO((char *, char *)); int get_info PROTO((querybuf *, char *, int, int)); -bool print_info PROTO((querybuf *, int, char *, int, bool)); +bool print_info PROTO((querybuf *, int, char *, int, int, bool)); void print_data PROTO((char *, ...)); -u_char *print_rrec PROTO((char *, u_char *, u_char *, u_char *, bool)); -u_char *skip_qrec PROTO((char *, u_char *, u_char *, u_char *)); -bool get_recursive PROTO((char *)); - +u_char *print_rrec PROTO((char *, int, int, u_char *, u_char *, u_char *, bool)); +u_char *skip_qrec PROTO((char *, int, int, u_char *, u_char *, u_char *)); +bool get_recursive PROTO((char **)); /* list.c */ @@ -48,8 +47,9 @@ void sort_servers PROTO((void)); bool skip_transfer PROTO((char *)); void do_check PROTO((char *)); bool do_transfer PROTO((char *)); -bool transfer_zone PROTO((char *, int, struct in_addr, char *)); -bool get_zone PROTO((char *, int, struct in_addr, char *)); +bool transfer_zone PROTO((char *, struct in_addr, char *)); +bool get_zone PROTO((char *, struct in_addr, char *)); +void update_zone PROTO((char *)); bool get_mxrec PROTO((char *)); char *get_primary PROTO((char *)); bool check_zone PROTO((char *)); @@ -64,12 +64,15 @@ int zone_index PROTO((char *, bool)); void clear_zonetab PROTO((void)); int check_canon PROTO((char *)); - /* addr.c */ bool check_addr PROTO((char *)); bool check_name PROTO((ipaddr_t)); + /* geth.c */ + +struct hostent *geth_byname PROTO((CONST char *)); +struct hostent *geth_byaddr PROTO((CONST char *, int, int)); /* util.c */ @@ -84,7 +87,7 @@ void clear_statistics PROTO((void)); void show_types PROTO((char *, int, int)); void ns_error PROTO((char *, int, int, char *)); char *decode_error PROTO((int)); -void print_status PROTO((querybuf *)); +void print_status PROTO((querybuf *, int)); void pr_error PROTO((char *, ...)); void pr_warning PROTO((char *, ...)); bool want_type PROTO((int, int)); @@ -103,22 +106,24 @@ int check_size PROTO((char *, int, u_char *, u_char *, u_char *, int)); bool valid_name PROTO((char *, bool, bool, bool)); int canonical PROTO((char *)); char *mapreverse PROTO((char *, struct in_addr)); -int compare_name PROTO((char **, char **)); - +int compare_name PROTO((const ptr_t *, const ptr_t *)); /* misc.c */ ptr_t *xalloc PROTO((ptr_t *, siz_t)); char *itoa PROTO((int)); char *utoa PROTO((int)); -char *stoa PROTO((u_char *, int)); +char *xtoa PROTO((int)); +char *stoa PROTO((u_char *, int, bool)); +char *base_ntoa PROTO((u_char *, int)); char *nsap_ntoa PROTO((u_char *, int)); +char *ipng_ntoa PROTO((u_char *)); +char *pr_date PROTO((int)); char *pr_time PROTO((int, bool)); char *pr_spherical PROTO((int, char *, char *)); char *pr_vertical PROTO((int, char *, char *)); char *pr_precision PROTO((int)); - /* send.c */ #ifdef HOST_RES_SEND @@ -133,16 +138,51 @@ void _res_perror PROTO((struct sockaddr_in *, char *, char *)); ** External library functions ** -------------------------- */ - /* extern */ +#if 0 ipaddr_t inet_addr PROTO((CONST char *)); char *inet_ntoa PROTO((struct in_addr)); char *hostalias PROTO((CONST char *)); -char *index PROTO((const char *, char)); -char *rindex PROTO((const char *, char)); +#endif + + /* avoid */ + +#if !defined(index) + +char *index PROTO((const char *, int)); +char *rindex PROTO((const char *, int)); + +#endif + + /* */ + +#if !defined(NO_STRING_H) +#include +#else + char *strcpy PROTO((char *, const char *)); +char *strncpy PROTO((char *, const char *, siz_t)); + +#endif + + /* */ + +#if defined(__STDC__) && !defined(apollo) +#include +#else + char *getenv PROTO((const char *)); ptr_t *malloc PROTO((siz_t)); ptr_t *realloc PROTO((ptr_t *, siz_t)); +free_t free PROTO((ptr_t *)); void exit PROTO((int)); +void qsort PROTO((ptr_t *, siz_t, siz_t, int (*)(const ptr_t *, const ptr_t *))); + +#endif + + /* */ + +#if defined(__STDC__) && !defined(apollo) +#include +#endif diff --git a/usr.sbin/named/host/exit.h b/usr.sbin/named/host/exit.h index 3e630b1e977..f5fc7085782 100644 --- a/usr.sbin/named/host/exit.h +++ b/usr.sbin/named/host/exit.h @@ -1,13 +1,16 @@ +/* $OpenBSD: exit.h,v 1.2 1997/03/12 10:41:52 downsj Exp $ */ + /* ** Various exit codes. ** ** They come from ** Defined here to avoid including /usr/ucbinclude on solaris 2.x ** -** @(#)exit.h e07@nikhef.nl (Eric Wassenaar) 930903 +** @(#)exit.h e07@nikhef.nl (Eric Wassenaar) 961010 */ -#define EX_OK 0 /* successful termination */ +#undef EX_OK /* defined in on SVR4 */ +#define EX_SUCCESS 0 /* successful termination */ #define EX_USAGE 64 /* command line usage error */ #define EX_DATAERR 65 /* data format error */ #define EX_NOINPUT 66 /* cannot open input */ diff --git a/usr.sbin/named/host/host.c b/usr.sbin/named/host/host.c index e928c464c1c..c5b1a4d95bc 100644 --- a/usr.sbin/named/host/host.c +++ b/usr.sbin/named/host/host.c @@ -1,3 +1,5 @@ +/* $OpenBSD: host.c,v 1.2 1997/03/12 10:41:53 downsj Exp $ */ + /* * Copyright (c) 1985, 1989 Regents of the University of California. * All rights reserved. @@ -36,7 +38,7 @@ */ #ifndef lint -static char Version[] = "@(#)host.c e07@nikhef.nl (Eric Wassenaar) 951231"; +static char Version[] = "@(#)host.c e07@nikhef.nl (Eric Wassenaar) 961013"; #endif #if defined(apollo) && defined(lint) @@ -73,6 +75,7 @@ static char Version[] = "@(#)host.c e07@nikhef.nl (Eric Wassenaar) 951231"; * - Implement new resource record types from RFC 1183 and 1348. * - Basic experimental NSAP support as defined in RFC 1637. * - Implement new resource record types from RFC 1664 and 1712. + * - Implement new resource record types from RFC 1876 and 1886. * - Code is extensively documented. */ @@ -269,10 +272,10 @@ Extended usage: [-x [name ...]] [-X server [name ...]]\ "; #include -#include #include #include #include +#include #include /* not always automatically included */ #include @@ -281,6 +284,7 @@ Extended usage: [-x [name ...]] [-X server [name ...]]\ #undef NOERROR /* in on solaris 2.x */ #include +#include #include #include "port.h" /* various portability definitions */ @@ -305,7 +309,7 @@ typedef int bool; /* boolean type */ #define T_NONE 0 /* yet unspecified resource record type */ #define T_FIRST T_A /* first possible type in resource record */ -#define T_LAST (T_AXFR - 1) /* last possible type in resource record */ +#define T_LAST (T_IXFR - 1) /* last possible type in resource record */ #ifndef NOCHANGE #define NOCHANGE 0xf /* compatibility with older BIND versions */ @@ -315,10 +319,10 @@ typedef int bool; /* boolean type */ #define BROADCAST_ADDR ((ipaddr_t)0xffffffff) #define LOCALHOST_ADDR ((ipaddr_t)0x7f000001) -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ +#if PACKETSZ > 8192 +#define MAXPACKET PACKETSZ /* PACKETSZ should be the max udp size (512) */ #else -#define MAXPACKET 1024 +#define MAXPACKET 8192 /* but tcp packets can be considerably larger */ #endif typedef union { @@ -348,7 +352,7 @@ typedef union { #endif EXTERN int errno; -EXTERN int h_errno; /* defined in gethostnamadr.c */ +EXTERN int h_errno; /* defined in the resolver library */ EXTERN res_state_t _res; /* defined in res_init.c */ extern char *dbprefix; /* prefix for debug messages (send.c) */ extern char *version; /* program version number (vers.c) */ @@ -361,19 +365,15 @@ int errorcount = 0; /* global error count */ int record_stats[T_ANY+1]; /* count of resource records per type */ char cnamebuf[MAXDNAME+1]; -char *cname = NULL; /* name to which CNAME is aliased */ - +char *cname = NULL; /* RHS name to which CNAME is aliased */ char mnamebuf[MAXDNAME+1]; -char *mname = NULL; /* name to which MR or MG is aliased */ - +char *mname = NULL; /* RHS name to which MR or MG is aliased */ char soanamebuf[MAXDNAME+1]; -char *soaname = NULL; /* domain name of SOA record */ - +char *soaname = NULL; /* LHS domain name of SOA record */ char subnamebuf[MAXDNAME+1]; -char *subname = NULL; /* domain name of NS record */ - +char *subname = NULL; /* LHS domain name of NS record */ char adrnamebuf[MAXDNAME+1]; -char *adrname = NULL; /* domain name of A record */ +char *adrname = NULL; /* LHS domain name of A record */ ipaddr_t address; /* internet address of A record */ @@ -407,6 +407,7 @@ int namelen = 0; /* select records exceeding this length */ int recursive = 0; /* recursive listmode maximum level */ int recursion_level = 0; /* current recursion level */ int skip_level = 0; /* level beyond which to skip checks */ +int print_level = 0; /* level below which to skip verbose output */ bool quiet = FALSE; /* suppress non-fatal warning messages */ bool reverse = FALSE; /* generate reverse in-addr.arpa queries */ @@ -435,14 +436,15 @@ bool classprint = FALSE; /* print class value in non-verbose mode */ #include "defs.h" /* declaration of functions */ -#define lower(c) (((c) >= 'A' && (c) <= 'Z') ? (c) + 'a' - 'A' : (c)) -#define hexdigit(n) (((n) < 10) ? '0' + (n) : 'A' + (n) - 10); - #define is_xdigit(c) (isascii(c) && isxdigit(c)) #define is_space(c) (isascii(c) && isspace(c)) #define is_alnum(c) (isascii(c) && isalnum(c)) #define is_upper(c) (isascii(c) && isupper(c)) +#define lowercase(c) (is_upper(c) ? tolower(c) : (c)) +#define lower(c) (((c) >= 'A' && (c) <= 'Z') ? (c) + 'a' - 'A' : (c)) +#define hexdigit(n) (((n) < 10) ? '0' + (n) : 'A' + (n) - 10); + #define bitset(a,b) (((a) & (b)) != 0) #define sameword(a,b) (strcasecmp(a,b) == 0) #define samepart(a,b) (strncasecmp(a,b,strlen(b)) == 0) @@ -451,15 +453,18 @@ bool classprint = FALSE; /* print class value in non-verbose mode */ #define fakename(a) (samehead(a,"localhost.") || samehead(a,"loopback.")) #define nulladdr(a) (((a) == 0) || ((a) == BROADCAST_ADDR)) #define fakeaddr(a) (nulladdr(a) || ((a) == htonl(LOCALHOST_ADDR))) -#define incopy(a) *((struct in_addr *)a) +#define incopy(a) *((struct in_addr *)(a)) +#define querysize(n) (((n) > sizeof(querybuf)) ? sizeof(querybuf) : (n)) -#define newlist(a,n,t) (t *)xalloc((ptr_t *)a, (siz_t)((n)*sizeof(t))) +#define newlist(a,n,t) (t *)xalloc((ptr_t *)(a), (siz_t)((n)*sizeof(t))) +#define newstruct(t) (t *)xalloc((ptr_t *)NULL, (siz_t)(sizeof(t))) #define newstring(s) (char *)xalloc((ptr_t *)NULL, (siz_t)(strlen(s)+1)) #define newstr(s) strcpy(newstring(s), s) -#define xfree(a) (void) free((ptr_t *)a) +#define xfree(a) (void) free((ptr_t *)(a)) #define strlength(s) (int)strlen(s) #define in_string(s,c) (index(s,c) != NULL) +#define is_quoted(a,b) (((a) > (b)) && ((a)[-1] == '\\')) #define plural(n) (((n) == 1) ? "" : "s") #define plurale(n) (((n) == 1) ? "" : "es") @@ -484,7 +489,7 @@ bool classprint = FALSE; /* print class value in non-verbose mode */ ** ----------------------------- ** ** Exits: -** EX_OK Operation successfully completed +** EX_SUCCESS Operation successfully completed ** EX_UNAVAILABLE Could not obtain requested information ** EX_CANTCREAT Could not create specified log file ** EX_NOINPUT No input arguments were found @@ -531,8 +536,8 @@ input char *argv[]; _res.options &= ~RES_DEBUG; /* turn off debug printout */ _res.options &= ~RES_USEVC; /* do not use virtual circuit */ - _res.retry = 2; /* number of retries, default = 4 */ - _res.retrans = 5; /* timeout in seconds, default = 5 or 6 */ + _res.retry = DEF_RETRIES; /* number of datagram retries */ + _res.retrans = DEF_RETRANS; /* timeout in secs between retries */ /* initialize packet id */ _res.id = getpid() & 0x7fff; @@ -578,14 +583,14 @@ input char *argv[]; { case 'w' : waitmode = TRUE; - new_res.retry = 2; - new_res.retrans = 5; + new_res.retry = DEF_RETRIES; + new_res.retrans = DEF_RETRANS; break; case 's' : if (argv[2] == NULL || argv[2][0] == '-') fatal("Missing timeout value"); - new_res.retry = 2; + new_res.retry = DEF_RETRIES; new_res.retrans = atoi(argv[2]); if (new_res.retrans <= 0) fatal("Invalid timeout value %s", argv[2]); @@ -797,7 +802,7 @@ input char *argv[]; #endif case 'V' : printf("Version %s\n", version); - exit(EX_OK); + exit(EX_SUCCESS); default: fatal(Usage); @@ -846,7 +851,7 @@ input char *argv[]; _res.options = new_res.options; /* show the new resolver database */ - if (debug > 1 || verbose > 1) + if (verbose > 1 || debug > 1) show_res(); /* show customized default domain */ @@ -943,7 +948,7 @@ input char *argv[]; /* original command line arguments */ ** ---------------------------------------------- ** ** Returns: -** EX_OK if information was obtained successfully. +** EX_SUCCESS if information was obtained successfully. ** Appropriate exit code otherwise. */ @@ -962,7 +967,7 @@ input char *argv[]; result = process_name(argv[i]); /* maintain overall result */ - if (result != EX_OK || excode == EX_NOINPUT) + if (result != EX_SUCCESS || excode == EX_NOINPUT) excode = result; } @@ -975,7 +980,7 @@ input char *argv[]; ** ------------------------------------------------- ** ** Returns: -** EX_OK if information was obtained successfully. +** EX_SUCCESS if information was obtained successfully. ** Appropriate exit code otherwise. */ @@ -1014,7 +1019,7 @@ input FILE *fp; /* input file with query names */ result = process_name(p); /* maintain overall result */ - if (result != EX_OK || excode == EX_NOINPUT) + if (result != EX_SUCCESS || excode == EX_NOINPUT) excode = result; } } @@ -1028,7 +1033,7 @@ input FILE *fp; /* input file with query names */ ** ------------------------------------------------------ ** ** Returns: -** EX_OK if information was obtained successfully. +** EX_SUCCESS if information was obtained successfully. ** Appropriate exit code otherwise. ** ** Wrapper for execute_name() to hide administrative tasks. @@ -1075,7 +1080,7 @@ input char *name; /* command line argument */ ** ------------------------------------------------------ ** ** Returns: -** EX_OK if information was obtained successfully. +** EX_SUCCESS if information was obtained successfully. ** Appropriate exit code otherwise. ** ** Outputs: @@ -1103,6 +1108,7 @@ input char *name; /* command line argument */ * The name can be an ordinary domain name, or an internet address * in dotted quad notation. If the -n option is given, the name is * supposed to be a dotted nsap address. + * Furthermore, an empty input name is treated as the root domain. */ queryname = name; if (queryname[0] == '\0') @@ -1120,16 +1126,18 @@ input char *name; /* command line argument */ if (reverse) { if (queryaddr == NOT_DOTTED_QUAD) - name = queryname, queryname = NULL; + name = NULL; else - queryname = in_addr_arpa(queryname); + name = in_addr_arpa(queryname); - if (queryname == NULL) + if (name == NULL) { - errmsg("Invalid dotted quad %s", name); + errmsg("Invalid dotted quad %s", queryname); return(EX_USAGE); } + /* redefine appropriately */ + queryname = name; queryaddr = NOT_DOTTED_QUAD; } @@ -1140,17 +1148,21 @@ input char *name; /* command line argument */ if (revnsap) { if (reverse) - name = queryname, queryname = NULL; + name = NULL; else - queryname = nsap_int(queryname); + name = nsap_int(queryname); - if (queryname == NULL) + if (name == NULL) { - errmsg("Invalid nsap address %s", name); + errmsg("Invalid nsap address %s", queryname); return(EX_USAGE); } + /* redefine appropriately */ + queryname = name; queryaddr = NOT_DOTTED_QUAD; + + /* this is also a reversed mapping domain */ reverse = TRUE; } @@ -1193,7 +1205,7 @@ input char *name; /* command line argument */ * All set. Perform requested function. */ result = execute(queryname, queryaddr); - return(result ? EX_OK : EX_UNAVAILABLE); + return(result ? EX_SUCCESS : EX_UNAVAILABLE); } /* @@ -1291,7 +1303,7 @@ input ipaddr_t addr; /* explicit address of query */ { newname = strcpy(newnamebuf, cname); - if (++ncnames > 5) + if (ncnames++ > MAXCHAIN) { errmsg("Possible CNAME loop"); return(FALSE); @@ -1304,7 +1316,7 @@ input ipaddr_t addr; /* explicit address of query */ } else { - hp = gethostbyaddr((char *)&inaddr, INADDRSZ, AF_INET); + hp = geth_byaddr((char *)&inaddr, INADDRSZ, AF_INET); if (hp != NULL) { print_host("Name", hp); @@ -1362,7 +1374,8 @@ myhostname() } /* cache the result */ - myname = strcpy(mynamebuf, hp->h_name); + myname = strncpy(mynamebuf, hp->h_name, MAXDNAME); + myname[MAXDNAME] = '\0'; } return(myname); @@ -1447,13 +1460,16 @@ input char *name; /* name of server to be queried */ */ if (hp != NULL) { - server = strcpy(serverbuf, hp->h_name); + server = strncpy(serverbuf, hp->h_name, MAXDNAME); + server[MAXDNAME] = '\0'; + if (verbose) print_host("Server", hp); } else { server = strcpy(serverbuf, inet_ntoa(inaddr)); + if (verbose) printf("Server: %s\n\n", server); } @@ -1578,6 +1594,7 @@ input bool qualified; /* assume fully qualified if set */ { register char **domain; register char *cp; + const char *hp; int dot; /* number of dots in query name */ bool result; /* result status of action taken */ char oldnamebuf[2*MAXDNAME+2]; @@ -1611,12 +1628,12 @@ input bool qualified; /* assume fully qualified if set */ * Check for aliases of single name. * Note that the alias is supposed to be fully qualified. */ - if (dot == 0 && (cp = hostalias(name)) != NULL) + if (dot == 0 && (hp = hostalias(name)) != NULL) { if (verbose) - printf("Aliased to \"%s\"\n", cp); + printf("Aliased %s to %s\n", name, hp); - result = get_domaininfo(cp, (char *)NULL); + result = get_domaininfo(hp, (char *)NULL); return(result); } @@ -1784,7 +1801,7 @@ input char *domain; /* domain to which name is relative */ * If we got a positive answer, the data may still be corrupted. */ if (result) - result = print_info(&answer, n, name, querytype, FALSE); + result = print_info(&answer, n, name, querytype, queryclass, TRUE); /* * Remember the actual name that was queried. @@ -1860,8 +1877,8 @@ input int class; /* specific resource record class */ /* * Analyze the status of the answer from the nameserver. */ - if (debug || verbose) - print_status(answerbuf); + if ((verbose > print_level) || debug) + print_status(answerbuf, n); bp = (HEADER *)answerbuf; ancount = ntohs(bp->ancount); @@ -1895,8 +1912,9 @@ input int class; /* specific resource record class */ return(-1); } + /* valid answer received, avoid buffer overrun */ h_errno = 0; - return(n); + return(querysize(n)); } /* @@ -1913,12 +1931,13 @@ input int class; /* specific resource record class */ */ bool -print_info(answerbuf, answerlen, name, type, listing) +print_info(answerbuf, answerlen, name, type, class, regular) input querybuf *answerbuf; /* location of answer buffer */ input int answerlen; /* length of answer buffer */ input char *name; /* full name we are querying about */ input int type; /* record type we are querying about */ -input bool listing; /* set if this is a zone listing */ +input int class; /* record class we are querying about */ +input bool regular; /* set if this is a regular lookup */ { HEADER *bp; int qdcount, ancount, nscount, arcount; @@ -1940,10 +1959,9 @@ input bool listing; /* set if this is a zone listing */ */ if (qdcount) { - while (qdcount > 0 && cp < eom) + while (qdcount > 0 && cp < eom) /* process all records */ { - /* cp += dn_skipname(cp, eom) + QFIXEDSZ; */ - cp = skip_qrec(name, cp, msg, eom); + cp = skip_qrec(name, type, class, cp, msg, eom); if (cp == NULL) return(FALSE); qdcount--; @@ -1964,38 +1982,32 @@ input bool listing; /* set if this is a zone listing */ */ if (ancount) { - if (!listing && verbose && !bp->aa) + if ((type != T_AXFR) && verbose && !bp->aa) printf("The following answer is not authoritative:\n"); while (ancount > 0 && cp < eom) { - cp = print_rrec(name, cp, msg, eom, listing); + /* reset for each record during zone listings */ + soaname = NULL, subname = NULL, adrname = NULL, address = 0; + + print_level++; + cp = print_rrec(name, type, class, cp, msg, eom, regular); + print_level--; if (cp == NULL) return(FALSE); ancount--; - /* - * When we ask for address and there is a CNAME, it returns - * both the CNAME and the address. Since we trace down the - * CNAME chain ourselves, we don't really want to print the - * address at this point. - */ - if (!listmode && !verbose && cname) - return(TRUE); - - /* - * Recursively expand MR or MG records into MB records. - */ - if (!listmode && mailmode && mname) - { - char newnamebuf[MAXDNAME+1]; - char *newname; + /* update zone information during zone listings */ + if (type == T_AXFR) + update_zone(name); - newname = strcpy(newnamebuf, mname); - mname = NULL; + /* we trace down CNAME chains ourselves */ + if (regular && !verbose && cname) + return(TRUE); - (void) get_recursive(newname); - } + /* recursively expand MR/MG records into MB records */ + if (regular && mailmode && mname) + (void) get_recursive(&mname); } if (ancount) @@ -2020,7 +2032,9 @@ input bool listing; /* set if this is a zone listing */ while (nscount > 0 && cp < eom) { - cp = print_rrec(name, cp, msg, eom, FALSE); + print_level++; + cp = print_rrec(name, type, class, cp, msg, eom, FALSE); + print_level--; if (cp == NULL) return(FALSE); nscount--; @@ -2041,7 +2055,9 @@ input bool listing; /* set if this is a zone listing */ while (arcount > 0 && cp < eom) { - cp = print_rrec(name, cp, msg, eom, FALSE); + print_level++; + cp = print_rrec(name, type, class, cp, msg, eom, FALSE); + print_level--; if (cp == NULL) return(FALSE); arcount--; @@ -2056,6 +2072,7 @@ input bool listing; /* set if this is a zone listing */ } } + /* all sections were processed successfully */ return(TRUE); } @@ -2124,23 +2141,26 @@ input char *a, *b, *c, *d; /* optional arguments */ #define pr_name(x) pr_domain(x, listing) /* check the LHS record name of these records for invalid characters */ -#define test_valid(t) ((t == T_A && !reverse) || t == T_MX || t == T_AAAA) +#define test_valid(t) (((t == T_A) && !reverse) || t == T_MX || t == T_AAAA) /* check the RHS domain name of these records for canonical host names */ #define test_canon(t) (t == T_NS || t == T_MX) u_char * -print_rrec(name, cp, msg, eom, listing) +print_rrec(name, qtype, qclass, cp, msg, eom, regular) input char *name; /* full name we are querying about */ +input int qtype; /* record type we are querying about */ +input int qclass; /* record class we are querying about */ register u_char *cp; /* current position in answer buf */ input u_char *msg, *eom; /* begin and end of answer buf */ -input bool listing; /* set if this is a zone listing */ +input bool regular; /* set if this is a regular lookup */ { char rname[MAXDNAME+1]; /* record name in LHS */ char dname[MAXDNAME+1]; /* domain name in RHS */ int type, class, ttl, dlen; /* fixed values in every record */ u_char *eor; /* predicted position of next record */ bool classmatch; /* set if we want to see this class */ + bool listing; /* set if this is a zone listing */ char *host = listhost; /* contacted host for zone listings */ register int n, c; struct in_addr inaddr; @@ -2176,6 +2196,8 @@ input bool listing; /* set if this is a zone listing */ /* * Decide whether or not to print this resource record. */ + listing = (qtype == T_AXFR || qtype == T_IXFR) ? TRUE : FALSE; + if (listing) { classmatch = want_class(class, queryclass); @@ -2187,10 +2209,6 @@ input bool listing; /* set if this is a zone listing */ doprint = classmatch && want_type(type, T_ANY); } -#ifdef obsolete - if (doprint && exclusive && !samedomain(rname, name, TRUE)) - doprint = FALSE; -#endif if (doprint && exclusive && !indomain(rname, name, TRUE)) doprint = FALSE; @@ -2212,7 +2230,7 @@ input bool listing; /* set if this is a zone listing */ if (verbose || ttlprint) doprintf(("\t%s", itoa(ttl))) - if (verbose || classprint || (class != queryclass)) + if (verbose || classprint || (class != qclass)) doprintf(("\t%s", pr_class(class))) doprintf(("\t%s", pr_type(type))) @@ -2257,7 +2275,7 @@ input bool listing; /* set if this is a zone listing */ cp += INADDRSZ; break; } - +#ifdef obsolete if (dlen == INADDRSZ + 1 + INT16SZ) { bcopy((char *)cp, (char *)&inaddr, INADDRSZ); @@ -2273,11 +2291,10 @@ input bool listing; /* set if this is a zone listing */ cp += INT16SZ; break; } - +#endif address = 0; break; } - address = 0; cp += dlen; break; @@ -2310,13 +2327,13 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t\"%s\"", stoa(cp, n))) + doprintf(("\t\"%s\"", stoa(cp, n, TRUE))) cp += n; if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t\"%s\"", stoa(cp, n))) + doprintf(("\t\"%s\"", stoa(cp, n, TRUE))) cp += n; break; @@ -2376,6 +2393,7 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; + protocol = getprotobynumber(n); if (protocol != NULL) doprintf((" %s", protocol->p_name)) @@ -2412,9 +2430,9 @@ input bool listing; /* set if this is a zone listing */ #ifdef obsolete case T_TXT: - if (dlen > 0) + /* if (dlen > 0) */ { - doprintf(("\t\"%s\"", stoa(cp, dlen))) + doprintf(("\t\"%s\"", stoa(cp, dlen, TRUE))) cp += dlen; } break; @@ -2424,7 +2442,7 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t\"%s", stoa(cp, n))) + doprintf(("\t\"%s\"", stoa(cp, n, TRUE))) cp += n; while (cp < eor) @@ -2432,10 +2450,9 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("%s", stoa(cp, n))) + doprintf((" \"%s\"", stoa(cp, n, TRUE))) cp += n; } - doprintf(("\"")) break; case T_MINFO: @@ -2475,7 +2492,7 @@ input bool listing; /* set if this is a zone listing */ break; case T_UINFO: - doprintf(("\t\"%s\"", stoa(cp, dlen))) + doprintf(("\t\"%s\"", stoa(cp, dlen, TRUE))) cp += dlen; break; @@ -2525,7 +2542,7 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t%s", stoa(cp, n))) + doprintf(("\t%s", stoa(cp, n, FALSE))) cp += n; break; @@ -2533,7 +2550,7 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t%s", stoa(cp, n))) + doprintf(("\t%s", stoa(cp, n, FALSE))) cp += n; if (cp < eor) @@ -2541,7 +2558,7 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf((" %s", stoa(cp, n))) + doprintf((" %s", stoa(cp, n, FALSE))) cp += n; } break; @@ -2583,19 +2600,19 @@ input bool listing; /* set if this is a zone listing */ if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t%s", stoa(cp, n))) + doprintf(("\t%s", stoa(cp, n, FALSE))) cp += n; if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t%s", stoa(cp, n))) + doprintf(("\t%s", stoa(cp, n, FALSE))) cp += n; if (check_size(rname, type, cp, msg, eor, 1) < 0) break; n = *cp++; - doprintf(("\t%s", stoa(cp, n))) + doprintf(("\t%s", stoa(cp, n, FALSE))) cp += n; break; @@ -2636,20 +2653,236 @@ input bool listing; /* set if this is a zone listing */ cp += dlen; break; + case T_AAAA: + if (dlen == IPNGSIZE) + { + doprintf(("\t%s", ipng_ntoa(cp))) + cp += IPNGSIZE; + } + break; + case T_SIG: + if (check_size(rname, type, cp, msg, eor, INT16SZ) < 0) + break; + n = _getshort(cp); + doprintf(("\t%s", pr_type(n))) + cp += INT16SZ; + + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf((" %s", itoa(n))) + + n = 1 + 3*INT32SZ + INT16SZ; + if (check_size(rname, type, cp, msg, eor, n) < 0) + break; + doprintf((" (")) + + n = *cp++; + doprintf(("\n\t\t\t; %s", itoa(n))) + doprintf(("\t\t;labels")) + + n = _getlong(cp); + doprintf(("\n\t\t\t%s", itoa(n))) + doprintf(("\t\t;original ttl")) + cp += INT32SZ; + + n = _getlong(cp); + doprintf(("\n\t\t\t%s", pr_date(n))) + doprintf(("\t;signature expiration")) + cp += INT32SZ; + + n = _getlong(cp); + doprintf(("\n\t\t\t%s", pr_date(n))) + doprintf(("\t;signature signed time")) + cp += INT32SZ; + + n = _getshort(cp); + doprintf(("\n\t\t\t%s", itoa(n))) + doprintf(("\t\t;key footprint")) + cp += INT16SZ; + + n = expand_name(rname, type, cp, msg, eom, dname); + if (n < 0) + break; + doprintf(("\n\t\t\t%s", pr_name(dname))) + cp += n; + + if (cp < eor) + { + register char *buf; + register int size; + + n = eor - cp; + buf = base_ntoa(cp, n); + size = strlength(buf); + cp += n; + + while ((n = (size > 64) ? 64 : size) > 0) + { + doprintf(("\n\t%s", stoa((u_char *)buf, n, FALSE))) + buf += n; size -= n; + } + } + + doprintf(("\n\t\t\t)")) + break; + case T_KEY: - case T_AAAA: - doprintf(("\t(not yet implemented)")) + if (check_size(rname, type, cp, msg, eor, INT16SZ) < 0) + break; + n = _getshort(cp); + doprintf(("\t0x%s", xtoa(n))) + cp += INT16SZ; + + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf((" %s", itoa(n))) + + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf((" %s", itoa(n))) + + if (cp < eor) + { + register char *buf; + register int size; + + n = eor - cp; + buf = base_ntoa(cp, n); + size = strlength(buf); + cp += n; + + doprintf((" (")) + while ((n = (size > 64) ? 64 : size) > 0) + { + doprintf(("\n\t%s", stoa((u_char *)buf, n, FALSE))) + buf += n; size -= n; + } + doprintf(("\n\t\t\t)")) + } + break; + + case T_NXT: + n = expand_name(rname, type, cp, msg, eom, dname); + if (n < 0) + break; + doprintf(("\t%s", pr_name(dname))) + cp += n; + + n = 0; + while (cp < eor) + { + c = *cp++; + do + { + if (c & 0200) + { + doprintf((" %s", pr_type(n))) + } + c <<= 1; + } while (++n & 07); + } + break; + + case T_SRV: + if (check_size(rname, type, cp, msg, eor, INT16SZ) < 0) + break; + n = _getshort(cp); + doprintf(("\t%s", itoa(n))) + cp += INT16SZ; + + if (check_size(rname, type, cp, msg, eor, INT16SZ) < 0) + break; + n = _getshort(cp); + doprintf((" %s", itoa(n))) + cp += INT16SZ; + + if (check_size(rname, type, cp, msg, eor, INT16SZ) < 0) + break; + n = _getshort(cp); + doprintf((" %s", itoa(n))) + cp += INT16SZ; + + n = expand_name(rname, type, cp, msg, eom, dname); + if (n < 0) + break; + doprintf((" %s", pr_name(dname))) + cp += n; + break; + + case T_EID: + case T_NIMLOC: + case T_ATMA: + doprintf(("\t\"not yet implemented\"")) cp += dlen; break; + case T_NAPTR: + if (check_size(rname, type, cp, msg, eor, INT16SZ) < 0) + break; + n = _getshort(cp); + doprintf(("\t%s", itoa(n))) + cp += INT16SZ; + + if (check_size(rname, type, cp, msg, eor, INT16SZ) < 0) + break; + n = _getshort(cp); + doprintf((" %s", itoa(n))) + cp += INT16SZ; + + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf((" \"%s\"", stoa(cp, n, TRUE))) + cp += n; + + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf((" \"%s\"", stoa(cp, n, TRUE))) + cp += n; + + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf((" \"%s\"", stoa(cp, n, TRUE))) + cp += n; + + n = expand_name(rname, type, cp, msg, eom, dname); + if (n < 0) + break; + doprintf((" %s", pr_name(dname))) + cp += n; + break; +#ifdef notyet + case T_TSIG: + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf(("\t\"%s\"", stoa(cp, n, TRUE))) + cp += n; + + while (cp < eor) + { + if (check_size(rname, type, cp, msg, eor, 1) < 0) + break; + n = *cp++; + doprintf((" \"%s\"", stoa(cp, n, TRUE))) + cp += n; + } + break; +#endif default: - doprintf(("\t???")) + doprintf(("\t\"???\"")) cp += dlen; break; } /* + * End of specific data type processing. * Terminate resource record printout. */ doprintf(("\n")) @@ -2673,7 +2906,7 @@ input bool listing; /* set if this is a zone listing */ * Save the MR or MG alias for MB chain tracing. * These features can be enabled only in normal mode. */ - if (!listmode && classmatch) + if (regular && classmatch) { if (type == T_CNAME) cname = strcpy(cnamebuf, dname); @@ -2723,7 +2956,7 @@ input bool listing; /* set if this is a zone listing */ * i.e. it should exist and have an A record and not be a CNAME. * Currently this test is suppressed during deep recursive zone listings. */ - if (!recurskip && test_canon(type) && (n = check_canon(dname)) != 0) + if (!recurskip && test_canon(type) && ((n = check_canon(dname)) != 0)) { /* only report definitive target host failures */ if (n == HOST_NOT_FOUND) @@ -2750,7 +2983,7 @@ input bool listing; /* set if this is a zone listing */ * it is registered and maps back to the name of the A record. * Currently this option has effect here only during zone listings. */ - if (addrmode && (type == T_A && !reverse) && !fakeaddr(address)) + if (addrmode && ((type == T_A) && !reverse) && !fakeaddr(address)) { host = mapreverse(rname, inaddr); if (host == NULL) @@ -2777,8 +3010,10 @@ input bool listing; /* set if this is a zone listing */ */ u_char * -skip_qrec(name, cp, msg, eom) +skip_qrec(name, qtype, qclass, cp, msg, eom) input char *name; /* full name we are querying about */ +input int qtype; /* record type we are querying about */ +input int qclass; /* record class we are querying about */ register u_char *cp; /* current position in answer buf */ input u_char *msg, *eom; /* begin and end of answer buf */ { @@ -2786,6 +3021,9 @@ input u_char *msg, *eom; /* begin and end of answer buf */ int type, class; /* fixed values in query record */ register int n; +/* + * Pickup the standard values present in the query section. + */ n = expand_name(name, T_NONE, cp, msg, eom, rname); if (n < 0) return(NULL); @@ -2806,6 +3044,24 @@ input u_char *msg, *eom; /* begin and end of answer buf */ printf("%-20s\t%s\t%s\n", rname, pr_class(class), pr_type(type)); #endif + +/* + * The values in the answer should match those in the query. + * If there is a mismatch, we just signal an error, but don't abort. + * For regular queries there is exactly one record in the query section. + */ + if (!sameword(rname, name)) + pr_error("invalid answer name %s after %s query for %s", + rname, pr_type(qtype), name); + + if (type != qtype) + pr_error("invalid answer type %s after %s query for %s", + pr_type(type), pr_type(qtype), name); + + if (class != qclass) + pr_error("invalid answer class %s after %s query for %s", + pr_class(class), pr_type(qtype), name); + return(cp); } @@ -2820,24 +3076,30 @@ input u_char *msg, *eom; /* begin and end of answer buf */ bool get_recursive(name) -input char *name; /* name to query about */ +input char **name; /* name to query about */ { static int level = 0; /* recursion level */ + char newnamebuf[MAXDNAME+1]; + char *newname; /* new name to look up */ bool result; /* result status of action taken */ int save_errno; int save_herrno; - if (level > 5) + if (level > MAXCHAIN) { errmsg("Recursion too deep"); return(FALSE); } + /* save local copy, and reset indicator */ + newname = strcpy(newnamebuf, *name); + *name = NULL; + save_errno = errno; save_herrno = h_errno; level++; - result = get_hostinfo(name, TRUE); + result = get_hostinfo(newname, TRUE); level--; errno = save_errno; @@ -2861,9 +3123,9 @@ int nservers = 0; /* count of nameservers */ #ifdef notyet typedef struct srvr_data { - char nsname[MAXDNAME+1]; /* nameserver host name */ - struct in_addr ipaddr[MAXIPADDR]; /* nameserver addresses */ - int naddrs; /* count of addresses */ + char sd_nsname[MAXDNAME+1]; /* nameserver host name */ + struct in_addr sd_ipaddr[MAXIPADDR]; /* nameserver addresses */ + int sd_naddrs; /* count of addresses */ } srvr_data_t; srvr_data_t nsinfo[MAXNSNAME]; /* nameserver info */ @@ -2879,27 +3141,34 @@ bool lameserver; /* server could not provide SOA service */ * that do not belong to the zone are not stored. Glue records that belong * to a delegated zone will be filtered out later during the host count scan. * The host names are allocated dynamically. -#ifdef notyet - * The host data should have been allocated dynamically to avoid static - * limits, but this is less important since it is not saved across calls. - * In case the static limit is reached, increase MAXHOSTS and recompile. -#endif + * The list itself is also allocated dynamically, to avoid static limits, + * and to keep the initial bss of the executable to a reasonable size. + * Allocation is done in chunks, to reduce considerable malloc overhead. + * Note that the list will not shrink during recursive processing. */ +#ifdef obsolete char *hostname[MAXHOSTS]; /* host name of host in zone */ ipaddr_t hostaddr[MAXHOSTS]; /* first host address */ bool multaddr[MAXHOSTS]; /* set if this is a multiple address host */ -int hostcount = 0; /* count of hosts in zone */ +#endif -#ifdef notyet typedef struct host_data { - char *hostname; /* host name of host in zone */ - ipaddr_t hostaddr; /* first host address */ - bool multaddr; /* set if this is a multiple address host */ + char *hd_hostname; /* host name of host in zone */ + ipaddr_t hd_hostaddr; /* first host address */ + bool hd_multaddr; /* set if this is a multiple address host */ } host_data_t; -host_data_t hostlist[MAXHOSTS]; /* info on hosts in zone */ -#endif +host_data_t *hostlist = NULL; /* info on hosts in zone */ +int hostcount = 0; /* count of hosts in zone */ + +int maxhosts = 0; /* number of allocated hostlist entries */ + +#define MAXHOSTINCR 4096 /* chunk size to increment hostlist */ + +#define hostname(i) hostlist[i].hd_hostname +#define hostaddr(i) hostlist[i].hd_hostaddr +#define multaddr(i) hostlist[i].hd_multaddr /* * Delegated zone information. @@ -2930,6 +3199,8 @@ int addrcount = 0; /* count of global addresses */ soa_data_t soa; /* buffer to store soa data */ +int soacount = 0; /* count of SOA records during listing */ + /* * Nameserver preference. * As per BIND 4.9.* resource records may be returned after round-robin @@ -2994,7 +3265,7 @@ input char *name; /* name of zone to process */ * Suppress various checks if working beyond the recursion skip level. * This affects processing in print_rrec(). It may need refinement. */ - recurskip = (recursion_level > skip_level) ? TRUE : FALSE; + recurskip = ((recursion_level > skip_level) && !addrmode) ? TRUE : FALSE; /* * Find the nameservers for the given zone. @@ -3024,7 +3295,7 @@ input char *name; /* name of zone to process */ * Without an explicit server on the command line, the servers we * have looked up are supposed to be authoritative for the zone. */ - authserver = server ? FALSE : TRUE; + authserver = (server && !primary) ? FALSE : TRUE; /* * Check SOA records at each of the nameservers if so requested. @@ -3080,21 +3351,21 @@ input char *name; /* name of zone to process */ for (n = i; n < hostcount; n++) { /* skip fake hosts using a very rudimentary test */ - if (fakename(hostname[n]) || fakeaddr(hostaddr[n])) + if (fakename(hostname(n)) || fakeaddr(hostaddr(n))) continue; #ifdef justfun /* save longest host name encountered so far */ - if (verbose && ((i = strlength(hostname[n])) > longsize)) + if (verbose && ((i = strlength(hostname(n))) > longsize)) { longsize = i; - (void) strcpy(longname, hostname[n]); + (void) strcpy(longname, hostname(n)); } #endif /* skip apparent glue records */ - if (gluerecord(hostname[n], name, zonename, nzones)) + if (gluerecord(hostname(n), name, zonename, nzones)) { if (verbose > 1) - printf("%s is glue record\n", hostname[n]); + printf("%s is glue record\n", hostname(n)); continue; } @@ -3104,37 +3375,37 @@ input char *name; /* name of zone to process */ /* * Mark hosts not residing directly in the zone as extrazone host. */ - if (!samedomain(hostname[n], name, TRUE)) + if (!samedomain(hostname(n), name, TRUE)) { nextrs++; if (extrmode || (verbose > 1)) - printf("%s is extrazone host\n", hostname[n]); + printf("%s is extrazone host\n", hostname(n)); } /* * Mark hosts with more than one address as gateway host. * These are not checked for duplicate addresses. */ - if (multaddr[n]) + if (multaddr(n)) { ngates++; if (gatemode || (verbose > 1)) - printf("%s is gateway host\n", hostname[n]); + printf("%s is gateway host\n", hostname(n)); } /* * Compare single address hosts against global list of addresses. * Multiple address hosts are too complicated to handle this way. */ - else if (check_dupl(hostaddr[n])) + else if (check_dupl(hostaddr(n))) { struct in_addr inaddr; - inaddr.s_addr = hostaddr[n]; + inaddr.s_addr = hostaddr(n); ndupls++; if (duplmode || (verbose > 1)) printf("%s is duplicate host with address %s\n", - hostname[n], inet_ntoa(inaddr)); + hostname(n), inet_ntoa(inaddr)); } } @@ -3174,13 +3445,13 @@ input char *name; /* name of zone to process */ * Note that this precludes further use of the zone_index() function. */ if ((nzones > 1) && (recursive || listzones || mxdomains)) - qsort((char *)zonename, nzones, sizeof(char *), compare_name); + qsort((ptr_t *)zonename, nzones, sizeof(char *), compare_name); /* * The names of the hosts were allocated dynamically. */ for (n = 0; n < hostcount; n++) - xfree(hostname[n]); + xfree(hostname(n)); /* * Check for mailable delegated zones within this zone. @@ -3331,8 +3602,7 @@ find_servers(name) input char *name; /* name of zone to find servers for */ { struct hostent *hp; - register int n; - register int i; + register int n, i; /* * Use the explicit server if given on the command line. @@ -3342,6 +3612,7 @@ input char *name; /* name of zone to find servers for */ if (server && !primary) { (void) strcpy(nsname[0], server); + for (i = 0; i < MAXIPADDR && i < _res.nscount; i++) ipaddr[0][i] = nslist(i).sin_addr; naddrs[0] = i; @@ -3369,7 +3640,7 @@ input char *name; /* name of zone to find servers for */ return(FALSE); } - hp = gethostbyname(primaryname); + hp = geth_byname(primaryname); if (hp == NULL) { ns_error(primaryname, T_A, C_IN, server); @@ -3377,15 +3648,16 @@ input char *name; /* name of zone to find servers for */ return(FALSE); } - (void) strcpy(nsname[0], hp->h_name); + primaryname = strncpy(nsname[0], hp->h_name, MAXDNAME); + primaryname[MAXDNAME] = '\0'; + for (i = 0; i < MAXIPADDR && hp->h_addr_list[i]; i++) ipaddr[0][i] = incopy(hp->h_addr_list[i]); naddrs[0] = i; if (verbose) - printf("Found %d address%-2s for %s\n", + printf("Found %d address%s for %s\n", naddrs[0], plurale(naddrs[0]), nsname[0]); - nservers = 1; return(TRUE); } @@ -3394,7 +3666,6 @@ input char *name; /* name of zone to find servers for */ * Otherwise we have to find the nameservers for the zone. * These are supposed to be authoritative, but sometimes we * encounter lame delegations, perhaps due to misconfiguration. - * Retrieve the NS records for this zone. */ if (!get_servers(name)) { @@ -3415,7 +3686,7 @@ input char *name; /* name of zone to find servers for */ { if (naddrs[n] == 0) { - hp = gethostbyname(nsname[n]); + hp = geth_byname(nsname[n]); if (hp != NULL) { for (i = 0; i < MAXIPADDR && hp->h_addr_list[i]; i++) @@ -3424,7 +3695,7 @@ input char *name; /* name of zone to find servers for */ } if (verbose) - printf("Found %d address%-2s for %s by extra query\n", + printf("Found %d address%s for %s by extra query\n", naddrs[n], plurale(naddrs[n]), nsname[n]); if (hp == NULL) @@ -3435,8 +3706,9 @@ input char *name; /* name of zone to find servers for */ /* authoritative denial: probably misconfiguration */ if (h_errno == NO_DATA || h_errno == HOST_NOT_FOUND) { - errmsg("%s has lame delegation to %s", - name, nsname[n]); + if (server == NULL) + errmsg("%s has lame delegation to %s", + name, nsname[n]); } } @@ -3447,7 +3719,7 @@ input char *name; /* name of zone to find servers for */ else { if (verbose) - printf("Found %d address%-2s for %s\n", + printf("Found %d address%s for %s\n", naddrs[n], plurale(naddrs[n]), nsname[n]); } } @@ -3494,7 +3766,7 @@ input char *name; /* name of zone to find servers for */ return(FALSE); if (verbose > 1) - (void) print_info(&answer, n, name, T_NS, FALSE); + (void) print_info(&answer, n, name, T_NS, queryclass, FALSE); result = get_nsinfo(&answer, n, name); return(result); @@ -3505,7 +3777,7 @@ input char *name; /* name of zone to find servers for */ ** ------------------------------------------------------------------- ** ** Returns: -** TRUE if servers could be determined successfully. +** TRUE if the answer buffer was processed successfully. ** FALSE otherwise. ** ** Outputs: @@ -3539,9 +3811,9 @@ input char *name; /* name of zone to find servers for */ eom = (u_char *)answerbuf + answerlen; cp = (u_char *)answerbuf + HFIXEDSZ; - while (qdcount > 0 && cp < eom) + if (qdcount > 0 && cp < eom) /* should be exactly one record */ { - cp = skip_qrec(name, cp, msg, eom); + cp = skip_qrec(name, T_NS, queryclass, cp, msg, eom); if (cp == NULL) return(FALSE); qdcount--; @@ -3616,7 +3888,7 @@ input char *name; /* name of zone to find servers for */ nservers++; } } - else if ((type == T_A) && dlen == INADDRSZ) + else if ((type == T_A) && (dlen == INADDRSZ)) { for (i = 0; i < nservers; i++) if (sameword(nsname[i], rname)) @@ -3632,12 +3904,16 @@ input char *name; /* name of zone to find servers for */ cp += dlen; } else + { + /* just ignore other records */ cp += dlen; + } if (cp != eor) { pr_error("size error in %s record for %s, off by %s", pr_type(type), rname, itoa(cp - eor)); + h_errno = NO_RECOVERY; return(FALSE); } @@ -3652,6 +3928,8 @@ input char *name; /* name of zone to find servers for */ return(FALSE); } + /* set proper status if no answers found */ + h_errno = (nservers > 0) ? 0 : TRY_AGAIN; return(TRUE); } @@ -3889,7 +4167,7 @@ input char *name; /* name of zone to do zone xfer for */ printf("Trying server %s (%s) ...\n", inet_ntoa(ipaddr[n][i]), nsname[n]); - if (transfer_zone(name, queryclass, ipaddr[n][i], nsname[n])) + if (transfer_zone(name, ipaddr[n][i], nsname[n])) goto done; /* double break */ /* zone transfer failed */ @@ -3957,9 +4235,8 @@ done: */ bool -transfer_zone(name, class, inaddr, host) +transfer_zone(name, inaddr, host) input char *name; /* name of zone to do zone xfer for */ -input int class; /* specific resource record class */ input struct in_addr inaddr; /* address of server to be queried */ input char *host; /* name of server to be queried */ { @@ -3980,8 +4257,9 @@ input char *host; /* name of server to be queried */ /* * Perform the actual zone transfer. + * All error reporting is done by get_zone(). */ - if (get_zone(name, class, inaddr, host)) + if (get_zone(name, inaddr, host)) return(TRUE); /* @@ -3990,7 +4268,7 @@ input char *host; /* name of server to be queried */ * The information gathered is used by list_zone() after the zone transfer. */ for (n = 0; n < hostcount; n++) - xfree(hostname[n]); + xfree(hostname(n)); for (n = 0; n < zonecount; n++) xfree(zonename[n]); @@ -4022,9 +4300,8 @@ input char *host; /* name of server to be queried */ */ bool -get_zone(name, class, inaddr, host) +get_zone(name, inaddr, host) input char *name; /* name of zone to do zone xfer for */ -input int class; /* specific resource record class */ input struct in_addr inaddr; /* address of server to be queried */ input char *host; /* name of server to be queried */ { @@ -4034,11 +4311,12 @@ input char *host; /* name of server to be queried */ int ancount; int sock; struct sockaddr_in sin; - register int n; - register int i; + register int n, i; int nrecords = 0; /* number of records processed */ - int soacount = 0; /* count of SOA records */ + int npackets = 0; /* number of packets received */ + /* clear global counts */ + soacount = 0; /* count of SOA records */ zonecount = 0; /* count of delegated zones */ hostcount = 0; /* count of host names */ @@ -4047,7 +4325,7 @@ input char *host; /* name of server to be queried */ */ errno = 0; /* reset before querying nameserver */ - n = res_mkquery(QUERY, name, class, T_AXFR, (qbuf_t *)NULL, 0, + n = res_mkquery(QUERY, name, queryclass, T_AXFR, (qbuf_t *)NULL, 0, (rrec_t *)NULL, (qbuf_t *)&query, sizeof(querybuf)); if (n < 0) { @@ -4063,13 +4341,13 @@ input char *host; /* name of server to be queried */ pr_query((qbuf_t *)&query, n, stdout); } + /* setup destination address */ + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; sin.sin_port = htons(NAMESERVER_PORT); sin.sin_addr = inaddr; - /* add name and address to error messages */ - /* _res_setaddr(&sin, host); */ - sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { @@ -4080,7 +4358,7 @@ input char *host; /* name of server to be queried */ if (_res_connect(sock, &sin, sizeof(sin)) < 0) { - if (debug || verbose) + if (verbose || debug) _res_perror(&sin, host, "connect"); (void) close(sock); h_errno = TRY_AGAIN; @@ -4101,7 +4379,7 @@ input char *host; /* name of server to be queried */ } /* - * Process all incoming records, each record in a separate packet. + * Process all incoming packets, usually one record in a separate packet. */ while ((n = _res_read(sock, &sin, host, (char *)&answer, sizeof(querybuf))) != 0) { @@ -4126,7 +4404,7 @@ input char *host; /* name of server to be queried */ if (debug > 1) { printf("%sgot answer, %d bytes:\n", dbprefix, n); - pr_query((qbuf_t *)&answer, n, stdout); + pr_query((qbuf_t *)&answer, querysize(n), stdout); } /* @@ -4140,8 +4418,8 @@ input char *host; /* name of server to be queried */ if (bp->rcode != NOERROR || ancount == 0) { - if (debug || verbose) - print_status(&answer); + if (verbose || debug) + print_status(&answer, n); switch (bp->rcode) { @@ -4171,7 +4449,7 @@ input char *host; /* name of server to be queried */ break; } - if (nrecords != 0) + if (npackets != 0) pr_error("unexpected error during %s for %s from %s", pr_type(T_AXFR), name, host); @@ -4179,99 +4457,44 @@ input char *host; /* name of server to be queried */ return(FALSE); } + /* valid answer received, avoid buffer overrun */ h_errno = 0; + n = querysize(n); /* - * The nameserver and additional info section should be empty, - * and there should be a single answer in the answer section. + * The nameserver and additional info section should be empty. + * There may be multiple answers in the answer section. */ - if (ancount != 1) +#ifdef obsolete + if (ancount > 1) pr_error("multiple answers during %s for %s from %s", pr_type(T_AXFR), name, host); - - i = ntohs(bp->nscount); - if (i != 0) +#endif + if (ntohs(bp->nscount) != 0) pr_error("nonzero nscount during %s for %s from %s", pr_type(T_AXFR), name, host); - i = ntohs(bp->arcount); - if (i != 0) + if (ntohs(bp->arcount) != 0) pr_error("nonzero arcount during %s for %s from %s", pr_type(T_AXFR), name, host); /* * Valid packet received. Print contents if appropriate. + * Specific zone information will be saved by update_zone(). */ - nrecords++; + npackets += 1; + nrecords += ancount; - soaname = NULL, subname = NULL, adrname = NULL; + soaname = NULL, subname = NULL, adrname = NULL, address = 0; listhost = host; - (void) print_info(&answer, n, name, T_AXFR, TRUE); + + (void) print_info(&answer, n, name, T_AXFR, queryclass, FALSE); /* * Terminate upon the second SOA record for this zone. */ - if (soaname && sameword(soaname, name) && soacount++) + if (soacount > 1) break; - - /* the nameserver balks on this one */ - if (soaname && !sameword(soaname, name)) - pr_warning("extraneous SOA record for %s within %s from %s", - soaname, name, host); - - /* - * Save encountered delegated zone name for recursive listing. - */ - if (subname && indomain(subname, name, FALSE)) - { - i = zone_index(subname, TRUE); -#ifdef obsolete - for (i = 0; i < zonecount; i++) - if (sameword(zonename[i], subname)) - break; /* duplicate */ -#endif - if (i >= zonecount) - { - zonename = newlist(zonename, zonecount+1, char *); - zonename[zonecount] = newstr(subname); - zonecount++; - } - } - /* warn about strange delegated zones */ - else if (subname && !indomain(subname, name, TRUE)) - pr_warning("extraneous NS record for %s within %s from %s", - subname, name, host); - - /* - * Save encountered name of A record for host name count. - */ - if (adrname && indomain(adrname, name, FALSE) && !reverse) - { - i = host_index(adrname, (hostcount < MAXHOSTS)); -#ifdef obsolete - for (i = 0; i < hostcount; i++) - if (sameword(hostname[i], adrname)) - break; /* duplicate */ -#endif - if (i < hostcount && address != hostaddr[i]) - multaddr[i] = TRUE; - - if (i >= hostcount && hostcount < MAXHOSTS) - { - hostname[hostcount] = newstr(adrname); - hostaddr[hostcount] = address; - multaddr[hostcount] = FALSE; - hostcount++; - - if (hostcount == MAXHOSTS) - pr_error("maximum %s hosts reached within %s from %s", - itoa(hostcount), name, host); - } - } - /* check for unauthoritative glue records */ - else if (adrname && !indomain(adrname, name, TRUE)) - pr_warning("extraneous glue record for %s within %s from %s", - adrname, name, host); } /* @@ -4304,7 +4527,7 @@ input char *host; /* name of server to be queried */ i = host_index(zonename[n], FALSE); #ifdef obsolete for (i = 0; i < hostcount; i++) - if (sameword(hostname[i], zonename[n])) + if (sameword(hostname(i), zonename[n])) break; /* found */ #endif if (i < hostcount) @@ -4316,12 +4539,109 @@ input char *host; /* name of server to be queried */ * The zone transfer has been successful. */ if (verbose) - printf("Transfer complete, %d records received for %s\n", - nrecords, name); + { + printf("Transfer complete, %d record%s received for %s\n", + nrecords, plural(nrecords), name); + if (npackets != nrecords) + printf("Transfer consisted of %d packet%s from %s\n", + npackets, plural(npackets), host); + } return(TRUE); } + /* +** UPDATE_ZONE -- Save zone information during zone listings +** --------------------------------------------------------- +** +** Returns: +** None. +** +** Side effects: +** Stores list of delegated zones found in zonename[], +** and the count of delegated zones in ``zonecount''. +** Stores list of host names found in hostname[], +** and the count of host names in ``hostcount''. +** Stores the count of SOA records in ``soacount''. +** +** This routine is called by print_info() for each resource record. +*/ + +void +update_zone(name) +input char *name; /* name of zone to do zone xfer for */ +{ + char *host = listhost; /* contacted host for zone listings */ + register int i; + +/* + * Terminate upon the second SOA record for this zone. + */ + if (soaname && sameword(soaname, name)) + soacount++; + + /* the nameserver balks on this one */ + else if (soaname && !sameword(soaname, name)) + pr_warning("extraneous SOA record for %s within %s from %s", + soaname, name, host); + +/* + * Save encountered delegated zone name for recursive listing. + */ + if (subname && indomain(subname, name, FALSE)) + { + i = zone_index(subname, TRUE); +#ifdef obsolete + for (i = 0; i < zonecount; i++) + if (sameword(zonename[i], subname)) + break; /* duplicate */ +#endif + if (i >= zonecount) + { + zonename = newlist(zonename, zonecount+1, char *); + zonename[zonecount] = newstr(subname); + zonecount++; + } + } + + /* warn about strange delegated zones */ + else if (subname && !indomain(subname, name, TRUE)) + pr_warning("extraneous NS record for %s within %s from %s", + subname, name, host); + +/* + * Save encountered name of A record for host name count. + */ + if (adrname && indomain(adrname, name, FALSE) && !reverse) + { + i = host_index(adrname, TRUE); +#ifdef obsolete + for (i = 0; i < hostcount; i++) + if (sameword(hostname(i), adrname)) + break; /* duplicate */ +#endif + if (i >= hostcount) + { + if (hostcount >= maxhosts) + { + maxhosts += MAXHOSTINCR; + hostlist = newlist(hostlist, maxhosts, host_data_t); + } + hostname(hostcount) = newstr(adrname); + hostaddr(hostcount) = address; + multaddr(hostcount) = FALSE; + hostcount++; + } + else if (address != hostaddr(i)) + multaddr(i) = TRUE; + } + + /* check for unauthoritative glue records */ + else if (adrname && !indomain(adrname, name, TRUE)) + pr_warning("extraneous glue record for %s within %s from %s", + adrname, name, host); +} + /* ** GET_MXREC -- Fetch MX records of a domain ** ----------------------------------------- @@ -4345,7 +4665,7 @@ input char *name; /* domain name to get mx for */ if (n < 0) return(FALSE); - (void) print_info(&answer, n, name, T_MX, FALSE); + (void) print_info(&answer, n, name, T_MX, queryclass, FALSE); return(TRUE); } @@ -4374,7 +4694,7 @@ input char *name; /* name of zone to get soa for */ return(NULL); if (verbose > 1) - (void) print_info(&answer, n, name, T_SOA, FALSE); + (void) print_info(&answer, n, name, T_SOA, queryclass, FALSE); soaname = NULL; (void) get_soainfo(&answer, n, name); @@ -4416,7 +4736,7 @@ input char *name; /* name of zone to get soa for */ return(FALSE); if (verbose > 1) - (void) print_info(&answer, n, name, T_SOA, FALSE); + (void) print_info(&answer, n, name, T_SOA, queryclass, FALSE); soaname = NULL; (void) get_soainfo(&answer, n, name); @@ -4433,14 +4753,14 @@ input char *name; /* name of zone to get soa for */ ** ------------------------------------------------------------- ** ** Returns: -** TRUE if the SOA record was found successfully. +** TRUE if the answer buffer was processed successfully. ** FALSE otherwise. ** ** Outputs: ** The global struct ``soa'' is filled with the soa data. ** ** Side effects: -** Sets ``soaname'' if this is a valid SOA record. +** Sets ``soaname'' if there is a valid SOA record. ** This variable must have been cleared before calling ** get_soainfo() and may be checked afterwards. */ @@ -4464,9 +4784,9 @@ input char *name; /* name of zone to get soa for */ eom = (u_char *)answerbuf + answerlen; cp = (u_char *)answerbuf + HFIXEDSZ; - while (qdcount > 0 && cp < eom) + if (qdcount > 0 && cp < eom) /* should be exactly one record */ { - cp = skip_qrec(name, cp, msg, eom); + cp = skip_qrec(name, T_SOA, queryclass, cp, msg, eom); if (cp == NULL) return(FALSE); qdcount--; @@ -4482,6 +4802,7 @@ input char *name; /* name of zone to get soa for */ /* * Check answer section only. + * Check that answers match the requested zone. Ignore other entries. * The nameserver section may contain the nameservers for the zone, * and the additional section their addresses, but not guaranteed. * Those sections are usually empty for authoritative answers. @@ -4520,9 +4841,8 @@ input char *name; /* name of zone to get soa for */ printf("%-20s\t%d\t%s\t%s\n", rname, ttl, pr_class(class), pr_type(type)); #endif - switch (type) + if ((type == T_SOA) && sameword(rname, name)) { - case T_SOA: n = expand_name(rname, type, cp, msg, eom, soa.primary); if (n < 0) return(FALSE); @@ -4549,17 +4869,18 @@ input char *name; /* name of zone to get soa for */ /* valid complete soa record found */ soaname = strcpy(soanamebuf, rname); - break; - - default: + } + else + { + /* just ignore other records */ cp += dlen; - break; } if (cp != eor) { pr_error("size error in %s record for %s, off by %s", pr_type(type), rname, itoa(cp - eor)); + h_errno = NO_RECOVERY; return(FALSE); } @@ -4574,6 +4895,8 @@ input char *name; /* name of zone to get soa for */ return(FALSE); } + /* set proper status if no answers found */ + h_errno = (soaname != NULL) ? 0 : TRY_AGAIN; return(TRUE); } @@ -4805,7 +5128,7 @@ input int type, class, ttl; /* resource record fixed values */ */ for (hfunc = type, p = name; (c = *p) != '\0'; p++) { - hfunc = ((hfunc << 1) ^ (lower(c) & 0377)) % THASHSIZE; + hfunc = ((hfunc << 1) ^ (lowercase(c) & 0377)) % THASHSIZE; } for (ps = &ttltab[hfunc]; (s = *ps) != NULL; ps = &s->next) @@ -4822,7 +5145,7 @@ input int type, class, ttl; /* resource record fixed values */ if (s == NULL) { /* ps = &ttltab[hfunc]; */ - s = newlist(NULL, 1, ttl_tab_t); + s = newstruct(ttl_tab_t); /* initialize new entry */ s->name = newstr(name); @@ -4929,14 +5252,14 @@ input bool enter; /* add to table if not found */ */ for (hfunc = 0, p = name; (c = *p) != '\0'; p++) { - hfunc = ((hfunc << 1) ^ (lower(c) & 0377)) % HHASHSIZE; + hfunc = ((hfunc << 1) ^ (lowercase(c) & 0377)) % HHASHSIZE; } for (ps = &hosttab[hfunc]; (s = *ps) != NULL; ps = &s->next) { if (s->slot >= hostcount) continue; - if (sameword(hostname[s->slot], name)) + if (sameword(hostname(s->slot), name)) break; } @@ -4946,7 +5269,7 @@ input bool enter; /* add to table if not found */ if ((s == NULL) && enter) { /* ps = &hosttab[hfunc]; */ - s = newlist(NULL, 1, host_tab_t); + s = newstruct(host_tab_t); /* initialize new entry */ s->slot = hostcount; @@ -5038,7 +5361,7 @@ input bool enter; /* add to table if not found */ */ for (hfunc = 0, p = name; (c = *p) != '\0'; p++) { - hfunc = ((hfunc << 1) ^ (lower(c) & 0377)) % ZHASHSIZE; + hfunc = ((hfunc << 1) ^ (lowercase(c) & 0377)) % ZHASHSIZE; } for (ps = &zonetab[hfunc]; (s = *ps) != NULL; ps = &s->next) @@ -5055,7 +5378,7 @@ input bool enter; /* add to table if not found */ if ((s == NULL) && enter) { /* ps = &zonetab[hfunc]; */ - s = newlist(NULL, 1, zone_tab_t); + s = newstruct(zone_tab_t); /* initialize new entry */ s->slot = zonecount; @@ -5145,7 +5468,7 @@ input char *name; /* the domain name to check */ */ for (hfunc = 0, p = name; (c = *p) != '\0'; p++) { - hfunc = ((hfunc << 1) ^ (lower(c) & 0377)) % CHASHSIZE; + hfunc = ((hfunc << 1) ^ (lowercase(c) & 0377)) % CHASHSIZE; } for (ps = &canontab[hfunc]; (s = *ps) != NULL; ps = &s->next) @@ -5161,7 +5484,7 @@ input char *name; /* the domain name to check */ if (s == NULL) { /* ps = &canontab[hfunc]; */ - s = newlist(NULL, 1, canon_tab_t); + s = newstruct(canon_tab_t); /* initialize new entry */ s->name = newstr(name); @@ -5191,7 +5514,7 @@ input char *name; /* host name to check addresses for */ struct hostent *hp; register int i; struct in_addr inaddr[MAXADDRS]; - int naddr; + int naddress; char hnamebuf[MAXDNAME+1]; char *hname; char inamebuf[MAXDNAME+1]; @@ -5208,20 +5531,21 @@ input char *name; /* host name to check addresses for */ return(FALSE); } - hname = strcpy(hnamebuf, hp->h_name); + hname = strncpy(hnamebuf, hp->h_name, MAXDNAME); + hname[MAXDNAME] = '\0'; for (i = 0; i < MAXADDRS && hp->h_addr_list[i]; i++) inaddr[i] = incopy(hp->h_addr_list[i]); - naddr = i; + naddress = i; if (verbose) printf("Found %d address%s for %s\n", - naddr, plurale(naddr), hname); + naddress, plurale(naddress), hname); /* * Map back the addresses found, and check whether they revert to host. */ - for (matched = 0, i = 0; i < naddr; i++) + for (matched = 0, i = 0; i < naddress; i++) { iname = strcpy(inamebuf, inet_ntoa(inaddr[i])); @@ -5238,7 +5562,7 @@ input char *name; /* host name to check addresses for */ matched++; } - return((matched == naddr) ? TRUE : FALSE); + return((matched == naddress) ? TRUE : FALSE); } /* @@ -5276,14 +5600,14 @@ input ipaddr_t addr; /* address of host to check */ return(FALSE); } - hname = strcpy(hnamebuf, hp->h_name); + hname = strncpy(hnamebuf, hp->h_name, MAXDNAME); + hname[MAXDNAME] = '\0'; if (verbose) printf("Address %s maps to %s\n", iname, hname); /* * Lookup the host name found to fetch its addresses. - * Verify whether the mapped host name is canonical. */ hp = gethostbyname(hname); if (hp == NULL) @@ -5292,6 +5616,9 @@ input ipaddr_t addr; /* address of host to check */ return(FALSE); } +/* + * Verify whether the mapped host name is canonical. + */ if (!sameword(hp->h_name, hname)) pr_warning("%s host %s is not canonical (%s)", iname, hname, hp->h_name); @@ -5318,6 +5645,95 @@ input ipaddr_t addr; /* address of host to check */ return(matched ? TRUE : FALSE); } + /* +** GETH_BYNAME -- Wrapper for gethostbyname +** ---------------------------------------- +** +** Returns: +** Pointer to struct hostent if lookup was successful. +** NULL otherwise. +** +** Note. This routine works for fully qualified names only. +** The entire special res_search() processing can be skipped. +*/ + +struct hostent * +geth_byname(name) +input CONST char *name; /* name to do forward lookup for */ +{ + querybuf answer; + struct hostent *hp; + register int n; + + hp = gethostbyname(name); + if (hp != NULL) + return(hp); + + if (verbose > print_level) + printf("Finding addresses for %s ...\n", name); + + n = get_info(&answer, name, T_A, C_IN); + if (n < 0) + return(NULL); + + if ((verbose > print_level + 1) && (print_level < 1)) + (void) print_info(&answer, n, name, T_A, C_IN, FALSE); + + hp = gethostbyname(name); + return(hp); +} + + /* +** GETH_BYADDR -- Wrapper for gethostbyaddr +** ---------------------------------------- +** +** Returns: +** Pointer to struct hostent if lookup was successful. +** NULL otherwise. +*/ + +struct hostent * +geth_byaddr(addr, size, family) +input CONST char *addr; /* address to do reverse mapping for */ +input int size; /* size of the address */ +input int family; /* address family */ +{ + char addrbuf[4*4 + sizeof(ARPA_ROOT) + 1]; + char *name = addrbuf; + u_char *a = (u_char *)addr; + querybuf answer; + struct hostent *hp; + register int n; + + if (size != INADDRSZ || family != AF_INET) + { + hp = gethostbyaddr(addr, size, family); + return(hp); + } + + hp = gethostbyaddr(addr, size, family); + if (hp != NULL) + return(hp); + + /* construct absolute reverse name *without* trailing dot */ + (void) sprintf(addrbuf, "%u.%u.%u.%u.%s", + a[3]&0xff, a[2]&0xff, a[1]&0xff, a[0]&0xff, ARPA_ROOT); + + if (verbose > print_level) + printf("Finding reverse mapping for %s ...\n", + inet_ntoa(incopy(addr))); + + n = get_info(&answer, name, T_PTR, C_IN); + if (n < 0) + return(NULL); + + if ((verbose > print_level + 1) && (print_level < 1)) + (void) print_info(&answer, n, name, T_PTR, C_IN, FALSE); + + hp = gethostbyaddr(addr, size, family); + return(hp); +} + /* ** PARSE_TYPE -- Decode rr type from input string ** ---------------------------------------------- @@ -5326,8 +5742,8 @@ input ipaddr_t addr; /* address of host to check */ ** Value of resource record type. ** -1 if specified record name is invalid. ** -** Note. T_MD, T_MF, T_MAILA are obsolete, but recognized. -** T_AXFR is not allowed to be specified as query type. +** Note. Several types are deprecated or obsolete, but recognized. +** T_AXFR/T_IXFR is not allowed to be specified as query type. */ int @@ -5336,23 +5752,27 @@ input char *str; /* input string with record type */ { register int type; + /* standard types */ + if (sameword(str, "A")) return(T_A); if (sameword(str, "NS")) return(T_NS); if (sameword(str, "MD")) return(T_MD); /* obsolete */ if (sameword(str, "MF")) return(T_MF); /* obsolete */ if (sameword(str, "CNAME")) return(T_CNAME); if (sameword(str, "SOA")) return(T_SOA); - if (sameword(str, "MB")) return(T_MB); - if (sameword(str, "MG")) return(T_MG); - if (sameword(str, "MR")) return(T_MR); - if (sameword(str, "NULL")) return(T_NULL); + if (sameword(str, "MB")) return(T_MB); /* deprecated */ + if (sameword(str, "MG")) return(T_MG); /* deprecated */ + if (sameword(str, "MR")) return(T_MR); /* deprecated */ + if (sameword(str, "NULL")) return(T_NULL); /* obsolete */ if (sameword(str, "WKS")) return(T_WKS); if (sameword(str, "PTR")) return(T_PTR); if (sameword(str, "HINFO")) return(T_HINFO); - if (sameword(str, "MINFO")) return(T_MINFO); + if (sameword(str, "MINFO")) return(T_MINFO); /* deprecated */ if (sameword(str, "MX")) return(T_MX); if (sameword(str, "TXT")) return(T_TXT); + /* new types */ + if (sameword(str, "RP")) return(T_RP); if (sameword(str, "AFSDB")) return(T_AFSDB); if (sameword(str, "X25")) return(T_X25); @@ -5363,21 +5783,34 @@ input char *str; /* input string with record type */ if (sameword(str, "SIG")) return(T_SIG); if (sameword(str, "KEY")) return(T_KEY); if (sameword(str, "PX")) return(T_PX); - if (sameword(str, "GPOS")) return(T_GPOS); + if (sameword(str, "GPOS")) return(T_GPOS); /* withdrawn */ if (sameword(str, "AAAA")) return(T_AAAA); if (sameword(str, "LOC")) return(T_LOC); + if (sameword(str, "NXT")) return(T_NXT); + if (sameword(str, "EID")) return(T_EID); + if (sameword(str, "NIMLOC")) return(T_NIMLOC); + if (sameword(str, "SRV")) return(T_SRV); + if (sameword(str, "ATMA")) return(T_ATMA); + if (sameword(str, "NAPTR")) return(T_NAPTR); + + /* nonstandard types */ if (sameword(str, "UINFO")) return(T_UINFO); if (sameword(str, "UID")) return(T_UID); if (sameword(str, "GID")) return(T_GID); if (sameword(str, "UNSPEC")) return(T_UNSPEC); + /* filters */ + + if (sameword(str, "IXFR")) return(-1); /* illegal */ if (sameword(str, "AXFR")) return(-1); /* illegal */ if (sameword(str, "MAILB")) return(T_MAILB); if (sameword(str, "MAILA")) return(T_MAILA); /* obsolete */ if (sameword(str, "ANY")) return(T_ANY); if (sameword(str, "*")) return(T_ANY); + /* unknown types */ + type = atoi(str); if (type >= T_FIRST && type <= T_LAST) return(type); @@ -6016,8 +6449,9 @@ input int rcode; /* error code from bp->rcode */ */ void -print_status(answerbuf) +print_status(answerbuf, answerlen) input querybuf *answerbuf; /* location of answer buffer */ +input int answerlen; /* length of answer buffer */ { HEADER *bp; int ancount; @@ -6027,13 +6461,26 @@ input querybuf *answerbuf; /* location of answer buffer */ ancount = ntohs(bp->ancount); failed = (bp->rcode != NOERROR || ancount == 0); - printf("%sQuery %s, %d answer%s%s, %sstatus: %s\n", - verbose ? "" : dbprefix, - failed ? "failed" : "done", - ancount, plural(ancount), - bp->tc ? " (truncated)" : "", - bp->aa ? "authoritative " : "", - decode_error((int)bp->rcode)); + printf("%s", verbose ? "" : dbprefix); + + printf("Query %s", failed ? "failed" : "done"); + + if (bp->tc || (answerlen > PACKETSZ)) + printf(", %d byte%s", answerlen, plural(answerlen)); + + if (bp->tc) + { + if (answerlen > sizeof(querybuf)) + printf(" (truncated to %d)", sizeof(querybuf)); + else + printf(" (truncated)"); + } + + printf(", %d answer%s", ancount, plural(ancount)); + + printf(", %s", bp->aa ? "authoritative " : ""); + + printf("status: %s\n", decode_error((int)bp->rcode)); } /* @@ -6186,8 +6633,11 @@ input bool equal; /* set if name may be same as zone */ dot = index(name, '.'); while (dot != NULL) { - if (sameword(dot+1, domain)) - return(TRUE); + if (!is_quoted(dot, name)) + { + if (sameword(dot+1, domain)) + return(TRUE); + } dot = index(dot+1, '.'); } @@ -6217,10 +6667,20 @@ input bool equal; /* set if name may be same as zone */ return(equal); dot = index(name, '.'); - if (dot == NULL) - return(sameword(domain, ".")); + while (dot != NULL) + { + if (!is_quoted(dot, name)) + { + if (sameword(dot+1, domain)) + return(TRUE); + + return(FALSE); + } - if (sameword(dot+1, domain)) + dot = index(dot+1, '.'); + } + + if (sameword(domain, ".")) return(TRUE); return(FALSE); @@ -6276,6 +6736,10 @@ input int nzones; /* number of known delegated zones */ ** ** Returns: ** Number of shared trailing components in both names. +** +** Note. This routine is currently used only to compare nameserver +** names in the RHS of NS records, so there is no need to check +** for embedded quoted dots. */ int @@ -6291,7 +6755,7 @@ input char *domain; /* domain name to compare against */ while (--i >= 0 && --j >= 0) { - if (lower(name[i]) != lower(domain[j])) + if (lowercase(name[i]) != lowercase(domain[j])) break; if (domain[j] == '.') matched++; @@ -6438,10 +6902,12 @@ char * pr_type(type) input int type; /* resource record type */ { - static char buf[30]; + static char buf[30]; /* sufficient for 64-bit values */ switch (type) { + /* standard types */ + case T_A: return("A"); /* internet address */ case T_NS: return("NS"); /* authoritative server */ case T_MD: return("MD"); /* mail destination */ @@ -6459,6 +6925,8 @@ input int type; /* resource record type */ case T_MX: return("MX"); /* mail routing info */ case T_TXT: return("TXT"); /* descriptive text */ + /* new types */ + case T_RP: return("RP"); /* responsible person */ case T_AFSDB: return("AFSDB"); /* afs database location */ case T_X25: return("X25"); /* x25 address */ @@ -6472,12 +6940,23 @@ input int type; /* resource record type */ case T_GPOS: return("GPOS"); /* geographical position */ case T_AAAA: return("AAAA"); /* ip v6 address */ case T_LOC: return("LOC"); /* geographical location */ + case T_NXT: return("NXT"); /* next valid name */ + case T_EID: return("EID"); /* endpoint identifier */ + case T_NIMLOC: return("NIMLOC"); /* nimrod locator */ + case T_SRV: return("SRV"); /* service info */ + case T_ATMA: return("ATMA"); /* atm address */ + case T_NAPTR: return("NAPTR"); /* naming authority urn */ + + /* nonstandard types */ case T_UINFO: return("UINFO"); /* user information */ case T_UID: return("UID"); /* user ident */ case T_GID: return("GID"); /* group ident */ case T_UNSPEC: return("UNSPEC"); /* unspecified binary data */ + /* filters */ + + case T_IXFR: return("IXFR"); /* incremental zone transfer */ case T_AXFR: return("AXFR"); /* zone transfer */ case T_MAILB: return("MAILB"); /* matches MB/MR/MG/MINFO */ case T_MAILA: return("MAILA"); /* matches MD/MF */ @@ -6486,6 +6965,7 @@ input int type; /* resource record type */ case T_NONE: return("resource"); /* not yet determined */ } + /* unknown type */ (void) sprintf(buf, "%d", type); return(buf); } @@ -6502,7 +6982,7 @@ char * pr_class(class) input int class; /* resource record class */ { - static char buf[30]; + static char buf[30]; /* sufficient for 64-bit values */ switch (class) { @@ -6513,19 +6993,21 @@ input int class; /* resource record class */ case C_ANY: return("ANY"); /* any class */ } + /* unknown class */ (void) sprintf(buf, "%d", class); return(buf); } /* -** EXPAND_NAME -- Expand compressed domain name in a recource record +** EXPAND_NAME -- Expand compressed domain name in a resource record ** ----------------------------------------------------------------- ** ** Returns: ** Number of bytes advanced in answer buffer. ** -1 if there was a format error. ** -** It is assumed that the specified buffer is of sufficient size. +** It is assumed that the specified buffer is of a fixed size +** MAXDNAME+1 that should be sufficient to store the data. */ int @@ -6547,6 +7029,9 @@ output char *namebuf; /* location of buf to expand name in */ return(-1); } + /* should not be necessary, but who knows */ + namebuf[MAXDNAME] = '\0'; + /* change root to single dot */ if (namebuf[0] == '\0') { @@ -6610,7 +7095,7 @@ input int size; /* required record size remaining */ ** only in the middle). We only check the individual characters. ** Strictly speaking, this restriction is only for ``host names''. ** The underscore is illegal, at least not recommended, but is -** so abundant that is requires special processing. +** so abundant that it requires special processing. ** ** If the domain name represents a mailbox specification, the ** first label up to the first (unquoted) dot is the local part @@ -6621,6 +7106,8 @@ input int size; /* required record size remaining */ ** wildcarding. It is valid only in the LHS resource record name, ** in definitions in zone files only as the first component. ** Used primarily in wildcard MX record definitions. +** +** Note. This routine is much too liberal. */ char *specials = ".()<>@,;:\\\"[]"; /* RFC 822 specials */ @@ -6670,7 +7157,7 @@ input bool underscore; /* set if underscores are allowed */ continue; /* allow '*' for use in wildcard names */ - if ((c == '*') && wildcard) + if ((c == '*') && (p == name && p[1] == '.') && wildcard) continue; /* ignore underscore in certain circumstances */ @@ -6715,7 +7202,7 @@ input char *name; /* the domain name to check */ save_errno = errno; save_herrno = h_errno; - hp = gethostbyname(name); + hp = geth_byname(name); status = h_errno; errno = save_errno; @@ -6770,7 +7257,7 @@ input struct in_addr inaddr; /* address of A record to check */ save_errno = errno; save_herrno = h_errno; - hp = gethostbyaddr((char *)&inaddr, INADDRSZ, AF_INET); + hp = geth_byaddr((char *)&inaddr, INADDRSZ, AF_INET); status = h_errno; errno = save_errno; @@ -6805,10 +7292,10 @@ input struct in_addr inaddr; /* address of A record to check */ int compare_name(a, b) -input char **a; /* first name */ -input char **b; /* second name */ +input const ptr_t *a; /* first name */ +input const ptr_t *b; /* second name */ { - return(strcasecmp(*a, *b)); + return(strcasecmp(*(char **)a, *(char **)b)); } /* @@ -6840,8 +7327,8 @@ input siz_t size; /* number of bytes to allocate */ } /* -** ITOA -- Convert integer value to ascii string -** --------------------------------------------- +** ITOA -- Convert value to decimal integer ascii string +** ----------------------------------------------------- ** ** Returns: ** Pointer to string. @@ -6851,15 +7338,14 @@ char * itoa(n) input int n; /* value to convert */ { - static char buf[30]; + static char buf[30]; /* sufficient for 64-bit values */ (void) sprintf(buf, "%d", n); return(buf); } - -/* -** UTOA -- Convert unsigned integer value to ascii string + /* +** UTOA -- Convert value to unsigned decimal ascii string ** ------------------------------------------------------ ** ** Returns: @@ -6870,26 +7356,48 @@ char * utoa(n) input int n; /* value to convert */ { - static char buf[30]; + static char buf[30]; /* sufficient for 64-bit values */ (void) sprintf(buf, "%u", (unsigned)n); return(buf); } /* -** STOA -- Extract partial ascii string -** ------------------------------------ +** XTOA -- Convert value to hexadecimal ascii string +** ------------------------------------------------- +** +** Returns: +** Pointer to string. +*/ + +char * +xtoa(n) +input int n; /* value to convert */ +{ + static char buf[17]; /* sufficient for 64-bit values */ + + (void) sprintf(buf, "%X", (unsigned)n); + return(buf); +} + + /* +** STOA -- Extract partial ascii string, escape if necessary +** --------------------------------------------------------- ** ** Returns: ** Pointer to string. */ char * -stoa(cp, size) +stoa(cp, size, escape) input u_char *cp; /* current position in answer buf */ input int size; /* number of bytes to extract */ +input bool escape; /* escape special characters if set */ { - static char buf[MAXDLEN+1]; + static char buf[2*MAXDLEN+1]; + register char *p; + register char c; + register int i; if (size > MAXDLEN) size = MAXDLEN; @@ -6900,8 +7408,81 @@ input int size; /* number of bytes to extract */ else (void) sprintf(buf, "%s", ""); #endif - bcopy((char *)cp, buf, size); - buf[size] = '\0'; + + for (p = buf, i = 0; i < size; i++) + { + c = *cp++; + if (escape && (c == '\n' || c == '\\' || c == '"')) + *p++ = '\\'; + *p++ = c; + } + *p = '\0'; + + return(buf); +} + + /* +** BASE_NTOA -- Convert binary data to base64 ascii +** ------------------------------------------------ +** +** Returns: +** Pointer to string. +** +** This routine is used to convert encoded keys and signatures +** in T_KEY and T_SIG resource records. +*/ + +char b64tab[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char * +base_ntoa(cp, size) +input u_char *cp; /* current position in answer buf */ +input int size; /* number of bytes to extract */ +{ + static char buf[MAXB64SIZE+1]; + register char *p; + int c1, c2, c3, c4; + + if (size > MAXMD5SIZE) + size = MAXMD5SIZE; + + for (p = buf; size > 2; cp += 3, size -= 3) + { + c1 = (((int)cp[0] >> 2) & 0x3f); + c2 = (((int)cp[0] & 0x03) << 4) + (((int)cp[1] >> 4) & 0x0f); + c3 = (((int)cp[1] & 0x0f) << 2) + (((int)cp[2] >> 6) & 0x03); + c4 = ((int)cp[2] & 0x3f); + + *p++ = b64tab[c1]; + *p++ = b64tab[c2]; + *p++ = b64tab[c3]; + *p++ = b64tab[c4]; + } + + if (size == 2) + { + c1 = (((int)cp[0] >> 2) & 0x3f); + c2 = (((int)cp[0] & 0x03) << 4) + (((int)cp[1] >> 4) & 0x0f); + c3 = (((int)cp[1] & 0x0f) << 2); + + *p++ = b64tab[c1]; + *p++ = b64tab[c2]; + *p++ = b64tab[c3]; + *p++ = '='; + } + else if (size == 1) + { + c1 = (((int)cp[0] >> 2) & 0x3f); + c2 = (((int)cp[0] & 0x03) << 4); + + *p++ = b64tab[c1]; + *p++ = b64tab[c2]; + *p++ = '='; + *p++ = '='; + } + *p = '\0'; + return(buf); } @@ -6947,6 +7528,68 @@ input int size; /* number of bytes to extract */ return(buf); } + /* +** IPNG_NTOA -- Convert binary ip v6 address to ascii +** -------------------------------------------------- +** +** Returns: +** Pointer to string. +** +** As per RFC 1886 an ip v6 address is encoded in binary form +** in the resource record. The size is fixed. +*/ + +char * +ipng_ntoa(cp) +input u_char *cp; /* current position in answer buf */ +{ + static char buf[5*(IPNGSIZE/2)+1]; + register char *p; + register int n; + register int i; + + for (p = buf, i = 0; i < IPNGSIZE/2; i++) + { + n = _getshort(cp); + cp += INT16SZ; + + (void) sprintf(p, ":%X", n); + p += strlength(p); + } + *p = '\0'; + + return(buf + 1); +} + + /* +** PR_DATE -- Produce printable version of a clock value +** ----------------------------------------------------- +** +** Returns: +** Pointer to string. +** +** The value is a standard absolute clock value. +*/ + +char * +pr_date(value) +input int value; /* the clock value to be converted */ +{ + static char buf[sizeof("YYYYMMDDHHMMSS")+1]; + time_t clocktime = value; + struct tm *t; + + t = gmtime(&clocktime); + t->tm_year += 1900; + t->tm_mon += 1; + + (void) sprintf(buf, "%04d%02d%02d%02d%02d%02d", + t->tm_year, t->tm_mon, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec); + + return(buf); +} + /* ** PR_TIME -- Produce printable version of a time interval ** ------------------------------------------------------- @@ -7060,7 +7703,7 @@ input char *neg; /* suffix if value negative */ /* * Normalize. */ - value -= (1 << 31); + value -= (int)((unsigned)1 << 31); direction = pos; if (value < 0) diff --git a/usr.sbin/named/host/mxlookup b/usr.sbin/named/host/mxlookup index bbb5863d1ee..79ea7d49190 100644 --- a/usr.sbin/named/host/mxlookup +++ b/usr.sbin/named/host/mxlookup @@ -1,4 +1,5 @@ #!/bin/sh - +# $OpenBSD: mxlookup,v 1.2 1997/03/12 10:41:55 downsj Exp $ # # @(#)mxlookup e07@nikhef.nl (Eric Wassenaar) 950108 # diff --git a/usr.sbin/named/host/nslookup b/usr.sbin/named/host/nslookup index 71601f7057c..3f449258e86 100644 --- a/usr.sbin/named/host/nslookup +++ b/usr.sbin/named/host/nslookup @@ -1,4 +1,5 @@ #!/bin/sh - +# $OpenBSD: nslookup,v 1.2 1997/03/12 10:41:55 downsj Exp $ # # @(#)nslookup e07@nikhef.nl (Eric Wassenaar) 940919 # diff --git a/usr.sbin/named/host/port.h b/usr.sbin/named/host/port.h index 3e0ec14f6fe..9c1381af245 100644 --- a/usr.sbin/named/host/port.h +++ b/usr.sbin/named/host/port.h @@ -1,16 +1,20 @@ +/* $OpenBSD: port.h,v 1.2 1997/03/12 10:41:56 downsj Exp $ */ + /* ** Various portability definitions. ** -** @(#)port.h e07@nikhef.nl (Eric Wassenaar) 950925 +** @(#)port.h e07@nikhef.nl (Eric Wassenaar) 961010 */ #if defined(SYSV) || defined(SVR4) +#define SYSV_MALLOC #define SYSV_MEMSET #define SYSV_STRCHR #define SYSV_SETVBUF #endif #if defined(__hpux) || defined(hpux) +#define SYSV_MALLOC #define SYSV_SETVBUF #endif @@ -20,11 +24,9 @@ #define BIND_48 #endif -#if defined(BIND_49) -#if defined(__BIND) +#if defined(BIND_49) && defined(__BIND) #define BIND_493 #endif -#endif /* ** Define constants for fixed sizes. @@ -33,15 +35,15 @@ #ifndef INT16SZ #define INT16SZ 2 /* for systems without 16-bit ints */ #endif - #ifndef INT32SZ #define INT32SZ 4 /* for systems without 32-bit ints */ #endif - #ifndef INADDRSZ #define INADDRSZ 4 /* for sizeof(struct inaddr) != 4 */ #endif +#define IPNGSIZE 16 /* 128 bit ip v6 address size */ + /* ** The following should depend on existing definitions. */ @@ -86,9 +88,15 @@ typedef int sigtype_t; typedef void sigtype_t; #endif -/* too primitive */ +#if defined(SYSV_MALLOC) +typedef void ptr_t; /* generic pointer type */ +typedef u_int siz_t; /* general size type */ +typedef void free_t; +#else typedef char ptr_t; /* generic pointer type */ typedef u_int siz_t; /* general size type */ +typedef int free_t; +#endif #ifdef SYSV_MEMSET #define bzero(a,n) (void) memset(a,'\0',n) @@ -129,6 +137,10 @@ typedef u_int siz_t; /* general size type */ #define PROTO(TYPES) () +#if !defined(__STDC__) || defined(apollo) +#define const +#endif + #if defined(__STDC__) && defined(BIND_49) #define CONST const #else diff --git a/usr.sbin/named/host/rrec.h b/usr.sbin/named/host/rrec.h index 305f8af3ebd..58f75cc2bae 100644 --- a/usr.sbin/named/host/rrec.h +++ b/usr.sbin/named/host/rrec.h @@ -1,23 +1,24 @@ +/* $OpenBSD: rrec.h,v 1.2 1997/03/12 10:41:56 downsj Exp $ */ + /* ** Resource record structures. ** ** These define the various resource record fields after decoding ** from the internal representation in the nameserver answer buffer. ** -** @(#)rrec.h e07@nikhef.nl (Eric Wassenaar) 941205 +** @(#)rrec.h e07@nikhef.nl (Eric Wassenaar) 961010 */ #define MAXSTRING 255 /* maximum size of single encoded string */ -#define MAXSTRLEN MAXDLEN /* maximum size of total encoded string */ +#define MAXSTRLEN MAXDLEN /* maximum size of multiple substrings */ typedef struct rr_data { u_char databuf[MAXDLEN]; /* generic data buffer */ } rr_data_t; /* -** Record-specific data fields. +** Record-specific data fields, traditional records. */ - /* traditional records */ typedef struct a_data { ipaddr_t address; /* internet address of host */ @@ -91,10 +92,12 @@ typedef struct mx_data { } mx_data_t; typedef struct txt_data { - char text[MAXSTRLEN+1]; /* concatenated substrings */ + char text[MAXSTRLEN+1]; /* multiple substrings */ } txt_data_t; - /* later additions */ +/* +** Record-specific data fields, later additions. +*/ typedef struct rp_data { char mailbox[MAXDNAME+1]; /* name of person mailbox */ @@ -128,6 +131,25 @@ typedef struct nsapptr_data { char nsapdomain[MAXDNAME+1]; /* domain name of nsap pointer */ } nsapptr_data_t; +typedef struct sig_data { + int sigtype; /* resource record type covered */ + int algorithm; /* signature encoding algorithm */ + int nlabels; /* number of labels in SIG name */ + int sigttl; /* original ttl of SIG record */ + time_t expiretime; /* signature expiration time */ + time_t sigtime; /* time signature was signed */ + int footprint; /* key identification */ + char signer[MAXDNAME+1]; /* signer's domain name */ + u_char sig[MAXMD5SIZE]; /* encoded signature */ +} sig_data_t; + +typedef struct key_data { + int keyflags; /* key description flags */ + int protocol; /* protocol suite */ + int algorithm; /* key encoding algorithm */ + u_char key[MAXMD5SIZE]; /* encoded key */ +} key_data_t; + typedef struct px_data { int mappref; /* preference value */ char map822[MAXDNAME+1]; /* rfc822 domain name */ @@ -140,6 +162,10 @@ typedef struct gpos_data { char altpos[MAXSTRING+1]; /* geographical altitude */ } gpos_data_t; +typedef struct aaaa_data { + u_char ipngaddr[IPNGSIZE]; /* binary ip v6 address */ +} aaaa_data_t; + typedef struct loc_data { int locversion; /* version number */ int objectsize; /* size of object */ @@ -150,7 +176,30 @@ typedef struct loc_data { int altitude; /* geographical altitude */ } loc_data_t; - /* nonstandard records */ +typedef struct nxt_data { + char nxtdomain[MAXDNAME+1]; /* name of next domain in order */ + u_char typemap[32]; /* types 0-255 */ +} nxt_data_t; + +typedef struct srv_data { + int srvpref; /* preference value */ + int srvweight; /* load balancing weight */ + int srvport; /* port of service */ + char srvhost[MAXDNAME+1]; /* name of service host */ +} srv_data_t; + +typedef struct naptr_data { + int naorder; + int napref; /* preference value */ + char naflags[MAXSTRING+1]; /* flags */ + char naservice[MAXSTRING+1]; + char naregexp[MAXSTRING+1]; + char nahost[MAXDNAME+1]; /* name of naming authority host */ +} naptr_data_t; + +/* +** Record-specific data fields, nonstandard types. +*/ typedef struct uinfo_data { char userinfo[MAXSTRLEN+1]; /* user description */ @@ -202,9 +251,15 @@ typedef struct rrecord { rt_data_t data_rt; nsap_data_t data_nsap; nsapptr_data_t data_nsapptr; + sig_data_t data_sig; + key_data_t data_key; px_data_t data_px; gpos_data_t data_gpos; + aaaa_data_t data_aaaa; loc_data_t data_loc; + nxt_data_t data_nxt; + srv_data_t data_srv; + naptr_data_t data_naptr; uinfo_data_t data_uinfo; uid_data_t data_uid; gid_data_t data_gid; @@ -236,9 +291,15 @@ typedef struct rrecord { #define t_rt data.data_rt #define t_nsap data.data_nsap #define t_nsapptr data.data_nsapptr +#define t_sig data.data_sig +#define t_key data.data_key #define t_px data.data_px #define t_gpos data.data_gpos +#define t_aaaa data.data_aaaa #define t_loc data.data_loc +#define t_nxt data.data_nxt +#define t_srv data.data_srv +#define t_naptr data.data_naptr #define t_uinfo data.data_uinfo #define t_uid data.data_uid #define t_gid data.data_gid diff --git a/usr.sbin/named/host/send.c b/usr.sbin/named/host/send.c index f8a76825dec..e365e914a25 100644 --- a/usr.sbin/named/host/send.c +++ b/usr.sbin/named/host/send.c @@ -1,3 +1,5 @@ +/* $OpenBSD: send.c,v 1.2 1997/03/12 10:41:57 downsj Exp $ */ + /* * Copyright (c) 1985, 1989 Regents of the University of California. * All rights reserved. @@ -18,7 +20,7 @@ */ #ifndef lint -static char Version[] = "@(#)send.c e07@nikhef.nl (Eric Wassenaar) 951231"; +static char Version[] = "@(#)send.c e07@nikhef.nl (Eric Wassenaar) 961013"; #endif #if defined(apollo) && defined(lint) @@ -47,7 +49,7 @@ static char Version[] = "@(#)send.c e07@nikhef.nl (Eric Wassenaar) 951231"; #define output /* modified output parameter */ #define bitset(a,b) (((a) & (b)) != 0) -#define setalarm(n) (void) alarm((unsigned int)n) +#define setalarm(n) (void) alarm((unsigned int)(n)) extern int errno; extern res_state_t _res; /* defined in res_init.c */ @@ -58,13 +60,13 @@ static int timeout; /* connection read timeout */ static struct sockaddr_in from; /* address of inbound packet */ static struct sockaddr *from_sa = (struct sockaddr *)&from; -/* extern */ char *inet_ntoa PROTO((struct in_addr)); +unsigned int alarm PROTO((unsigned int)); -/* send.c */ #ifdef HOST_RES_SEND int res_send PROTO((CONST qbuf_t *, int, qbuf_t *, int)); void _res_close PROTO((void)); +static int check_from PROTO((void)); static int send_stream PROTO((struct sockaddr_in *, qbuf_t *, int, qbuf_t *, int)); static int send_dgram PROTO((struct sockaddr_in *, qbuf_t *, int, qbuf_t *, int)); #endif /*HOST_RES_SEND*/ @@ -82,7 +84,7 @@ void _res_perror PROTO((struct sockaddr_in *, char *, char *)); ** ----------------------------------------------------- ** ** Returns: -** Length of nameserver answer buffer, if obtained. +** Length of (untruncated) nameserver answer, if obtained. ** -1 if an error occurred (errno set appropriately). ** ** This is a simplified version of the BIND 4.8.3 res_send(). @@ -125,8 +127,8 @@ input int anslen; /* maximum size of answer buffer */ v_circuit = bitset(RES_USEVC, _res.options) || (querylen > PACKETSZ); /* reset server failure codes */ - for (n = 0; n < MAXNS; n++) - servfail[n] = 0; + for (ns = 0; ns < MAXNS; ns++) + servfail[ns] = 0; /* * Do _res.retry attempts for each of the _res.nscount addresses. @@ -172,10 +174,10 @@ retry: n = send_dgram(addr, query, querylen, answer, anslen); /* check truncation; use v_circuit with same server */ - if (n > 0 && bp->tc) + if ((n > 0) && bp->tc) { if (bitset(RES_DEBUG, _res.options)) - printf("%struncated answer\n", dbprefix); + printf("%struncated answer, %d bytes\n", dbprefix, n); if (!bitset(RES_IGNTC, _res.options)) { @@ -205,7 +207,7 @@ retry: if (bitset(RES_DEBUG, _res.options)) { printf("%sgot answer, %d bytes:\n", dbprefix, n); - pr_query(answer, n, stdout); + pr_query(answer, (n > anslen) ? anslen : n, stdout); } /* we have an answer; clear possible error condition */ @@ -244,14 +246,55 @@ _res_close() errno = save_errno; } + /* +** CHECK_FROM -- Make sure the response comes from a known server +** -------------------------------------------------------------- +** +** Returns: +** Nonzero if the source address is known. +** Zero otherwise. +*/ + +static int +check_from() +{ + struct sockaddr_in *addr; + register int ns; + + for (ns = 0; ns < _res.nscount; ns++) + { + /* fetch server address */ + addr = &nslist(ns); + + if (from.sin_family != addr->sin_family) + continue; + + if (from.sin_port != addr->sin_port) + continue; + + /* this allows a reply from any responding server */ + if (addr->sin_addr.s_addr == INADDR_ANY) + return(1); + + if (from.sin_addr.s_addr == addr->sin_addr.s_addr) + return(1); + } + + /* matches none of the known addresses */ + return(0); +} + /* ** SEND_STREAM -- Query nameserver via virtual circuit ** --------------------------------------------------- ** ** Returns: -** Length of nameserver answer buffer, if obtained. +** Length of (untruncated) nameserver answer, if obtained. ** -1 if an error occurred. ** +** A new socket is allocated for each call, and it is never +** left open. Checking the packet id is rather redundant. +** ** Note that connect() is the call that is allowed to fail ** under normal circumstances. All other failures generate ** an unconditional error message. @@ -267,6 +310,8 @@ output qbuf_t *answer; /* location of buffer to store answer */ input int anslen; /* maximum size of answer buffer */ { char *host = NULL; /* name of server is unknown */ + HEADER *qp = (HEADER *)query; + HEADER *bp = (HEADER *)answer; register int n; /* @@ -302,6 +347,7 @@ input int anslen; /* maximum size of answer buffer */ /* * Read the answer buffer. */ +wait: n = _res_read(srvsock, addr, host, (char *)answer, anslen); if (n <= 0) { @@ -309,6 +355,19 @@ input int anslen; /* maximum size of answer buffer */ return(-1); } +/* + * Make sure it is the proper response by checking the packet id. + */ + if (qp->id != bp->id) + { + if (bitset(RES_DEBUG, _res.options)) + { + printf("%sunexpected answer:\n", dbprefix); + pr_query(answer, (n > anslen) ? anslen : n, stdout); + } + goto wait; + } + /* * Never leave the socket open. */ @@ -321,7 +380,7 @@ input int anslen; /* maximum size of answer buffer */ ** ------------------------------------------- ** ** Returns: -** Length of nameserver answer buffer, if obtained. +** Length of nameserver answer, if obtained. ** -1 if an error occurred. ** ** Inputs: @@ -403,7 +462,20 @@ wait: if (bitset(RES_DEBUG, _res.options)) { printf("%sold answer:\n", dbprefix); - pr_query(answer, n, stdout); + pr_query(answer, (n > anslen) ? anslen : n, stdout); + } + goto wait; + } + +/* + * Make sure it comes from a known server. + */ + if (!check_from()) + { + if (bitset(RES_DEBUG, _res.options)) + { + printf("%sunknown server %s:\n", dbprefix, inet_ntoa(from.sin_addr)); + pr_query(answer, (n > anslen) ? anslen : n, stdout); } goto wait; } @@ -520,7 +592,7 @@ input int bufsize; /* length of query buffer */ ** ------------------------------------------------------- ** ** Returns: -** Length of buffer if successfully received. +** Length of (untruncated) answer if successfully received. ** -1 in case of failure (error message is issued). ** ** The answer is read in two steps: first a single word which @@ -528,6 +600,10 @@ input int bufsize; /* length of query buffer */ ** If the answer is too long to fit into the supplied buffer, ** only the portion that fits will be stored, the residu will be ** flushed, and the truncation flag will be set. +** +** Note. The returned length is that of the *un*truncated answer, +** however, and not the amount of data that is actually available. +** This may give the caller a hint about new buffer reallocation. */ int @@ -545,7 +621,7 @@ input int bufsize; /* maximum size of answer buffer */ register int n; /* set stream timeout for recv_sock() */ - timeout = 60; + timeout = READTIMEOUT; /* * Read the length of answer buffer. @@ -575,19 +651,21 @@ input int bufsize; /* maximum size of answer buffer */ /* * Check for truncation. + * Do not chop the returned length in case of buffer overflow. */ reslen = 0; if ((int)len > bufsize) { reslen = len - bufsize; - len = bufsize; + /* len = bufsize; */ } /* * Read the answer buffer itself. + * Truncate the answer is the supplied buffer is not big enough. */ buffer = buf; - buflen = len; + buflen = (reslen > 0) ? bufsize : len; while (buflen > 0 && (n = recv_sock(sock, buffer, buflen)) > 0) { @@ -610,12 +688,12 @@ input int bufsize; /* maximum size of answer buffer */ char resbuf[PACKETSZ]; buffer = resbuf; - buflen = reslen < sizeof(resbuf) ? reslen : sizeof(resbuf); + buflen = (reslen < sizeof(resbuf)) ? reslen : sizeof(resbuf); while (reslen > 0 && (n = recv_sock(sock, buffer, buflen)) > 0) { reslen -= n; - buflen = reslen < sizeof(resbuf) ? reslen : sizeof(resbuf); + buflen = (reslen < sizeof(resbuf)) ? reslen : sizeof(resbuf); } if (reslen != 0) @@ -625,7 +703,7 @@ input int bufsize; /* maximum size of answer buffer */ } if (bitset(RES_DEBUG, _res.options)) - printf("%sresponse truncated\n", dbprefix); + printf("%sresponse truncated to %d bytes\n", dbprefix, bufsize); /* set truncation flag */ bp->tc = 1; @@ -641,14 +719,11 @@ input int bufsize; /* maximum size of answer buffer */ ** Returns: ** Length of buffer if successfully received. ** -1 in case of failure or timeout. -** ** Inputs: ** The global variable ``timeout'' should have been ** set with the desired timeout value in seconds. -** ** Outputs: -** Sets global ``from'' to the address from which we -** received the packet. +** Sets ``from'' to the address of the packet sender. */ static int @@ -664,7 +739,7 @@ input int buflen; /* remaining buffer size */ wait.tv_sec = timeout; wait.tv_usec = 0; - +rewait: /* FD_ZERO(&fds); */ bzero((char *)&fds, sizeof(fds)); FD_SET(sock, &fds); @@ -673,14 +748,18 @@ input int buflen; /* remaining buffer size */ n = select(FD_SETSIZE, &fds, (fd_set *)NULL, (fd_set *)NULL, &wait); if (n <= 0) { + if (n < 0 && errno == EINTR) + goto rewait; if (n == 0) errno = ETIMEDOUT; return(-1); } - +reread: /* fake an error if nothing was actually read */ fromlen = sizeof(from); n = recvfrom(sock, buffer, buflen, 0, from_sa, &fromlen); + if (n < 0 && errno == EINTR) + goto reread; if (n == 0) errno = ECONNRESET; return(n); @@ -717,10 +796,12 @@ input int buflen; /* remaining buffer size */ (void) signal(SIGALRM, timer); setalarm(timeout); - +reread: /* fake an error if nothing was actually read */ fromlen = sizeof(from); n = recvfrom(sock, buffer, buflen, 0, from_sa, &fromlen); + if (n < 0 && errno == EINTR) + goto reread; if (n == 0) errno = ECONNRESET; setalarm(0); diff --git a/usr.sbin/named/host/type.h b/usr.sbin/named/host/type.h index 8f1712ec34c..c51285ee7c7 100644 --- a/usr.sbin/named/host/type.h +++ b/usr.sbin/named/host/type.h @@ -1,9 +1,15 @@ +/* $OpenBSD: type.h,v 1.2 1997/03/12 10:41:57 downsj Exp $ */ + /* ** Various new resource record type and class values. ** +** These might be missing in the default files on old platforms. +** Also included are several definitions that might have been +** omitted because they are obsolete, or are otherwise missing. +** ** They belong in ** -** @(#)type.h e07@nikhef.nl (Eric Wassenaar) 941205 +** @(#)type.h e07@nikhef.nl (Eric Wassenaar) 961010 */ /* never used in practice */ @@ -12,12 +18,42 @@ #define C_CSNET 2 #endif +/* missing on some platforms */ + +#ifndef C_CHAOS +#define C_CHAOS 3 +#endif + /* missing in some old versions */ #ifndef C_HS #define C_HS 4 #endif +/* obsolete/deprecated types already missing on some platforms */ + +#ifndef T_MD +#define T_MD 3 +#endif +#ifndef T_MF +#define T_MF 4 +#endif +#ifndef T_MB +#define T_MB 7 +#endif +#ifndef T_MG +#define T_MG 8 +#endif +#ifndef T_MR +#define T_MR 9 +#endif +#ifndef T_NULL +#define T_NULL 10 +#endif +#ifndef T_MINFO +#define T_MINFO 14 +#endif + /* missing in some old versions */ #ifndef T_TXT @@ -29,19 +65,15 @@ #ifndef T_RP #define T_RP 17 #endif - #ifndef T_AFSDB #define T_AFSDB 18 #endif - #ifndef T_X25 #define T_X25 19 #endif - #ifndef T_ISDN #define T_ISDN 20 #endif - #ifndef T_RT #define T_RT 21 #endif @@ -51,17 +83,15 @@ #ifndef T_NSAP #define T_NSAP 22 #endif - #ifndef T_NSAPPTR #define T_NSAPPTR 23 #endif -/* reserved per RFC 1700 */ +/* reserved per RFC 1700, defined per RFC XXXX */ #ifndef T_SIG #define T_SIG 24 #endif - #ifndef T_KEY #define T_KEY 25 #endif @@ -78,14 +108,89 @@ #define T_GPOS 27 #endif -/* reserved per RFC 1700 */ +/* reserved per RFC 1700, defined per RFC 1884 and 1886 */ #ifndef T_AAAA #define T_AAAA 28 #endif -/* defined per RFC XXXX */ +/* defined per RFC 1876 */ #ifndef T_LOC #define T_LOC 29 #endif + +/* defined per RFC XXXX */ + +#ifndef T_NXT +#define T_NXT 30 +#endif + +/* defined per RFC XXXX */ + +#ifndef T_EID +#define T_EID 31 +#endif + +/* defined per RFC XXXX */ + +#ifndef T_NIMLOC +#define T_NIMLOC 32 +#endif + +/* defined per RFC XXXX */ + +#ifndef T_SRV +#define T_SRV 33 +#endif + +/* defined per RFC XXXX */ + +#ifndef T_ATMA +#define T_ATMA 34 +#endif + +/* defined per RFC XXXX */ + +#ifndef T_NAPTR +#define T_NAPTR 35 +#endif + +/* nonstandard types are threatened to become extinct */ + +#ifndef T_UINFO +#define T_UINFO 100 +#endif + +#ifndef T_UID +#define T_UID 101 +#endif + +#ifndef T_GID +#define T_GID 102 +#endif + +#ifndef T_UNSPEC +#define T_UNSPEC 103 +#endif + +/* defined per RFC 1995 */ + +#ifndef T_IXFR +#define T_IXFR 251 +#endif + +/* really missing on some weird platforms, can you believe it */ + +#ifndef T_AXFR +#define T_AXFR 252 +#endif + +/* obsolete/deprecated types already missing on some platforms */ + +#ifndef T_MAILB +#define T_MAILB 253 +#endif +#ifndef T_MAILA +#define T_MAILA 254 +#endif diff --git a/usr.sbin/named/host/vers.c b/usr.sbin/named/host/vers.c index ec39cc4ab09..8c0a19a7e5f 100644 --- a/usr.sbin/named/host/vers.c +++ b/usr.sbin/named/host/vers.c @@ -1,8 +1,10 @@ +/* $OpenBSD: vers.c,v 1.2 1997/03/12 10:41:57 downsj Exp $ */ + #ifndef lint -static char Version[] = "@(#)vers.c e07@nikhef.nl (Eric Wassenaar) 951231"; +static char Version[] = "@(#)vers.c e07@nikhef.nl (Eric Wassenaar) 961113"; #endif -char *version = "951231"; +char *version = "961113"; #if defined(apollo) int h_errno = 0; diff --git a/usr.sbin/named/include/arpa/inet.h b/usr.sbin/named/include/arpa/inet.h new file mode 100644 index 00000000000..d047f8fca6d --- /dev/null +++ b/usr.sbin/named/include/arpa/inet.h @@ -0,0 +1,91 @@ +/* + * ++Copyright++ 1983, 1993 + * - + * Copyright (c) 1983, 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-- + */ + +/* + * @(#)inet.h 8.1 (Berkeley) 6/2/93 + * $Id: inet.h,v 1.1 1997/03/12 10:41:59 downsj Exp $ + */ + +#ifndef _INET_H_ +#define _INET_H_ + +/* External definitions for functions in inet(3) */ + +#include +#if (!defined(BSD)) || (BSD < 199306) +# include +#else +# include +#endif +#include + +__BEGIN_DECLS +unsigned long inet_addr __P((const char *)); +int inet_aton __P((const char *, struct in_addr *)); +unsigned long inet_lnaof __P((struct in_addr)); +struct in_addr inet_makeaddr __P((u_long , u_long)); +char * inet_neta __P((u_long, char *, size_t)); +unsigned long inet_netof __P((struct in_addr)); +unsigned long inet_network __P((const char *)); +char *inet_net_ntop __P((int, const void *, int, char *, size_t)); +int inet_net_pton __P((int, const char *, void *, size_t)); +char *inet_ntoa __P((struct in_addr)); +int inet_pton __P((int, const char *, void *)); +const char *inet_ntop __P((int, const void *, char *, size_t)); +u_int inet_nsap_addr __P((const char *, u_char *, int)); +char *inet_nsap_ntoa __P((int, const u_char *, char *)); +__END_DECLS + +#endif /* !_INET_H_ */ diff --git a/usr.sbin/named/include/arpa/nameser.h b/usr.sbin/named/include/arpa/nameser.h new file mode 100644 index 00000000000..7cf501b37b1 --- /dev/null +++ b/usr.sbin/named/include/arpa/nameser.h @@ -0,0 +1,392 @@ +/* + * ++Copyright++ 1983, 1989, 1993 + * - + * Copyright (c) 1983, 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. + * - + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + * --Copyright-- + */ + +/* + * @(#)nameser.h 8.1 (Berkeley) 6/2/93 + * $Id: nameser.h,v 1.1 1997/03/12 10:42:00 downsj Exp $ + */ + +#ifndef _NAMESER_H_ +#define _NAMESER_H_ + +#include +#if (!defined(BSD)) || (BSD < 199306) +# include +#else +# include +#endif +#include + +#ifdef _AUX_SOURCE +# include +#endif + +/* + * revision information. this is the release date in YYYYMMDD format. + * it can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__BIND > 19931104)". do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __BIND 19960801 /* interface version stamp */ + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 1025 /* maximum presentation domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ +#define HFIXEDSZ 12 /* #/bytes of fixed data in header */ +#define QFIXEDSZ 4 /* #/bytes of fixed data in query */ +#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ +#define INT32SZ 4 /* for systems without 32-bit ints */ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#define INADDRSZ 4 /* IPv4 T_A */ +#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ +/*#define xxx 0x3*/ /* 0x3 reserved */ +#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */ +/* + * Currently defined response codes + */ +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* canonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ +#define T_RP 17 /* responsible person */ +#define T_AFSDB 18 /* AFS cell database */ +#define T_X25 19 /* X_25 calling address */ +#define T_ISDN 20 /* ISDN calling address */ +#define T_RT 21 /* router */ +#define T_NSAP 22 /* NSAP address */ +#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */ +#define T_SIG 24 /* security signature */ +#define T_KEY 25 /* security key */ +#define T_PX 26 /* X.400 mail mapping */ +#define T_GPOS 27 /* geographical position (withdrawn) */ +#define T_AAAA 28 /* IP6 Address */ +#define T_LOC 29 /* Location Information */ +#define T_NXT 30 /* Next Valid Name in Zone */ +#define T_EID 31 /* Endpoint identifier */ +#define T_NIMLOC 32 /* Nimrod locator */ +#define T_SRV 33 /* Server selection */ +#define T_ATMA 34 /* ATM Address */ +#define T_NAPTR 35 /* Naming Authority PoinTeR */ + /* non standard */ +#define T_UINFO 100 /* user (finger) information */ +#define T_UID 101 /* user ID */ +#define T_GID 102 /* group ID */ +#define T_UNSPEC 103 /* Unspecified format (binary data) */ + /* Query type values which do not appear in resource records */ +#define T_IXFR 251 /* incremental zone transfer */ +#define T_AXFR 252 /* transfer zone of authority */ +#define T_MAILB 253 /* transfer mailbox records */ +#define T_MAILA 254 /* transfer mail agent records */ +#define T_ANY 255 /* wildcard match */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +#define C_CHAOS 3 /* for chaos net (MIT) */ +#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */ + /* Query class values which do not appear in resource records */ +#define C_ANY 255 /* wildcard match */ + +/* + * Flags field of the KEY RR rdata + */ +#define KEYFLAG_TYPEMASK 0xC000 /* Mask for "type" bits */ +#define KEYFLAG_TYPE_AUTH_CONF 0x0000 /* Key usable for both */ +#define KEYFLAG_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */ +#define KEYFLAG_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */ +#define KEYFLAG_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */ +/* The type bits can also be interpreted independently, as single bits: */ +#define KEYFLAG_NO_AUTH 0x8000 /* Key not usable for authentication */ +#define KEYFLAG_NO_CONF 0x4000 /* Key not usable for confidentiality */ + +#define KEYFLAG_EXPERIMENTAL 0x2000 /* Security is *mandatory* if bit=0 */ +#define KEYFLAG_RESERVED3 0x1000 /* reserved - must be zero */ +#define KEYFLAG_RESERVED4 0x0800 /* reserved - must be zero */ +#define KEYFLAG_USERACCOUNT 0x0400 /* key is assoc. with a user acct */ +#define KEYFLAG_ENTITY 0x0200 /* key is assoc. with entity eg host */ +#define KEYFLAG_ZONEKEY 0x0100 /* key is zone key for the zone named */ +#define KEYFLAG_IPSEC 0x0080 /* key is for IPSEC use (host or user)*/ +#define KEYFLAG_EMAIL 0x0040 /* key is for email (MIME security) */ +#define KEYFLAG_RESERVED10 0x0020 /* reserved - must be zero */ +#define KEYFLAG_RESERVED11 0x0010 /* reserved - must be zero */ +#define KEYFLAG_SIGNATORYMASK 0x000F /* key can sign DNS RR's of same name */ + +#define KEYFLAG_RESERVED_BITMASK ( KEYFLAG_RESERVED3 | \ + KEYFLAG_RESERVED4 | \ + KEYFLAG_RESERVED10| KEYFLAG_RESERVED11) + +/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ +#define ALGORITHM_MD5RSA 1 /* MD5 with RSA */ +#define ALGORITHM_EXPIRE_ONLY 253 /* No alg, no security */ +#define ALGORITHM_PRIVATE_OID 254 /* Key begins with OID indicating alg */ + +/* Signatures */ + /* Size of a mod or exp in bits */ +#define MIN_MD5RSA_KEY_PART_BITS 512 +#define MAX_MD5RSA_KEY_PART_BITS 2552 + /* Total of binary mod and exp, bytes */ +#define MAX_MD5RSA_KEY_BYTES ((MAX_MD5RSA_KEY_PART_BITS+7/8)*2+3) + /* Max length of text sig block */ +#define MAX_KEY_BASE64 (((MAX_MD5RSA_KEY_BYTES+2)/3)*4) + +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW (-1) +#define CONV_BADFMT (-2) +#define CONV_BADCKSUM (-3) +#define CONV_BADBUFLEN (-4) + +#ifndef BYTE_ORDER +#if (BSD >= 199103) +# include +#else +#ifdef linux +# include +#else +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/ + +#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ + defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ + defined(__alpha__) || defined(__alpha) +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ + defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ + defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ + defined(apollo) || defined(__convex__) || defined(_CRAY) || \ + defined(__hppa) || defined(__hp9000) || \ + defined(__hp9000s300) || defined(__hp9000s700) || \ + defined (BIT_ZERO_ON_LEFT) || defined(m68k) +#define BYTE_ORDER BIG_ENDIAN +#endif +#endif /* linux */ +#endif /* BSD */ +#endif /* BYTE_ORDER */ + +#if !defined(BYTE_ORDER) || \ + (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \ + BYTE_ORDER != PDP_ENDIAN) + /* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ + error "Undefined or invalid BYTE_ORDER"; +#endif + +/* + * Structure for query header. The order of the fields is machine- and + * compiler-dependent, depending on the byte/bit order and the layout + * of bit fields. We use bit fields only in int variables, as this + * is all ANSI requires. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + unsigned id :16; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /* response flag */ + unsigned opcode: 4; /* purpose of message */ + unsigned aa: 1; /* authoritive answer */ + unsigned tc: 1; /* truncated message */ + unsigned rd: 1; /* recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /* recursion available */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /* authentic data from named */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned rcode :4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /* recursion desired */ + unsigned tc :1; /* truncated message */ + unsigned aa :1; /* authoritive answer */ + unsigned opcode :4; /* purpose of message */ + unsigned qr :1; /* response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /* response code */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned ad: 1; /* authentic data from named */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /* recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /* number of question entries */ + unsigned ancount :16; /* number of answer entries */ + unsigned nscount :16; /* number of authority entries */ + unsigned arcount :16; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +extern u_int16_t _getshort __P((const u_char *)); +extern u_int32_t _getlong __P((const u_char *)); + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} + +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} + +#define PUTSHORT(s, cp) { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += INT16SZ; \ +} + +#define PUTLONG(l, cp) { \ + register u_int32_t t_l = (u_int32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += INT32SZ; \ +} + +#endif /* !_NAMESER_H_ */ diff --git a/usr.sbin/named/include/netdb.h b/usr.sbin/named/include/netdb.h new file mode 100644 index 00000000000..3c325c07f14 --- /dev/null +++ b/usr.sbin/named/include/netdb.h @@ -0,0 +1,170 @@ +/* + * ++Copyright++ 1980, 1983, 1988, 1993 + * - + * Copyright (c) 1980, 1983, 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-- + */ + +/* + * @(#)netdb.h 8.1 (Berkeley) 6/2/93 + * $Id: netdb.h,v 1.1 1997/03/12 10:41:58 downsj Exp $ + */ + +#ifndef _NETDB_H_ +#define _NETDB_H_ + +#include +#if (!defined(BSD)) || (BSD < 199306) +# include +#endif +#include + +#define _PATH_HEQUIV "/etc/hosts.equiv" +#define _PATH_HOSTS "/etc/hosts" +#define _PATH_NETWORKS "/etc/networks" +#define _PATH_PROTOCOLS "/etc/protocols" +#define _PATH_SERVICES "/etc/services" + +extern int h_errno; + +/* + * Structures returned by network data base library. All addresses are + * supplied in host order, and returned in network order (suitable for + * use in system calls). + */ +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 compatiblity */ +}; + +/* + * Assumption here is that a network number + * fits in an unsigned long -- probably a poor one. + */ +struct netent { + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + int n_addrtype; /* net address type */ + unsigned long n_net; /* network # */ +}; + +struct servent { + char *s_name; /* official service name */ + char **s_aliases; /* alias list */ + int s_port; /* port # */ + char *s_proto; /* protocol to use */ +}; + +struct protoent { + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + int p_proto; /* protocol # */ +}; + +/* + * Error return codes from gethostbyname() and gethostbyaddr() + * (left in extern int h_errno). + */ + +#define NETDB_INTERNAL -1 /* see errno */ +#define NETDB_SUCCESS 0 /* no problem */ +#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ +#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ +#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ +#define NO_DATA 4 /* Valid name, no data record of requested type */ +#define NO_ADDRESS NO_DATA /* no address, look for MX record */ + +__BEGIN_DECLS +void endhostent __P((void)); +void endnetent __P((void)); +void endprotoent __P((void)); +void endservent __P((void)); +struct hostent *gethostbyaddr __P((const char *, int, int)); +struct hostent *gethostbyname __P((const char *)); +struct hostent *gethostbyname2 __P((const char *, int)); +struct hostent *gethostent __P((void)); +struct netent *getnetbyaddr __P((unsigned long, int)); +struct netent *getnetbyname __P((const char *)); +struct netent *getnetent __P((void)); +struct protoent *getprotobyname __P((const char *)); +struct protoent *getprotobynumber __P((int)); +struct protoent *getprotoent __P((void)); +struct servent *getservbyname __P((const char *, const char *)); +struct servent *getservbyport __P((int, const char *)); +struct servent *getservent __P((void)); +void herror __P((const char *)); +const char *hstrerror __P((int)); +void sethostent __P((int)); +/* void sethostfile __P((const char *)); */ +void setnetent __P((int)); +void setprotoent __P((int)); +void setservent __P((int)); +__END_DECLS + +/* This is nec'y to make this include file properly replace the sun version. */ +#ifdef sun +#ifdef __GNU_LIBRARY__ +#include +#else +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + int r_number; /* rpc program number */ +}; +struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent(); +#endif /* __GNU_LIBRARY__ */ +#endif /* sun */ + +#endif /* !_NETDB_H_ */ diff --git a/usr.sbin/named/include/resolv.h b/usr.sbin/named/include/resolv.h new file mode 100644 index 00000000000..88bb3e02dc2 --- /dev/null +++ b/usr.sbin/named/include/resolv.h @@ -0,0 +1,296 @@ +/* + * ++Copyright++ 1983, 1987, 1989, 1993 + * - + * Copyright (c) 1983, 1987, 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-- + */ + +/* + * @(#)resolv.h 8.1 (Berkeley) 6/2/93 + * $Id: resolv.h,v 1.1 1997/03/12 10:41:59 downsj Exp $ + */ + +#ifndef _RESOLV_H_ +#define _RESOLV_H_ + +#include +#if (!defined(BSD)) || (BSD < 199306) +# include +#else +# include +#endif +#include +#include + +/* + * Revision information. This is the release date in YYYYMMDD format. + * It can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__RES > 19931104)". Do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __RES 19960801 + +/* + * Resolver configuration file. + * Normally not present, but may contain the address of the + * inital name server(s) to query and the domain search list. + */ + +#ifndef _PATH_RESCONF +#define _PATH_RESCONF "/etc/resolv.conf" +#endif + +/* + * Global defines and variables for resolver stub. + */ +#define MAXNS 3 /* max # name servers we'll track */ +#define MAXDFLSRCH 3 /* # default domain levels to try */ +#define MAXDNSRCH 6 /* max # domains in search path */ +#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ + +#define RES_TIMEOUT 5 /* min. seconds between retries */ +#define MAXRESOLVSORT 10 /* number of net to sort on */ +#define RES_MAXNDOTS 15 /* should reflect bit field size */ + +struct __res_state { + int retrans; /* retransmition time interval */ + int retry; /* number of times to retransmit */ + u_long options; /* option flags - see below. */ + int nscount; /* number of name servers */ + struct sockaddr_in + nsaddr_list[MAXNS]; /* address of name server */ +#define nsaddr nsaddr_list[0] /* for backward compatibility */ + u_short id; /* current message id */ + char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ + char defdname[256]; /* default domain (deprecated) */ + u_long pfcode; /* RES_PRF_ flags - see below. */ + unsigned ndots:4; /* threshold for initial abs. query */ + unsigned nsort:4; /* number of elements in sort_list[] */ + char unused[3]; + struct { + struct in_addr addr; + u_int32_t mask; + } sort_list[MAXRESOLVSORT]; + char pad[72]; /* on an i386 this means 512b total */ +}; + +/* + * Resolver options (keep these in synch with res_debug.c, please) + */ +#define RES_INIT 0x00000001 /* address initialized */ +#define RES_DEBUG 0x00000002 /* print debug messages */ +#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/ +#define RES_USEVC 0x00000008 /* use virtual circuit */ +#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */ +#define RES_IGNTC 0x00000020 /* ignore trucation errors */ +#define RES_RECURSE 0x00000040 /* recursion desired */ +#define RES_DEFNAMES 0x00000080 /* use default domain name */ +#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */ +#define RES_DNSRCH 0x00000200 /* search up local domain tree */ +#define RES_INSECURE1 0x00000400 /* type 1 security disabled */ +#define RES_INSECURE2 0x00000800 /* type 2 security disabled */ +#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */ +#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */ + +#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) + +/* + * Resolver "pfcode" values. Used by dig. + */ +#define RES_PRF_STATS 0x00000001 +/* 0x00000002 */ +#define RES_PRF_CLASS 0x00000004 +#define RES_PRF_CMD 0x00000008 +#define RES_PRF_QUES 0x00000010 +#define RES_PRF_ANS 0x00000020 +#define RES_PRF_AUTH 0x00000040 +#define RES_PRF_ADD 0x00000080 +#define RES_PRF_HEAD1 0x00000100 +#define RES_PRF_HEAD2 0x00000200 +#define RES_PRF_TTLID 0x00000400 +#define RES_PRF_HEADX 0x00000800 +#define RES_PRF_QUERY 0x00001000 +#define RES_PRF_REPLY 0x00002000 +#define RES_PRF_INIT 0x00004000 +/* 0x00008000 */ + +/* hooks are still experimental as of 4.9.2 */ +typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error } + res_sendhookact; + +typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns, + const u_char **query, + int *querylen, + u_char *ans, + int anssiz, + int *resplen)); + +typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns, + const u_char *query, + int querylen, + u_char *ans, + int anssiz, + int *resplen)); + +struct res_sym { + int number; /* Identifying number, like T_MX */ + char * name; /* Its symbolic name, like "MX" */ + char * humanname; /* Its fun name, like "mail exchanger" */ +}; + +extern struct __res_state _res; +extern const struct res_sym __p_class_syms[]; +extern const struct res_sym __p_type_syms[]; + +/* Private routines shared between libc/net, named, nslookup and others. */ +#define res_hnok __res_hnok +#define res_ownok __res_ownok +#define res_mailok __res_mailok +#define res_dnok __res_dnok +#define sym_ston __sym_ston +#define sym_ntos __sym_ntos +#define sym_ntop __sym_ntop +#define b64_ntop __b64_ntop +#define b64_pton __b64_pton +#define loc_ntoa __loc_ntoa +#define loc_aton __loc_aton +#define dn_skipname __dn_skipname +#define fp_resstat __fp_resstat +#define fp_query __fp_query +#define fp_nquery __fp_nquery +#define hostalias __hostalias +#define putlong __putlong +#define putshort __putshort +#define p_class __p_class +#define p_time __p_time +#define p_type __p_type +#define p_query __p_query +#define p_cdnname __p_cdnname +#define p_cdname __p_cdname +#define p_fqnname __p_fqnname +#define p_fqname __p_fqname +#define p_rr __p_rr +#define p_option __p_option +#define p_secstodate __p_secstodate +#define dn_count_labels __dn_count_labels +#define dn_comp __dn_comp +#define res_randomid __res_randomid +#define res_send __res_send +#define res_isourserver __res_isourserver +#define res_nameinquery __res_nameinquery +#define res_queriesmatch __res_queriesmatch +#define res_close __res_close + +#ifdef BIND_RES_POSIX3 +#define dn_expand __dn_expand +#define res_init __res_init +#define res_query __res_query +#define res_search __res_search +#define res_querydomain __res_querydomain +#define res_mkquery __res_mkquery +#endif + +__BEGIN_DECLS +int res_hnok __P((const char *)); +int res_ownok __P((const char *)); +int res_mailok __P((const char *)); +int res_dnok __P((const char *)); +int sym_ston __P((const struct res_sym *, char *, int *)); +const char * sym_ntos __P((const struct res_sym *, int, int *)); +const char * sym_ntop __P((const struct res_sym *, int, int *)); +int b64_ntop __P((u_char const *, size_t, char *, size_t)); +int b64_pton __P((char const *, u_char *, size_t)); +int loc_aton __P((const char *, u_char *)); +const char * loc_ntoa __P((const u_char *, char *)); +int dn_skipname __P((const u_char *, const u_char *)); +void fp_resstat __P((struct __res_state *, FILE *)); +void fp_query __P((const u_char *, FILE *)); +void fp_nquery __P((const u_char *, int, FILE *)); +const char * hostalias __P((const char *)); +void putlong __P((u_int32_t, u_char *)); +void putshort __P((u_int16_t, u_char *)); +const char * p_class __P((int)); +const char * p_time __P((u_int32_t)); +const char * p_type __P((int)); +void p_query __P((const u_char *)); +const u_char * p_cdnname __P((const u_char *, const u_char *, int, FILE *)); +const u_char * p_cdname __P((const u_char *, const u_char *, FILE *)); +const u_char * p_fqnname __P((const u_char *cp, const u_char *msg, + int, char *, int)); +const u_char * p_fqname __P((const u_char *, const u_char *, FILE *)); +const u_char * p_rr __P((const u_char *, const u_char *, FILE *)); +const char * p_option __P((u_long option)); +char * p_secstodate __P((u_long)); +int dn_count_labels __P((char *)); +int dn_comp __P((const char *, u_char *, int, + u_char **, u_char **)); +int dn_expand __P((const u_char *, const u_char *, const u_char *, + char *, int)); +int res_init __P((void)); +u_int res_randomid __P((void)); +int res_query __P((const char *, int, int, u_char *, int)); +int res_search __P((const char *, int, int, u_char *, int)); +int res_querydomain __P((const char *, const char *, int, int, + u_char *, int)); +int res_mkquery __P((int, const char *, int, int, const u_char *, int, + const u_char *, u_char *, int)); +int res_send __P((const u_char *, int, u_char *, int)); +int res_isourserver __P((const struct sockaddr_in *)); +int res_nameinquery __P((const char *, int, int, + const u_char *, const u_char *)); +int res_queriesmatch __P((const u_char *, const u_char *, + const u_char *, const u_char *)); +void res_close __P((void)); +__END_DECLS + +#endif /* !_RESOLV_H_ */ diff --git a/usr.sbin/named/libresolv/Makefile b/usr.sbin/named/libresolv/Makefile new file mode 100644 index 00000000000..cc24f2d2573 --- /dev/null +++ b/usr.sbin/named/libresolv/Makefile @@ -0,0 +1,20 @@ +# $OpenBSD: Makefile,v 1.1 1997/03/12 10:42:01 downsj Exp $ + +LIB= resolv +SRCS= base64.c gethnamaddr.c getnetbyaddr.c getnetbyname.c getnetent.c \ + getnetnamadr.c herror.c hostnamelen.c inet_addr.c inet_net_ntop.c \ + inet_net_pton.c inet_neta.c inet_ntop.c inet_pton.c nsap_addr.c \ + res_comp.c res_data.c res_debug.c res_init.c res_mkquery.c \ + res_query.c res_send.c sethostent.c + +CFLAGS+=${INCLUDE} ${CONFIG} + +# we don't build the other copies of this library +NOPIC=yes +NOPROFILE=yes + +# we don't install this version of the library +install: + +.include +.include "../Makefile.inc" diff --git a/usr.sbin/named/libresolv/Makefile.dist b/usr.sbin/named/libresolv/Makefile.dist new file mode 100644 index 00000000000..f201815d9f8 --- /dev/null +++ b/usr.sbin/named/libresolv/Makefile.dist @@ -0,0 +1,116 @@ +# $OpenBSD: Makefile.dist,v 1.1 1997/03/12 10:42:01 downsj Exp $ +# +# from @(#)Makefile 5.16 (Berkeley) 3/14/88 +# $From: Makefile,v 8.13 1996/08/08 22:49:48 vixie Exp $ +# + +## ++Copyright++ 1988, 1995 +## - +## Copyright (c) 1988, 1995 +## 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-- + +DESTDIR = +DESTLIB = /usr/lib +CC= cc +SHELL= /bin/sh +CDEBUG= -g +INCL = ../include +COMPINCL = ../compat/include +AR= ar cru +RANLIB= ranlib +DEFS= +LOCDEFS= -DUSE_OPTIONS_H +INSTALL= install + +AROBJS= ${ARPREF} ${OBJS} ${ARSUFF} + +CFLAGS= ${CDEBUG} -I${INCL} -I${COMPINCL} ${DEFS} ${LOCDEFS} + +SRCS= base64.c herror.c res_debug.c res_data.c \ + res_comp.c res_init.c res_mkquery.c res_query.c res_send.c \ + getnetbyaddr.c getnetbyname.c getnetent.c getnetnamadr.c \ + gethnamaddr.c sethostent.c nsap_addr.c hostnamelen.c inet_addr.c \ + inet_ntop.c inet_neta.c inet_pton.c inet_net_ntop.c inet_net_pton.c + +OBJS= base64.o herror.o res_debug.o res_data.o \ + res_comp.o res_init.o res_mkquery.o res_query.o res_send.o \ + getnetbyaddr.o getnetbyname.o getnetent.o getnetnamadr.o \ + gethnamaddr.o sethostent.o nsap_addr.o hostnamelen.o inet_addr.o \ + inet_ntop.o inet_neta.o inet_pton.o inet_net_ntop.o inet_net_pton.o + +all: libresolv.a + +libresolv.a: ${OBJS} + ${AR} libresolv.a ${AROBJS} + $(RANLIB) libresolv.a + +install: ${DESTDIR}${DESTLIB}/libresolv.a + +${DESTDIR}${DESTLIB}/libresolv.a: libresolv.a + ${INSTALL} -c -o bin -g bin -m 644 libresolv.a ${DESTDIR}${DESTLIB}/ + ( cd ${DESTDIR}${DESTLIB} ; $(RANLIB) libresolv.a ) + +.c.o: + ${CC} ${CFLAGS} -c $*.c + -${LDS} ld -x -r $*.o + ${LDS} mv a.out $*.o + +clean: FRC + rm -f errs a.out core libresolv.a tags .depend + rm -f *.o *.BAK *.CKP *~ *.orig + +depend: FRC + mkdep ${CPPFLAGS} -I${INCL} -I${COMPINCL} ${DEFS} ${SRCS} + +FRC: + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/usr.sbin/named/libresolv/base64.c b/usr.sbin/named/libresolv/base64.c new file mode 100644 index 00000000000..3172b20a73c --- /dev/null +++ b/usr.sbin/named/libresolv/base64.c @@ -0,0 +1,323 @@ +/* $OpenBSD: base64.c,v 1.1 1997/03/12 10:42:01 downsj Exp $ */ + +/* + * 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. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) +# include +# include +#else +# include "../conf/portability.h" +#endif + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(src, srclength, target, targsize) + u_char const *src; + size_t srclength; + char *target; + size_t targsize; +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(src, target, targsize) + char const *src; + u_char *target; + size_t targsize; +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + default: + abort(); + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/usr.sbin/named/libresolv/gethnamaddr.c b/usr.sbin/named/libresolv/gethnamaddr.c new file mode 100644 index 00000000000..aa93b257643 --- /dev/null +++ b/usr.sbin/named/libresolv/gethnamaddr.c @@ -0,0 +1,967 @@ +/* $OpenBSD: gethnamaddr.c,v 1.1 1997/03/12 10:42:02 downsj Exp $ */ + +/* + * ++Copyright++ 1985, 1988, 1993 + * - + * 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 + * 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) +#if 0 +static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$From: gethnamaddr.c,v 8.20 1996/09/28 06:51:07 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: gethnamaddr.c,v 1.1 1997/03/12 10:42:02 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifndef LOG_AUTH +# define LOG_AUTH 0 +#endif + +#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */ + +#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) +# include +# include +#else +# include "../conf/portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include <../conf/options.h> +#endif + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +#define MAXALIASES 35 +#define MAXADDRS 35 + +static const char AskedForGot[] = + "gethostby*.getanswer: asked for \"%s\", got \"%s\""; + +static char *h_addr_ptrs[MAXADDRS + 1]; + +static struct hostent host; +static char *host_aliases[MAXALIASES]; +static char hostbuf[8*1024]; +static u_char host_addr[16]; /* IPv4 or IPv6 */ +static FILE *hostf = NULL; +static int stayopen = 0; + +static void map_v4v6_address __P((const char *src, char *dst)); +static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len)); + +#ifdef RESOLVSORT +static void addrsort __P((char **, int)); +#endif + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +typedef union { + int32_t al; + char ac; +} align; + +extern int h_errno; + +#ifdef DEBUG +static void +dprintf(msg, num) + char *msg; + int num; +{ + if (_res.options & RES_DEBUG) { + int save = errno; + + printf(msg, num); + errno = save; + } +} +#else +# define dprintf(msg, num) /*nada*/ +#endif + +static struct hostent * +getanswer(answer, anslen, qname, qtype) + const querybuf *answer; + int anslen; + const char *qname; + int qtype; +{ + register const HEADER *hp; + register const u_char *cp; + register int n; + const u_char *eom; + char *bp, **ap, **hap; + int type, class, buflen, ancount, qdcount; + int haveanswer, had_error; + int toobig = 0; + char tbuf[MAXDNAME]; + 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: + return (NULL); /* XXX should be abort(); */ + } + /* + * find first satisfactory answer + */ + hp = &answer->hdr; + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + bp = hostbuf; + buflen = sizeof hostbuf; + cp = answer->buf + HFIXEDSZ; + if (qdcount != 1) { + h_errno = NO_RECOVERY; + return (NULL); + } + 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 || 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). + */ + n = strlen(bp) + 1; /* for the \0 */ + host.h_name = bp; + bp += n; + buflen -= n; + /* The qname can be abbreviated, but h_name is now absolute. */ + qname = host.h_name; + } + ap = host_aliases; + *ap = NULL; + host.h_aliases = host_aliases; + hap = h_addr_ptrs; + *hap = NULL; + host.h_addr_list = h_addr_ptrs; + haveanswer = 0; + had_error = 0; + while (ancount-- > 0 && cp < eom && !had_error) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !(*name_ok)(bp)) { + had_error++; + continue; + } + cp += n; /* name */ + type = _getshort(cp); + cp += INT16SZ; /* type */ + class = _getshort(cp); + cp += INT16SZ + INT32SZ; /* class, TTL */ + n = _getshort(cp); + cp += INT16SZ; /* len */ + if (class != C_IN) { + /* XXX - debug? syslog? */ + cp += n; + continue; /* XXX - had_error++ ? */ + } + 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) || !(*name_ok)(tbuf)) { + had_error++; + continue; + } + cp += n; + /* Store alias. */ + *ap++ = bp; + n = strlen(bp) + 1; /* for the \0 */ + bp += n; + buflen -= n; + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ + if (n > buflen) { + had_error++; + continue; + } + strcpy(bp, tbuf); + host.h_name = bp; + bp += n; + buflen -= n; + continue; + } + if (qtype == T_PTR && type == T_CNAME) { + n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); + if ((n < 0) || !res_hnok(tbuf)) { + had_error++; + continue; + } + cp += n; + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ + if (n > buflen) { + had_error++; + continue; + } + strcpy(bp, tbuf); + tname = bp; + bp += n; + buflen -= n; + continue; + } + if (type != qtype) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", + qname, p_class(C_IN), p_type(qtype), + p_type(type)); + cp += n; + continue; /* XXX - had_error++ ? */ + } + switch (type) { + case T_PTR: + if (strcasecmp(tname, bp) != 0) { + syslog(LOG_NOTICE|LOG_AUTH, + AskedForGot, qname, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !res_hnok(bp)) { + had_error++; + break; + } +#if MULTI_PTRS_ARE_ALIASES + cp += n; + if (!haveanswer) + host.h_name = bp; + else if (ap < &host_aliases[MAXALIASES-1]) + *ap++ = bp; + else + n = -1; + if (n != -1) { + n = strlen(bp) + 1; /* for the \0 */ + bp += n; + buflen -= n; + } + 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); + cp += n; + continue; /* XXX - had_error++ ? */ + } + if (n != host.h_length) { + cp += n; + continue; + } + if (!haveanswer) { + register int nn; + + host.h_name = bp; + nn = strlen(bp) + 1; /* for the \0 */ + bp += nn; + buflen -= nn; + } + + bp += sizeof(align) - ((u_long)bp % sizeof(align)); + + if (bp + n >= &hostbuf[sizeof hostbuf]) { + dprintf("size (%d) too big\n", n); + had_error++; + continue; + } + if (hap >= &h_addr_ptrs[MAXADDRS-1]) { + if (!toobig++) + dprintf("Too many addresses (%d)\n", + MAXADDRS); + cp += n; + continue; + } + bcopy(cp, *hap++ = bp, n); + bp += n; + buflen -= n; + cp += n; + break; + default: + abort(); + } + if (!had_error) + haveanswer++; + } + if (haveanswer) { + *ap = NULL; + *hap = NULL; +# if defined(RESOLVSORT) + /* + * Note: we sort even if host can take only one address + * in its return structures - should give it the "best" + * address in that case, not some random one + */ + if (_res.nsort && haveanswer > 1 && qtype == T_A) + addrsort(h_addr_ptrs, haveanswer); +# endif /*RESOLVSORT*/ + 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); + } + try_again: + h_errno = TRY_AGAIN; + return (NULL); +} + +struct hostent * +gethostbyname(name) + const char *name; +{ + struct hostent *hp; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + if (_res.options & RES_USE_INET6) { + hp = gethostbyname2(name, AF_INET6); + if (hp) + return (hp); + } + return (gethostbyname2(name, AF_INET)); +} + +struct hostent * +gethostbyname2(name, af) + const char *name; + int af; +{ + querybuf buf; + register const char *cp; + char *bp; + int n, size, type, len; + extern struct hostent *_gethtbyname2(); + + 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 + * function that looks up host names. + */ + if (!strchr(name, '.') && (cp = __hostalias(name))) + name = cp; + + /* + * disallow names consisting only of digits/dots, unless + * they end in a dot. + */ + if (isdigit(name[0])) + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-numeric, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (inet_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; + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; + host.h_addr_list = h_addr_ptrs; + if (_res.options & RES_USE_INET6) + map_v4v6_hostent(&host, &bp, &len); + h_errno = NETDB_SUCCESS; + return (&host); + } + if (!isdigit(*cp) && *cp != '.') + break; + } + if (isxdigit(name[0]) || name[0] == ':') + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-IPv6-legal, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + 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; + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; + host.h_addr_list = h_addr_ptrs; + h_errno = NETDB_SUCCESS; + return (&host); + } + if (!isxdigit(*cp) && *cp != ':' && *cp != '.') + break; + } + + if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { + dprintf("res_search failed (%d)\n", n); + if (errno == ECONNREFUSED) + return (_gethtbyname2(name, af)); + return (NULL); + } + return (getanswer(&buf, n, name, type)); +} + +struct hostent * +gethostbyaddr(addr, len, af) + const char *addr; /* XXX should have been def'd as u_char! */ + int len, af; +{ + 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], *qp; +#ifdef SUNSECURITY + register struct hostent *rhp; + char **haddr; + u_long old_options; + char hname2[MAXDNAME+1]; +#endif /*SUNSECURITY*/ + extern struct hostent *_gethtbyaddr(); + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + 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); + } + 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); + if (errno == ECONNREFUSED) + return (_gethtbyaddr(addr, len, af)); + return (NULL); + } + if (!(hp = getanswer(&buf, n, qbuf, T_PTR))) + return (NULL); /* h_errno was set by getanswer() */ +#ifdef SUNSECURITY + 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++) + if (!memcmp(*haddr, addr, INADDRSZ)) + break; + 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 = af; + hp->h_length = len; + bcopy(addr, host_addr, len); + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; + 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); +} + +void +_sethtent(f) + int f; +{ + if (!hostf) + hostf = fopen(_PATH_HOSTS, "r" ); + else + rewind(hostf); + stayopen = f; +} + +void +_endhtent() +{ + if (hostf && !stayopen) { + (void) fclose(hostf); + hostf = NULL; + } +} + +struct hostent * +_gethtent() +{ + char *p; + register char *cp, **q; + int af, len; + + if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + again: + if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + if (*p == '#') + goto again; + if (!(cp = strpbrk(p, "#\n"))) + goto again; + *cp = '\0'; + if (!(cp = strpbrk(p, " \t"))) + goto again; + *cp++ = '\0'; + 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[1] = NULL; + host.h_addr_list = h_addr_ptrs; + 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")) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &host_aliases[MAXALIASES - 1]) + *q++ = cp; + 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 * +_gethtbyname(name) + const char *name; +{ + extern struct hostent *_gethtbyname2(); + struct hostent *hp; + + if (_res.options & RES_USE_INET6) { + hp = _gethtbyname2(name, AF_INET6); + if (hp) + return (hp); + } + return (_gethtbyname2(name, AF_INET)); +} + +struct hostent * +_gethtbyname2(name, af) + const char *name; + int af; +{ + register struct hostent *p; + register char **cp; + + _sethtent(0); + while (p = _gethtent()) { + if (p->h_addrtype != af) + continue; + if (strcasecmp(p->h_name, name) == 0) + break; + for (cp = p->h_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } + found: + _endhtent(); + return (p); +} + +struct hostent * +_gethtbyaddr(addr, len, af) + const char *addr; + int len, af; +{ + register struct hostent *p; + + _sethtent(0); + while (p = _gethtent()) + if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len)) + break; + _endhtent(); + return (p); +} + +static 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); +} + +static void +map_v4v6_hostent(hp, bpp, lenp) + struct hostent *hp; + char **bpp; + int *lenp; +{ + char **ap; + + 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)); + + 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; + } +} + +#ifdef RESOLVSORT +static void +addrsort(ap, num) + char **ap; + int num; +{ + int i, j; + char **p; + short aval[MAXADDRS]; + int needsort = 0; + + p = ap; + for (i = 0; i < num; i++, p++) { + for (j = 0 ; (unsigned)j < _res.nsort; j++) + if (_res.sort_list[j].addr.s_addr == + (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) + break; + aval[i] = j; + if (needsort == 0 && i > 0 && j < aval[i-1]) + needsort = i; + } + if (!needsort) + return; + + while (needsort < num) { + for (j = needsort - 1; j >= 0; j--) { + if (aval[j] > aval[j+1]) { + char *hp; + + i = aval[j]; + aval[j] = aval[j+1]; + aval[j+1] = i; + + hp = ap[j]; + ap[j] = ap[j+1]; + ap[j+1] = hp; + + } else + break; + } + needsort++; + } +} +#endif + +#if defined(BSD43_BSD43_NFS) || defined(sun) +/* some libc's out there are bound internally to these names (UMIPS) */ +void +ht_sethostent(stayopen) + int stayopen; +{ + _sethtent(stayopen); +} + +void +ht_endhostent() +{ + _endhtent(); +} + +struct hostent * +ht_gethostbyname(name) + char *name; +{ + return (_gethtbyname(name)); +} + +struct hostent * +ht_gethostbyaddr(addr, len, af) + const char *addr; + int len, af; +{ + return (_gethtbyaddr(addr, len, af)); +} + +struct hostent * +gethostent() +{ + return (_gethtent()); +} + +void +dns_service() +{ + return; +} + +#undef dn_skipname +dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + return (__dn_skipname(comp_dn, eom)); +} +#endif /*old-style libc with yp junk in it*/ diff --git a/usr.sbin/named/libresolv/getnetbyaddr.c b/usr.sbin/named/libresolv/getnetbyaddr.c new file mode 100644 index 00000000000..450bc45be56 --- /dev/null +++ b/usr.sbin/named/libresolv/getnetbyaddr.c @@ -0,0 +1,63 @@ +/* $OpenBSD: getnetbyaddr.c,v 1.1 1997/03/12 10:42:02 downsj Exp $ */ + +/* + * Copyright (c) 1983 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)getnetbyaddr.c 1.1 (Coimbra) 93/06/02"; +static char rcsid[] = "$From: getnetbyaddr.c,v 8.2 1996/05/09 05:59:13 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: getnetbyaddr.c,v 1.1 1997/03/12 10:42:02 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include + +extern int _net_stayopen; + +struct netent * +_getnetbyaddr(net, type) + register unsigned long net; + register int type; +{ + register struct netent *p; + + setnetent(_net_stayopen); + while (p = getnetent()) + if (p->n_addrtype == type && p->n_net == net) + break; + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/usr.sbin/named/libresolv/getnetbyname.c b/usr.sbin/named/libresolv/getnetbyname.c new file mode 100644 index 00000000000..90e45ecc27e --- /dev/null +++ b/usr.sbin/named/libresolv/getnetbyname.c @@ -0,0 +1,70 @@ +/* $OpenBSD: getnetbyname.c,v 1.1 1997/03/12 10:42:03 downsj Exp $ */ + +/* + * Copyright (c) 1983, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93"; +static char sccsid_[] = "from getnetbyname.c 1.1 (Coimbra) 93/06/02"; +static char rcsid[] = "$From: getnetbyname.c,v 8.2 1995/06/19 08:35:01 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: getnetbyname.c,v 1.1 1997/03/12 10:42:03 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +extern int _net_stayopen; + +struct netent * +_getnetbyname(name) + register const char *name; +{ + register struct netent *p; + register char **cp; + + setnetent(_net_stayopen); + while (p = getnetent()) { + if (strcasecmp(p->n_name, name) == 0) + break; + for (cp = p->n_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } +found: + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/usr.sbin/named/libresolv/getnetent.c b/usr.sbin/named/libresolv/getnetent.c new file mode 100644 index 00000000000..b80ada5f94b --- /dev/null +++ b/usr.sbin/named/libresolv/getnetent.c @@ -0,0 +1,169 @@ +/* $OpenBSD: getnetent.c,v 1.1 1997/03/12 10:42:03 downsj Exp $ */ + +/* + * Copyright (c) 1983 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 Carlos Leandro and Rui Salgueiro + * Dep. Matematica Universidade de Coimbra, Portugal, Europe + * + * 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. + * + * from getnetent.c 1.1 (Coimbra) 93/06/02 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$From: getnetent.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: getnetent.c,v 1.1 1997/03/12 10:42:03 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef _PATH_NETWORKS +#define _PATH_NETWORKS "/etc/networks" +#endif + +#define MAXALIASES 35 + +static FILE *netf; +static char line[BUFSIZ+1]; +static struct netent net; +static char *net_aliases[MAXALIASES]; +int _net_stayopen; + +void _setnetent __P((int)); +void _endnetent __P((void)); + +void +setnetent(stayopen) + int stayopen; +{ + + sethostent(stayopen); + _setnetent(stayopen); +} + +void +endnetent() +{ + + endhostent(); + _endnetent(); +} + +void +_setnetent(f) + int f; +{ + + if (netf == NULL) + netf = fopen(_PATH_NETWORKS, "r" ); + else + rewind(netf); + _net_stayopen |= f; +} + +void +_endnetent() +{ + + if (netf) { + fclose(netf); + netf = NULL; + } + _net_stayopen = 0; +} + +struct netent * +getnetent() +{ + char *p; + register char *cp, **q; + + if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL) + return (NULL); +again: + p = fgets(line, BUFSIZ, netf); + if (p == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + net.n_name = p; + cp = strpbrk(p, " \t"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + while (*cp == ' ' || *cp == '\t') + cp++; + p = strpbrk(cp, " \t"); + if (p != NULL) + *p++ = '\0'; + net.n_net = inet_network(cp); + net.n_addrtype = AF_INET; + q = net.n_aliases = net_aliases; + if (p != NULL) { + cp = p; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &net_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + } + *q = NULL; + return (&net); +} diff --git a/usr.sbin/named/libresolv/getnetnamadr.c b/usr.sbin/named/libresolv/getnetnamadr.c new file mode 100644 index 00000000000..924bbb1dbb1 --- /dev/null +++ b/usr.sbin/named/libresolv/getnetnamadr.c @@ -0,0 +1,294 @@ +/* $OpenBSD: getnetnamadr.c,v 1.1 1997/03/12 10:42:04 downsj Exp $ */ + +/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro + * Dep. Matematica Universidade de Coimbra, Portugal, Europe + * + * 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. + */ +/* + * Copyright (c) 1983, 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; +static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; +static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.1 1997/03/12 10:42:04 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +extern int h_errno; + +#if defined(mips) && defined(SYSTYPE_BSD43) +extern int errno; +#endif + +struct netent *_getnetbyaddr __P((long net, int type)); +struct netent *_getnetbyname __P((const char *name)); + +#define BYADDR 0 +#define BYNAME 1 +#define MAXALIASES 35 + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +typedef union { + long al; + char ac; +} align; + +static struct netent * +getnetanswer(answer, anslen, net_i) + querybuf *answer; + int anslen; + int net_i; +{ + + register HEADER *hp; + register u_char *cp; + register int n; + u_char *eom; + int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; + char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap, + *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; +static struct netent net_entry; +static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; + + /* + * find first satisfactory answer + * + * answer --> +------------+ ( MESSAGE ) + * | Header | + * +------------+ + * | Question | the question for the name server + * +------------+ + * | Answer | RRs answering the question + * +------------+ + * | Authority | RRs pointing toward an authority + * | Additional | RRs holding additional information + * +------------+ + */ + eom = answer->buf + anslen; + hp = &answer->hdr; + ancount = ntohs(hp->ancount); /* #/records in the answer section */ + qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ + bp = netbuf; + buflen = sizeof(netbuf); + cp = answer->buf + HFIXEDSZ; + if (!qdcount) { + if (hp->aa) + h_errno = HOST_NOT_FOUND; + else + h_errno = TRY_AGAIN; + return (NULL); + } + while (qdcount-- > 0) + cp += __dn_skipname(cp, eom) + QFIXEDSZ; + ap = net_aliases; + *ap = NULL; + net_entry.n_aliases = net_aliases; + haveanswer = 0; + while (--ancount >= 0 && cp < eom) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !res_dnok(bp)) + break; + cp += n; + ans[0] = '\0'; + (void)strcpy(&ans[0], bp); + GETSHORT(type, cp); + GETSHORT(class, cp); + cp += INT32SZ; /* TTL */ + GETSHORT(n, cp); + if (class == C_IN && type == T_PTR) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if ((n < 0) || !res_hnok(bp)) { + cp += n; + return (NULL); + } + cp += n; + *ap++ = bp; + bp += strlen(bp) + 1; + net_entry.n_addrtype = + (class == C_IN) ? AF_INET : AF_UNSPEC; + haveanswer++; + } + } + if (haveanswer) { + *ap = NULL; + switch (net_i) { + case BYADDR: + net_entry.n_name = *net_entry.n_aliases; + net_entry.n_net = 0L; + break; + case BYNAME: + in = *net_entry.n_aliases; + net_entry.n_name = &ans[0]; + aux2[0] = '\0'; + for (i = 0; i < 4; i++) { + for (st = in, nchar = 0; + *st != '.'; + st++, nchar++) + ; + if (nchar != 1 || *in != '0' || flag) { + flag = 1; + (void)strncpy(paux1, + (i==0) ? in : in-1, + (i==0) ?nchar : nchar+1); + paux1[(i==0) ? nchar : nchar+1] = '\0'; + pauxt = paux2; + paux2 = strcat(paux1, paux2); + paux1 = pauxt; + } + in = ++st; + } + net_entry.n_net = inet_network(paux2); + break; + } + net_entry.n_aliases++; + return (&net_entry); + } + h_errno = TRY_AGAIN; + return (NULL); +} + +struct netent * +getnetbyaddr(net, net_type) + register u_long net; + register int net_type; +{ + unsigned int netbr[4]; + int nn, anslen; + querybuf buf; + char qbuf[MAXDNAME]; + unsigned long net2; + struct netent *net_entry; + + if (net_type != AF_INET) + return (_getnetbyaddr(net, net_type)); + + for (nn = 4, net2 = net; net2; net2 >>= 8) + netbr[--nn] = net2 & 0xff; + switch (nn) { + case 3: /* Class A */ + sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]); + break; + case 2: /* Class B */ + sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]); + break; + case 1: /* Class C */ + sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], + netbr[1]); + break; + case 0: /* Class D - E */ + sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], + netbr[1], netbr[0]); + break; + } + anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + if (anslen < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_query failed\n"); +#endif + if (errno == ECONNREFUSED) + return (_getnetbyaddr(net, net_type)); + return (NULL); + } + net_entry = getnetanswer(&buf, anslen, BYADDR); + if (net_entry) { + unsigned u_net = net; /* maybe net should be unsigned ? */ + + /* Strip trailing zeros */ + while ((u_net & 0xff) == 0 && u_net != 0) + u_net >>= 8; + net_entry->n_net = u_net; + return (net_entry); + } + return (_getnetbyaddr(net, net_type)); +} + +struct netent * +getnetbyname(net) + register const char *net; +{ + int anslen; + querybuf buf; + char qbuf[MAXDNAME]; + struct netent *net_entry; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + strcpy(&qbuf[0], net); + anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + if (anslen < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_query failed\n"); +#endif + if (errno == ECONNREFUSED) + return (_getnetbyname(net)); + return (_getnetbyname(net)); + } + net_entry = getnetanswer(&buf, anslen, BYNAME); + if (net_entry) + return (net_entry); + return (_getnetbyname(net)); +} diff --git a/usr.sbin/named/libresolv/herror.c b/usr.sbin/named/libresolv/herror.c new file mode 100644 index 00000000000..61ea189ba74 --- /dev/null +++ b/usr.sbin/named/libresolv/herror.c @@ -0,0 +1,125 @@ +/* $OpenBSD: herror.c,v 1.1 1997/03/12 10:42:04 downsj Exp $ */ + +/* + * ++Copyright++ 1987, 1993 + * - + * Copyright (c) 1987, 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) +#if 0 +static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$From: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: herror.c,v 1.1 1997/03/12 10:42:04 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#if defined(BSD) && (BSD >= 199103) +# include +# include +#else +# include "../conf/portability.h" +#endif + +const char *h_errlist[] = { + "Resolver Error 0 (no error)", + "Unknown host", /* 1 HOST_NOT_FOUND */ + "Host name lookup failure", /* 2 TRY_AGAIN */ + "Unknown server error", /* 3 NO_RECOVERY */ + "No address associated with name", /* 4 NO_ADDRESS */ +}; +int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; + +extern int h_errno; + +/* + * herror -- + * print the error indicated by the h_errno value. + */ +void +herror(s) + const char *s; +{ + struct iovec iov[4]; + register struct iovec *v = iov; + + if (s && *s) { + v->iov_base = (char *)s; + v->iov_len = strlen(s); + v++; + v->iov_base = ": "; + v->iov_len = 2; + v++; + } + v->iov_base = (char *)hstrerror(h_errno); + v->iov_len = strlen(v->iov_base); + v++; + v->iov_base = "\n"; + v->iov_len = 1; + writev(STDERR_FILENO, iov, (v - iov) + 1); +} + +const char * +hstrerror(err) + int err; +{ + if (err < 0) + return ("Resolver internal error"); + else if (err < h_nerr) + return (h_errlist[err]); + return ("Unknown resolver error"); +} diff --git a/usr.sbin/named/libresolv/hostnamelen.c b/usr.sbin/named/libresolv/hostnamelen.c new file mode 100644 index 00000000000..d697ac25132 --- /dev/null +++ b/usr.sbin/named/libresolv/hostnamelen.c @@ -0,0 +1,100 @@ +/* $OpenBSD: hostnamelen.c,v 1.1 1997/03/12 10:42:04 downsj Exp $ */ + +/* + * ++Copyright++ 1995 + * - + * Copyright (c) 1995 + * 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) +#if 0 +static char rcsid[] = "$From: hostnamelen.c,v 8.2 1995/08/22 05:01:47 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: hostnamelen.c,v 1.1 1997/03/12 10:42:04 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#if defined(BSD) && (BSD >= 199103) +# include +#else +# include "../conf/portability.h" +#endif +#if defined(USE_OPTIONS_H) +# include <../conf/options.h> +#endif + +#ifndef ultrix +int __local_hostname_length_unneeded; +#else +int +local_hostname_length(hostname) + const char *hostname; +{ + int len_host, len_domain; + + if (!*_res.defdname) + res_init(); + len_host = strlen(hostname); + len_domain = strlen(_res.defdname); + if (len_host > len_domain && + !strcasecmp(hostname + len_host - len_domain, _res.defdname) && + hostname[len_host - len_domain - 1] == '.') + return (len_host - len_domain - 1); + return (0); +} +#endif diff --git a/usr.sbin/named/libresolv/inet_addr.c b/usr.sbin/named/libresolv/inet_addr.c new file mode 100644 index 00000000000..b01b243acac --- /dev/null +++ b/usr.sbin/named/libresolv/inet_addr.c @@ -0,0 +1,190 @@ +/* $OpenBSD: inet_addr.c,v 1.1 1997/03/12 10:42:05 downsj Exp $ */ + +/* + * ++Copyright++ 1983, 1990, 1993 + * - + * Copyright (c) 1983, 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) +#if 0 +static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.1 1997/03/12 10:42:05 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include "../conf/portability.h" + +/* these are compatibility routines, not needed on recent BSD releases */ + +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +u_long +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(cp, addr) + register const char *cp; + struct in_addr *addr; +{ + register u_long val; + register int base, n; + register char c; + u_int parts[4]; + register u_int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} diff --git a/usr.sbin/named/libresolv/inet_net_ntop.c b/usr.sbin/named/libresolv/inet_net_ntop.c new file mode 100644 index 00000000000..b1308b9aed9 --- /dev/null +++ b/usr.sbin/named/libresolv/inet_net_ntop.c @@ -0,0 +1,145 @@ +/* $OpenBSD: inet_net_ntop.c,v 1.1 1997/03/12 10:42:05 downsj Exp $ */ + +/* + * 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) +#if 0 +static const char rcsid[] = "$From: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp $"; +#else +static const char rcsid[] = "$OpenBSD: inet_net_ntop.c,v 1.1 1997/03/12 10:42:05 downsj Exp $"; +#endif +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits, + char *dst, size_t size)); + +/* + * char * + * inet_net_ntop(af, src, bits, dst, size) + * convert network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * author: + * Paul Vixie (ISC), July 1996 + */ +char * +inet_net_ntop(af, src, bits, dst, size) + int af; + const void *src; + int bits; + char *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_net_ntop_ipv4(src, bits, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } +} + +/* + * static char * + * inet_net_ntop_ipv4(src, bits, dst, size) + * convert IPv4 network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), July 1996 + */ +static char * +inet_net_ntop_ipv4(src, bits, dst, size) + const u_char *src; + int bits; + char *dst; + size_t size; +{ + char *odst = dst; + char *t; + u_int m; + int b; + + if (bits < 0 || bits > 32) { + errno = EINVAL; + return (NULL); + } + if (bits == 0) { + if (size < sizeof "0") + goto emsgsize; + *dst++ = '0'; + *dst = '\0'; + } + + /* Format whole octets. */ + for (b = bits / 8; b > 0; b--) { + if (size < sizeof "255.") + goto emsgsize; + t = dst; + dst += SPRINTF((dst, "%u", *src++)); + if (b > 1) { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t)(dst - t); + } + + /* Format partial octet. */ + b = bits % 8; + if (b > 0) { + if (size < sizeof ".255") + goto emsgsize; + t = dst; + if (dst != odst) + *dst++ = '.'; + m = ((1 << b) - 1) << (8 - b); + dst += SPRINTF((dst, "%u", *src & m)); + size -= (size_t)(dst - t); + } + + /* Format CIDR /width. */ + if (size < sizeof "/32") + goto emsgsize; + dst += SPRINTF((dst, "/%u", bits)); + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); +} diff --git a/usr.sbin/named/libresolv/inet_net_pton.c b/usr.sbin/named/libresolv/inet_net_pton.c new file mode 100644 index 00000000000..2f8c1e6e09d --- /dev/null +++ b/usr.sbin/named/libresolv/inet_net_pton.c @@ -0,0 +1,213 @@ +/* $OpenBSD: inet_net_pton.c,v 1.1 1997/03/12 10:42:05 downsj Exp $ */ + +/* + * 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) +#if 0 +static const char rcsid[] = "$From: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp $"; +#else +static const char rcsid[] = "$OpenBSD: inet_net_pton.c,v 1.1 1997/03/12 10:42:05 downsj Exp $"; +#endif +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static int inet_net_pton_ipv4 __P((const char *src, u_char *dst, + size_t size)); + +/* + * static int + * inet_net_pton(af, src, dst, size) + * convert network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not a valid network specification. + * author: + * Paul Vixie (ISC), June 1996 + */ +int +inet_net_pton(af, src, dst, size) + int af; + const char *src; + void *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_net_pton_ipv4(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (-1); + } +} + +/* + * static int + * inet_net_pton_ipv4(src, dst, size) + * convert IPv4 network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not an IPv4 network specification. + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), June 1996 + */ +static int +inet_net_pton_ipv4(src, dst, size) + const char *src; + u_char *dst; + size_t size; +{ + static const char + xdigits[] = "0123456789abcdef", + digits[] = "0123456789"; + int n, ch, tmp, dirty, bits; + const u_char *odst = dst; + + ch = *src++; + if (ch == '0' && (src[0] == 'x' || src[0] == 'X') + && isascii(src[1]) && isxdigit(src[1])) { + /* Hexadecimal: Eat nybble string. */ + if (size <= 0) + goto emsgsize; + *dst = 0, dirty = 0; + src++; /* skip x or X. */ + while ((ch = *src++) != '\0' && + isascii(ch) && isxdigit(ch)) { + if (isupper(ch)) + ch = tolower(ch); + n = strchr(xdigits, ch) - xdigits; + assert(n >= 0 && n <= 15); + *dst |= n; + if (!dirty++) + *dst <<= 4; + else if (size-- > 0) + *++dst = 0, dirty = 0; + else + goto emsgsize; + } + if (dirty) + size--; + } else if (isascii(ch) && isdigit(ch)) { + /* Decimal: eat dotted digit string. */ + for (;;) { + tmp = 0; + do { + n = strchr(digits, ch) - digits; + assert(n >= 0 && n <= 9); + tmp *= 10; + tmp += n; + if (tmp > 255) + goto enoent; + } while ((ch = *src++) != '\0' && + isascii(ch) && isdigit(ch)); + if (size-- <= 0) + goto emsgsize; + *dst++ = (u_char) tmp; + if (ch == '\0' || ch == '/') + break; + if (ch != '.') + goto enoent; + ch = *src++; + if (!isascii(ch) || !isdigit(ch)) + goto enoent; + } + } else + goto enoent; + + bits = -1; + if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) { + /* CIDR width specifier. Nothing can follow it. */ + ch = *src++; /* Skip over the /. */ + bits = 0; + do { + n = strchr(digits, ch) - digits; + assert(n >= 0 && n <= 9); + bits *= 10; + bits += n; + } while ((ch = *src++) != '\0' && + isascii(ch) && isdigit(ch)); + if (ch != '\0') + goto enoent; + if (bits > 32) + goto emsgsize; + } + + /* Firey death and destruction unless we prefetched EOS. */ + if (ch != '\0') + goto enoent; + + /* If nothing was written to the destination, we found no address. */ + if (dst == odst) + goto enoent; + /* If no CIDR spec was given, infer width from net class. */ + if (bits == -1) { + if (*odst >= 240) /* Class E */ + bits = 32; + else if (*odst >= 224) /* Class D */ + bits = 4; + else if (*odst >= 192) /* Class C */ + bits = 24; + else if (*odst >= 128) /* Class B */ + bits = 16; + else /* Class A */ + bits = 8; + /* If imputed mask is narrower than specified octets, widen. */ + if (bits >= 8 && bits < ((dst - odst) * 8)) + bits = (dst - odst) * 8; + } + /* Extend network to cover the actual mask. */ + while (bits > ((dst - odst) * 8)) { + if (size-- <= 0) + goto emsgsize; + *dst++ = '\0'; + } + return (bits); + + enoent: + errno = ENOENT; + return (-1); + + emsgsize: + errno = EMSGSIZE; + return (-1); +} diff --git a/usr.sbin/named/libresolv/inet_neta.c b/usr.sbin/named/libresolv/inet_neta.c new file mode 100644 index 00000000000..6565e03acb2 --- /dev/null +++ b/usr.sbin/named/libresolv/inet_neta.c @@ -0,0 +1,88 @@ +/* $OpenBSD: inet_neta.c,v 1.1 1997/03/12 10:42:06 downsj Exp $ */ + +/* + * 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) +#if 0 +static const char rcsid[] = "$Id: inet_neta.c,v 1.1 1997/03/12 10:42:06 downsj Exp $"; +#else +static const char rcsid[] = "$OpenBSD: inet_neta.c,v 1.1 1997/03/12 10:42:06 downsj Exp $"; +#endif +#endif + +#include +#include +#include +#include + +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +/* + * char * + * inet_neta(src, dst, size) + * format a u_long network number into presentation format. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * format of ``src'' is as for inet_network(). + * author: + * Paul Vixie (ISC), July 1996 + */ +char * +inet_neta(src, dst, size) + u_long src; + char *dst; + size_t size; +{ + char *odst = dst; + char *tp; + + while (src & 0xffffffff) { + u_char b = (src & 0xff000000) >> 24; + + src <<= 8; + if (b) { + if (size < sizeof "255.") + goto emsgsize; + tp = dst; + dst += SPRINTF((dst, "%u", b)); + if (src != 0L) { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t)(dst - tp); + } + } + if (dst == odst) { + if (size < sizeof "0.0.0.0") + goto emsgsize; + strcpy(dst, "0.0.0.0"); + } + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); +} diff --git a/usr.sbin/named/libresolv/inet_ntop.c b/usr.sbin/named/libresolv/inet_ntop.c new file mode 100644 index 00000000000..e3da069e7ef --- /dev/null +++ b/usr.sbin/named/libresolv/inet_ntop.c @@ -0,0 +1,201 @@ +/* $OpenBSD: inet_ntop.c,v 1.1 1997/03/12 10:42:06 downsj Exp $ */ + +/* 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) +#if 0 +static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.1 1997/03/12 10:42:06 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../conf/portability.h" + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +/* + * 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/usr.sbin/named/libresolv/inet_pton.c b/usr.sbin/named/libresolv/inet_pton.c new file mode 100644 index 00000000000..035d152770b --- /dev/null +++ b/usr.sbin/named/libresolv/inet_pton.c @@ -0,0 +1,221 @@ +/* $OpenBSD: inet_pton.c,v 1.1 1997/03/12 10:42:07 downsj Exp $ */ + +/* 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) +#if 0 +static char rcsid[] = "$From: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_pton.c,v 1.1 1997/03/12 10:42:07 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../conf/portability.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/usr.sbin/named/libresolv/nsap_addr.c b/usr.sbin/named/libresolv/nsap_addr.c new file mode 100644 index 00000000000..f6c6b72f217 --- /dev/null +++ b/usr.sbin/named/libresolv/nsap_addr.c @@ -0,0 +1,120 @@ +/* $OpenBSD: nsap_addr.c,v 1.1 1997/03/12 10:42:07 downsj Exp $ */ + +/* + * 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) +#if 0 +static char rcsid[] = "$From: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: nsap_addr.c,v 1.1 1997/03/12 10:42:07 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../conf/portability.h" + +#if !defined(isxdigit) /* XXX - could be a function */ +static int +isxdigit(c) + register int c; +{ + return ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'F')); +} +#endif + +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/usr.sbin/named/libresolv/res_comp.c b/usr.sbin/named/libresolv/res_comp.c new file mode 100644 index 00000000000..a40c00763da --- /dev/null +++ b/usr.sbin/named/libresolv/res_comp.c @@ -0,0 +1,512 @@ +/* $OpenBSD: res_comp.c,v 1.1 1997/03/12 10:42:08 downsj Exp $ */ + +/* + * ++Copyright++ 1985, 1993 + * - + * 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) +#if 0 +static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$From: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: res_comp.c,v 1.1 1997/03/12 10:42:08 downsj Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +#include +#include +#include + +#if defined(BSD) && (BSD >= 199103) +# include +# include +#else +# include "../conf/portability.h" +#endif + +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'; + 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); +} + +/* + * Verify that a domain name uses an acceptable character set. + */ + +/* + * Note the conspicuous absence of ctype macros in these definitions. On + * non-ASCII hosts, we can't depend on string literals or ctype macros to + * tell us anything about network-format data. The rest of the BIND system + * is not careful about this, but for some reason, we're doing it right here. + */ +#define PERIOD 0x2e +#define hyphenchar(c) ((c) == 0x2d) +#define bslashchar(c) ((c) == 0x5c) +#define periodchar(c) ((c) == PERIOD) +#define asterchar(c) ((c) == 0x2a) +#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ + || ((c) >= 0x61 && (c) <= 0x7a)) +#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) + +#define borderchar(c) (alphachar(c) || digitchar(c)) +#define middlechar(c) (borderchar(c) || hyphenchar(c)) +#define domainchar(c) ((c) > 0x20 && (c) < 0x7f) + +int +res_hnok(dn) + const char *dn; +{ + int ppch = '\0', pch = PERIOD, ch = *dn++; + + while (ch != '\0') { + int nch = *dn++; + + if (periodchar(ch)) { + NULL; + } else if (periodchar(pch)) { + if (!borderchar(ch)) + return (0); + } else if (periodchar(nch) || nch == '\0') { + if (!borderchar(ch)) + return (0); + } else { + if (!middlechar(ch)) + return (0); + } + ppch = pch, pch = ch, ch = nch; + } + return (1); +} + +/* + * hostname-like (A, MX, WKS) owners can have "*" as their first label + * but must otherwise be as a host name. + */ +int +res_ownok(dn) + const char *dn; +{ + if (asterchar(dn[0])) { + if (periodchar(dn[1])) + return (res_hnok(dn+2)); + if (dn[1] == '\0') + return (1); + } + return (res_hnok(dn)); +} + +/* + * SOA RNAMEs and RP RNAMEs can have any printable character in their first + * label, but the rest of the name has to look like a host name. + */ +int +res_mailok(dn) + const char *dn; +{ + int ch, escaped = 0; + + /* "." is a valid missing representation */ + if (*dn == '\0') + return(1); + + /* otherwise