aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Greenman <dg@FreeBSD.org>1995-08-30 04:09:27 +0000
committerDavid Greenman <dg@FreeBSD.org>1995-08-30 04:09:27 +0000
commit3139720337003aea416e4c920937fa8f628b21cb (patch)
treed0720ae88801dee01856693c0cb0c180df8e6f1a
parentfa1835d0e5fab661f43879dc170b85a9b1451ff2 (diff)
Notes
-rw-r--r--include/arpa/nameser.h51
-rw-r--r--include/netdb.h8
-rw-r--r--include/resolv.h37
-rw-r--r--lib/libc/net/gethostbydns.c131
-rw-r--r--lib/libc/net/getservent.34
-rw-r--r--lib/libc/net/herror.c17
-rw-r--r--lib/libc/net/res_debug.c140
-rw-r--r--lib/libc/net/res_init.c108
-rw-r--r--lib/libc/net/res_mkquery.c20
-rw-r--r--lib/libc/net/res_query.c67
-rw-r--r--lib/libc/net/res_send.c142
-rw-r--r--usr.bin/dig/dig.c71
-rw-r--r--usr.bin/host/host.c48
-rw-r--r--usr.sbin/named/db_defs.h12
-rw-r--r--usr.sbin/named/db_dump.c76
-rw-r--r--usr.sbin/named/db_func.h33
-rw-r--r--usr.sbin/named/db_glue.c566
-rw-r--r--usr.sbin/named/db_load.c509
-rw-r--r--usr.sbin/named/db_lookup.c23
-rw-r--r--usr.sbin/named/db_save.c53
-rw-r--r--usr.sbin/named/db_secure.c49
-rw-r--r--usr.sbin/named/db_update.c210
-rw-r--r--usr.sbin/named/ns_defs.h35
-rw-r--r--usr.sbin/named/ns_forw.c165
-rw-r--r--usr.sbin/named/ns_func.h53
-rw-r--r--usr.sbin/named/ns_glob.h40
-rw-r--r--usr.sbin/named/ns_init.c235
-rw-r--r--usr.sbin/named/ns_main.c239
-rw-r--r--usr.sbin/named/ns_maint.c340
-rw-r--r--usr.sbin/named/ns_ncache.c5
-rw-r--r--usr.sbin/named/ns_req.c717
-rw-r--r--usr.sbin/named/ns_resp.c997
-rw-r--r--usr.sbin/named/ns_sort.c6
-rw-r--r--usr.sbin/named/ns_stats.c109
-rw-r--r--usr.sbin/named/ns_validate.c195
-rw-r--r--usr.sbin/named/options.h32
-rw-r--r--usr.sbin/named/portability.h135
-rw-r--r--usr.sbin/named/storage.c21
-rw-r--r--usr.sbin/named/tools/Makefile2
-rw-r--r--usr.sbin/named/tools/named.reload/Makefile10
-rw-r--r--usr.sbin/named/tools/named.reload/named.reload.sh5
-rw-r--r--usr.sbin/named/tools/named.restart/Makefile8
-rw-r--r--usr.sbin/named/tools/named.restart/named.restart.sh20
-rw-r--r--usr.sbin/named/xfer/Makefile12
-rw-r--r--usr.sbin/named/xfer/named-xfer.c454
-rw-r--r--usr.sbin/nslookup/debug.c23
-rw-r--r--usr.sbin/nslookup/list.c59
-rw-r--r--usr.sbin/nslookup/nslookup.help6
-rw-r--r--usr.sbin/nslookup/subr.c12
49 files changed, 4457 insertions, 1853 deletions
diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
index eea392787f0d4..403530401d8ac 100644
--- a/include/arpa/nameser.h
+++ b/include/arpa/nameser.h
@@ -55,8 +55,8 @@
* From Id: nameser.h,v 4.9.1.15 1994/07/19 22:51:24 vixie Exp
*/
-#ifndef _NAMESER_H_
-#define _NAMESER_H_
+#ifndef _ARPA_NAMESER_H_
+#define _ARPA_NAMESER_H_
#include <sys/param.h>
#include <sys/types.h>
@@ -72,7 +72,7 @@
* is new enough to contain a certain feature.
*/
-#define __BIND 19940417 /* interface version stamp */
+#define __BIND 19950621 /* interface version stamp */
/*
* Define constants based on rfc883
@@ -94,24 +94,26 @@
#define NAMESERVER_PORT 53
/*
- * Currently define d opcodes
+ * Currently defined opcodes
*/
#define QUERY 0x0 /* standard query */
#define IQUERY 0x1 /* inverse query */
#define STATUS 0x2 /* nameserver status query */
- /* 0x3 reserved */
+/*#define xxx 0x3 */ /* 0x3 reserved */
+#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */
+#ifdef ALLOW_UPDATES
/* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
-#define UPDATEA 0x9 /* add resource record */
-#define UPDATED 0xa /* delete a specific resource record */
-#define UPDATEDA 0xb /* delete all named resource record */
-#define UPDATEM 0xc /* modify a specific resource record */
-#define UPDATEMA 0xd /* modify all named resource record */
-
-#define ZONEINIT 0xe /* initial zone transfer */
-#define ZONEREF 0xf /* incremental zone referesh */
+# define UPDATEA 0x9 /* add resource record */
+# define UPDATED 0xa /* delete a specific resource record */
+# define UPDATEDA 0xb /* delete all named resource record */
+# define UPDATEM 0xc /* modify a specific resource record */
+# define UPDATEMA 0xd /* modify all named resource record */
+# define ZONEINIT 0xe /* initial zone transfer */
+# define ZONEREF 0xf /* incremental zone referesh */
+#endif
/*
- * Currently define d response codes
+ * Currently defined response codes
*/
#define NOERROR 0 /* no error */
#define FORMERR 1 /* format error */
@@ -119,8 +121,10 @@
#define NXDOMAIN 3 /* non existent domain */
#define NOTIMP 4 /* not implemented */
#define REFUSED 5 /* query refused */
+#ifdef ALLOW_UPDATES
/* non standard */
-#define NOCHANGE 0xf /* update failed to change db */
+# define NOCHANGE 0xf /* update failed to change db */
+#endif
/*
* Type values for resources and queries
@@ -129,7 +133,7 @@
#define T_NS 2 /* authoritative server */
#define T_MD 3 /* mail destination */
#define T_MF 4 /* mail forwarder */
-#define T_CNAME 5 /* connonical name */
+#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 */
@@ -148,12 +152,17 @@
#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 */
/* 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) */
-#define T_SA 200 /* shuffle address */
/* Query type values which do not appear in resource records */
#define T_AXFR 252 /* transfer zone of authority */
#define T_MAILB 253 /* transfer mailbox records */
@@ -197,8 +206,7 @@ typedef struct {
unsigned rd: 1; /* recursion desired */
/* fields in fourth byte */
unsigned ra: 1; /* recursion available */
- unsigned pr: 1; /* primary server req'd (!standard) */
- unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned unused :3; /* unused bits (MBZ as of 4.9.3a3) */
unsigned rcode :4; /* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
@@ -210,8 +218,7 @@ typedef struct {
unsigned qr :1; /* response flag */
/* fields in fourth byte */
unsigned rcode :4; /* response code */
- unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */
- unsigned pr :1; /* primary server req'd (!standard) */
+ unsigned unused :3; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ra :1; /* recursion available */
#endif
/* remaining bytes */
@@ -283,4 +290,4 @@ extern u_int32_t _getlong __P((const u_char *));
(cp) += INT32SZ; \
}
-#endif /* !_NAMESER_H_ */
+#endif /* !_ARPA_NAMESER_H_ */
diff --git a/include/netdb.h b/include/netdb.h
index 1be7163cb8f4d..3fd20df003c1f 100644
--- a/include/netdb.h
+++ b/include/netdb.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)netdb.h 8.1 (Berkeley) 6/2/93
- * $Id: netdb.h,v 1.1.1.1 1994/05/24 09:57:18 rgrimes Exp $
+ * $Id: netdb.h,v 1.2 1995/05/30 04:54:41 rgrimes Exp $
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
*
@@ -63,6 +63,8 @@
#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
@@ -106,6 +108,8 @@ struct protoent {
* (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 */
@@ -132,7 +136,7 @@ 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 *));
-char *hstrerror __P((int));
+const char *hstrerror __P((int));
void sethostent __P((int));
/* void sethostfile __P((const char *)); */
void setnetent __P((int));
diff --git a/include/resolv.h b/include/resolv.h
index e1c57f164e8cf..fe77da2b6451f 100644
--- a/include/resolv.h
+++ b/include/resolv.h
@@ -53,7 +53,7 @@
*
* @(#)resolv.h 8.1 (Berkeley) 6/2/93
* From Id: resolv.h,v 4.9.1.2 1993/05/17 09:59:01 vixie Exp
- * $Id: resolv.h,v 1.2 1994/09/25 02:11:32 pst Exp $
+ * $Id: resolv.h,v 1.3 1995/05/30 04:54:44 rgrimes Exp $
*/
#ifndef _RESOLV_H_
@@ -72,7 +72,7 @@
* is new enough to contain a certain feature.
*/
-#define __RES 19940415
+#define __RES 19950621
/*
* Resolver configuration file.
@@ -120,20 +120,21 @@ struct __res_state {
/*
* 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 */
-#define RES_USEVC 0x00000008 /* use virtual circuit */
-#define RES_PRIMARY 0x00000010 /* query primary server only */
-#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_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_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
/*
* Resolver "pfcode" values. Used by dig.
@@ -190,6 +191,10 @@ extern struct __res_state _res;
#define p_fqname __p_fqname
#define p_rr __p_rr
#define p_option __p_option
+#define res_randomid __res_randomid
+#define res_isourserver __res_isourserver
+#define res_nameinquery __res_nameinquery
+#define res_queriesmatch __res_queriesmatch
__BEGIN_DECLS
int __dn_skipname __P((const u_char *, const u_char *));
@@ -212,6 +217,7 @@ 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_int16_t 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,
@@ -219,6 +225,11 @@ int res_querydomain __P((const char *, const char *, int, 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 *));
__END_DECLS
#endif /* !_RESOLV_H_ */
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c
index 6db04f932ddee..c091abbfcac0b 100644
--- a/lib/libc/net/gethostbydns.c
+++ b/lib/libc/net/gethostbydns.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp $";
+static char rcsid[] = "$Id: gethostbydns.c,v 1.4 1995/05/30 05:40:43 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -61,16 +61,16 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <string.h>
#include <netdb.h>
#include <resolv.h>
-#include <stdio.h>
#include <ctype.h>
#include <errno.h>
-#include <string.h>
#include <syslog.h>
-#define BYADDR 0
-#define BYNAME 1
+#include "res_config.h"
#define MAXALIASES 35
#define MAXADDRS 35
@@ -78,7 +78,7 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp
#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
static const char AskedForGot[] =
- "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
+ "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
static char *h_addr_ptrs[MAXADDRS + 1];
@@ -87,8 +87,6 @@ static char *host_aliases[MAXALIASES];
static char hostbuf[8*1024];
static struct in_addr host_addr;
static FILE *hostf = NULL;
-static char hostaddr[MAXADDRS];
-static char *host_addrs[2];
static int stayopen = 0;
#if PACKETSZ > 1024
@@ -109,6 +107,24 @@ typedef union {
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
+
+
#ifdef RESOLVSORT
static void
addrsort(ap, num)
@@ -122,7 +138,7 @@ addrsort(ap, num)
p = ap;
for (i = 0; i < num; i++, p++) {
- for (j = 0 ; j < _res.nsort; j++)
+ 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;
@@ -240,7 +256,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
cp += n;
if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
- "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
+ "gethostby*.gethostanswer: asked for \"%s\", got CNAME for \"%s\"",
host.h_name, bp);
continue; /* XXX - had_error++ ? */
}
@@ -262,9 +278,12 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
continue;
}
if (type != qtype) {
+ /* CNAME->PTR should not cause a log message. */
+ if (!(qtype == T_PTR && type == T_CNAME))
syslog(LOG_NOTICE|LOG_AUTH,
- "gethostby*.getanswer: asked for type %d(%s), got %d(%s)",
- qtype, qname, type, bp);
+ "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
+ qname, p_class(qclass), p_type(qtype),
+ p_type(type));
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -297,6 +316,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
break;
#else
host.h_name = bp;
+ h_errno = NETDB_SUCCESS;
return (&host);
#endif
case T_A:
@@ -327,14 +347,13 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
bp += sizeof(align) - ((u_long)bp % sizeof(align));
if (bp + n >= &hostbuf[sizeof hostbuf]) {
- if (_res.options & RES_DEBUG)
- printf("size (%d) too big\n", n);
+ dprintf("size (%d) too big\n", n);
had_error++;
continue;
}
if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
- if (_res.options & RES_DEBUG && !toobig++)
- printf("Too many addresses (%d)\n",
+ if (!toobig++)
+ dprintf("Too many addresses (%d)\n",
MAXADDRS);
cp += n;
continue;
@@ -344,7 +363,9 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
cp += n;
break;
default:
- abort();
+ dprintf("Impossible condition (type=%d)\n", type);
+ h_errno = NO_RECOVERY;
+ return (NULL);
} /*switch*/
if (!had_error)
haveanswer++;
@@ -367,6 +388,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
strcpy(bp, qname);
host.h_name = bp;
}
+ h_errno = NETDB_SUCCESS;
return (&host);
} else {
h_errno = TRY_AGAIN;
@@ -382,6 +404,19 @@ _gethostbydnsname(name)
register const char *cp;
int n;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+
+ /*
+ * 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.
@@ -400,7 +435,9 @@ _gethostbydnsname(name)
h_errno = HOST_NOT_FOUND;
return (NULL);
}
- host.h_name = (char *)name;
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ host.h_name = hostbuf;
host.h_aliases = host_aliases;
host_aliases[0] = NULL;
host.h_addrtype = AF_INET;
@@ -415,8 +452,7 @@ _gethostbydnsname(name)
}
if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
- if (_res.options & RES_DEBUG)
- printf("res_search failed\n");
+ dprintf("res_search failed (%d)\n", n);
return (NULL);
}
return (gethostanswer(&buf, n, name, C_IN, T_A));
@@ -431,33 +467,70 @@ _gethostbydnsaddr(addr, len, type)
querybuf buf;
register struct hostent *hp;
char qbuf[MAXDNAME+1];
- int o_res_options = _res.options;
+#ifdef SUNSECURITY
+ register struct hostent *rhp;
+ char **haddr;
+ u_long old_options;
+ char hname2[MAXDNAME+1];
+#endif /*SUNSECURITY*/
- if (type != AF_INET)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (type != AF_INET) {
+ errno = EAFNOSUPPORT;
+ h_errno = NETDB_INTERNAL;
return (NULL);
+ }
(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
((unsigned)addr[3] & 0xff),
((unsigned)addr[2] & 0xff),
((unsigned)addr[1] & 0xff),
((unsigned)addr[0] & 0xff));
- _res.options |= RES_RECURSE;
n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
- _res.options = o_res_options;
if (n < 0) {
- if (_res.options & RES_DEBUG)
- printf("res_query failed\n");
+ dprintf("res_query failed (%d)\n", n);
return (NULL);
}
if (!(hp = gethostanswer(&buf, n, qbuf, C_IN, T_PTR)))
+ return (NULL); /* h_errno was set by gethostanswer() */
+#ifdef SUNSECURITY
+ /*
+ * turn off search as the name should be absolute,
+ * 'localhost' should be matched by defnames
+ */
+ strncpy(hname2, hp->h_name, MAXDNAME);
+ hname2[MAXDNAME] = '\0';
+ old_options = _res.options;
+ _res.options &= ~RES_DNSRCH;
+ _res.options |= RES_DEFNAMES;
+ if (!(rhp = gethostbyname(hname2))) {
+ 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 = type;
hp->h_length = len;
h_addr_ptrs[0] = (char *)&host_addr;
h_addr_ptrs[1] = NULL;
host_addr = *(struct in_addr *)addr;
-#if BSD < 43 && !defined(h_addr) /* new-style hostent structure */
- hp->h_addr = h_addr_ptrs[0];
-#endif
+ h_errno = NETDB_SUCCESS;
return (hp);
}
diff --git a/lib/libc/net/getservent.3 b/lib/libc/net/getservent.3
index 973855cf098c9..b9b2585e1f491 100644
--- a/lib/libc/net/getservent.3
+++ b/lib/libc/net/getservent.3
@@ -46,9 +46,9 @@
.Ft struct servent *
.Fn getservent
.Ft struct servent *
-.Fn getservbyname "char *name" "char *proto"
+.Fn getservbyname "const char *name" "const char *proto"
.Ft struct servent *
-.Fn getservbyport "int port" proto
+.Fn getservbyport "int port" "const char *proto"
.Ft void
.Fn setservent "int stayopen"
.Ft void
diff --git a/lib/libc/net/herror.c b/lib/libc/net/herror.c
index c9135c304aae3..9b94ee4001204 100644
--- a/lib/libc/net/herror.c
+++ b/lib/libc/net/herror.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: herror.c,v 1.1.1.1 1994/05/27 04:57:15 rgrimes Exp $";
+static char rcsid[] = "$Id: herror.c,v 1.2 1995/05/30 05:40:49 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -62,8 +62,8 @@ static char rcsid[] = "$Id: herror.c,v 1.1.1.1 1994/05/27 04:57:15 rgrimes Exp $
#include <unistd.h>
#include <string.h>
-char *h_errlist[] = {
- "Error 0",
+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 */
@@ -92,8 +92,7 @@ herror(s)
v->iov_len = 2;
v++;
}
- v->iov_base = (u_int)h_errno < h_nerr ?
- h_errlist[h_errno] : "Unknown error";
+ v->iov_base = (char *)hstrerror(h_errno);
v->iov_len = strlen(v->iov_base);
v++;
v->iov_base = "\n";
@@ -101,9 +100,13 @@ herror(s)
writev(STDERR_FILENO, iov, (v - iov) + 1);
}
-char *
+const char *
hstrerror(err)
int err;
{
- return (u_int)err < h_nerr ? h_errlist[err] : "Unknown resolver error";
+ if (err < 0)
+ return ("Resolver internal error");
+ else if (err < h_nerr)
+ return (h_errlist[err]);
+ return ("Unknown resolver error");
}
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
index 78b11c957fd96..08b699e3223dd 100644
--- a/lib/libc/net/res_debug.c
+++ b/lib/libc/net/res_debug.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_debug.c,v 1.2 1994/09/25 02:12:34 pst Exp $";
+static char rcsid[] = "$Id: res_debug.c,v 1.3 1995/05/30 05:40:54 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -65,13 +65,16 @@ static char rcsid[] = "$Id: res_debug.c,v 1.2 1994/09/25 02:12:34 pst Exp $";
#include <stdio.h>
#include <resolv.h>
#include <string.h>
+#include <netdb.h>
+
+#include "res_config.h"
const char *_res_opcodes[] = {
"QUERY",
"IQUERY",
"CQUERYM",
- "CQUERYU",
- "4",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
"5",
"6",
"7",
@@ -104,12 +107,13 @@ const char *_res_resultcodes[] = {
"NOCHANGE",
};
-static char retbuf[16];
-
+/* XXX: we should use getservbyport() instead. */
static const char *
dewks(wks)
int wks;
{
+ static char nbuf[20];
+
switch (wks) {
case 5: return "rje";
case 7: return "echo";
@@ -157,14 +161,17 @@ dewks(wks)
case 161: return "snmp";
case 162: return "snmp-trap";
case 170: return "print-srv";
- default: (void) sprintf(retbuf, "%d", wks); return (retbuf);
+ default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
}
}
+/* XXX: we should use getprotobynumber() instead. */
static const char *
deproto(protonum)
int protonum;
{
+ static char nbuf[20];
+
switch (protonum) {
case 1: return "icmp";
case 2: return "igmp";
@@ -178,13 +185,13 @@ deproto(protonum)
case 12: return "pup";
case 16: return "chaos";
case 17: return "udp";
- default: (void) sprintf(retbuf, "%d", protonum); return (retbuf);
+ default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
}
}
static const u_char *
-do_rrset(msg, cp, cnt, pflag, file, hs)
- int cnt, pflag;
+do_rrset(msg, len, cp, cnt, pflag, file, hs)
+ int cnt, pflag, len;
const u_char *cp, *msg;
const char *hs;
FILE *file;
@@ -201,8 +208,19 @@ do_rrset(msg, cp, cnt, pflag, file, hs)
((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
fprintf(file, hs);
while (--n >= 0) {
+ if ((!_res.pfcode) || sflag) {
cp = p_rr(cp, msg, file);
- if ((cp - msg) > PACKETSZ)
+ } else {
+ unsigned int dlen;
+ cp += __dn_skipname(cp, cp + MAXCDNAME);
+ cp += INT16SZ;
+ cp += INT16SZ;
+ cp += INT32SZ;
+ dlen = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ cp += dlen;
+ }
+ if ((cp - msg) > len)
return (NULL);
}
if ((!_res.pfcode) ||
@@ -253,6 +271,9 @@ __fp_nquery(msg, len, file)
register const HEADER *hp;
register int n;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+
#define TruncTest(x) if (x >= endMark) goto trunc
#define ErrorTest(x) if (x == NULL) goto error
@@ -282,8 +303,6 @@ __fp_nquery(msg, len, file)
fprintf(file, " rd");
if (hp->ra)
fprintf(file, " ra");
- if (hp->pr)
- fprintf(file, " pr");
}
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
@@ -304,7 +323,7 @@ __fp_nquery(msg, len, file)
while (--n >= 0) {
fprintf(file,";;\t");
TruncTest(cp);
- cp = p_cdname(cp, msg, file);
+ cp = p_cdnname(cp, msg, len, file);
ErrorTest(cp);
TruncTest(cp);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
@@ -323,7 +342,7 @@ __fp_nquery(msg, len, file)
* Print authoritative answer records
*/
TruncTest(cp);
- cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
+ cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
";; ANSWERS:\n");
ErrorTest(cp);
@@ -331,7 +350,7 @@ __fp_nquery(msg, len, file)
* print name server records
*/
TruncTest(cp);
- cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
+ cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
";; AUTHORITY RECORDS:\n");
ErrorTest(cp);
@@ -339,7 +358,7 @@ __fp_nquery(msg, len, file)
/*
* print additional records
*/
- cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
+ cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
";; ADDITIONAL RECORDS:\n");
ErrorTest(cp);
return;
@@ -393,7 +412,7 @@ __p_fqname(cp, msg, file)
FILE *file;
{
char name[MAXDNAME];
- int n, len;
+ int n;
if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
return (NULL);
@@ -422,6 +441,10 @@ __p_rr(cp, msg, file)
u_int32_t tmpttl, t;
int lcnt;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL); /* compression error */
type = _getshort((u_char*)cp);
@@ -434,7 +457,7 @@ __p_rr(cp, msg, file)
cp += INT16SZ;
cp1 = cp;
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
- fprintf(file, "\t%lu", tmpttl);
+ fprintf(file, "\t%lu", (u_long)tmpttl);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
fprintf(file, "\t%s", __p_class(class));
fprintf(file, "\t%s", __p_type(type));
@@ -476,37 +499,46 @@ __p_rr(cp, msg, file)
case T_NS:
case T_PTR:
putc('\t', file);
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
break;
case T_HINFO:
case T_ISDN:
+ cp2 = cp + dlen;
if (n = *cp++) {
fprintf(file,"\t%.*s", n, cp);
cp += n;
}
- if (n = *cp++) {
+ if ((cp < cp2) && (n = *cp++)) {
fprintf(file,"\t%.*s", n, cp);
cp += n;
- }
+ } else if (type == T_HINFO)
+ fprintf(file, "\n;; *** Warning *** OS-type missing");
break;
case T_SOA:
putc('\t', file);
- cp = p_fqname(cp, msg, file); /* origin */
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
putc(' ', file);
- cp = p_fqname(cp, msg, file); /* mail addr */
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
fputs(" (\n", file);
t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file,"\t\t\t%lu\t; serial\n", t);
+ fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
+ (u_long)t, __p_time(t));
t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
+ (u_long)t, __p_time(t));
t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
+ (u_long)t, __p_time(t));
t = _getlong((u_char*)cp); cp += INT32SZ;
- fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
+ fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
+ (u_long)t, __p_time(t));
break;
case T_MX:
@@ -514,7 +546,18 @@ __p_rr(cp, msg, file)
case T_RT:
fprintf(file,"\t%d ", _getshort((u_char*)cp));
cp += INT16SZ;
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ break;
+
+ case T_PX:
+ fprintf(file, "\t%d ", _getshort((u_char*)cp));
+ cp += INT16SZ;
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ putc(' ', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
break;
case T_TXT:
@@ -524,7 +567,7 @@ __p_rr(cp, msg, file)
while (cp < cp2) {
if (n = (unsigned char) *cp++) {
for (c = n; c > 0 && cp < cp2; c--)
- if (*cp == '\n') {
+ if ((*cp == '\n') || (*cp == '"')) {
(void) putc('\\', file);
(void) putc(*cp++, file);
} else
@@ -546,9 +589,11 @@ __p_rr(cp, msg, file)
case T_MINFO:
case T_RP:
putc('\t', file);
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
putc(' ', file);
- cp = p_fqname(cp, msg, file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
break;
case T_UINFO:
@@ -628,8 +673,6 @@ __p_rr(cp, msg, file)
return (cp);
}
-static char nbuf[40];
-
/*
* Return a string for the type
*/
@@ -637,6 +680,8 @@ const char *
__p_type(type)
int type;
{
+ static char nbuf[20];
+
switch (type) {
case T_A: return "A";
case T_NS: return "NS";
@@ -652,12 +697,19 @@ __p_type(type)
case T_MINFO: return "MINFO";
case T_MX: return "MX";
case T_TXT: return "TXT";
- case T_NSAP: return "NSAP";
case T_RP: return "RP";
case T_AFSDB: return "AFSDB";
case T_X25: return "X25";
case T_ISDN: return "ISDN";
case T_RT: return "RT";
+ case T_NSAP: return "NSAP";
+ case T_NSAP_PTR: return "NSAP_PTR";
+ case T_SIG: return "SIG";
+ case T_KEY: return "KEY";
+ case T_PX: return "PX";
+ case T_GPOS: return "GPOS";
+ case T_AAAA: return "AAAA";
+ case T_LOC: return "LOC";
case T_AXFR: return "AXFR";
case T_MAILB: return "MAILB";
case T_MAILA: return "MAILA";
@@ -679,10 +731,12 @@ const char *
__p_class(class)
int class;
{
+ static char nbuf[20];
+
switch (class) {
- case C_IN: return("IN");
- case C_HS: return("HS");
- case C_ANY: return("ANY");
+ case C_IN: return "IN";
+ case C_HS: return "HS";
+ case C_ANY: return "ANY";
default: (void)sprintf(nbuf, "%d", class); return (nbuf);
}
}
@@ -694,12 +748,14 @@ const char *
__p_option(option)
u_long option;
{
+ static char nbuf[40];
+
switch (option) {
case RES_INIT: return "init";
case RES_DEBUG: return "debug";
- case RES_AAONLY: return "aaonly";
+ case RES_AAONLY: return "aaonly(unimpl)";
case RES_USEVC: return "usevc";
- case RES_PRIMARY: return "primry";
+ case RES_PRIMARY: return "primry(unimpl)";
case RES_IGNTC: return "igntc";
case RES_RECURSE: return "recurs";
case RES_DEFNAMES: return "defnam";
@@ -707,7 +763,8 @@ __p_option(option)
case RES_DNSRCH: return "dnsrch";
case RES_INSECURE1: return "insecure1";
case RES_INSECURE2: return "insecure2";
- default: sprintf(nbuf, "?0x%x?", option); return nbuf;
+ default: sprintf(nbuf, "?0x%lx?", (u_long)option);
+ return (nbuf);
}
}
@@ -718,6 +775,7 @@ char *
__p_time(value)
u_int32_t value;
{
+ static char nbuf[40];
int secs, mins, hours, days;
register char *p;
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
index 347e5b6d3e726..68f35c256d810 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -53,11 +53,12 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
-static char rcsid[] = "$Id: res_init.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
+static char rcsid[] = "$Id: res_init.c,v 1.4 1995/05/30 05:40:55 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
@@ -69,9 +70,13 @@ static char rcsid[] = "$Id: res_init.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
#include <stdlib.h>
#include <string.h>
+#include "res_config.h"
+
static void res_setoptions __P((char *, char *));
#ifdef RESOLVSORT
+static const char sort_mask[] = "/&";
+#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
static u_int32_t net_mask __P((struct in_addr));
#endif
@@ -102,11 +107,12 @@ struct __res_state _res;
*
* Return 0 if completes successfully, -1 on error
*/
+int
res_init()
{
register FILE *fp;
register char *cp, **pp;
- register int n, dots;
+ register int n;
char buf[BUFSIZ];
int nserv = 0; /* number of nameserver records read from file */
int haveenv = 0;
@@ -115,9 +121,12 @@ res_init()
int nsort = 0;
char *net;
#endif
+#ifndef RFC1535
+ int dots;
+#endif
/*
- * These four fields used to be statically initialized. This made
+ * These three fields used to be statically initialized. This made
* it hard to use this code in a shared library. It is necessary,
* now that we're doing dynamic initialization here, that we preserve
* the old semantics: if an application modifies one of these three
@@ -128,14 +137,27 @@ res_init()
* will follow. Zero for any of these fields would make no sense,
* so one can safely assume that the applications were already getting
* unexpected results.
+ *
+ * _res.options is tricky since some apps were known to diddle the bits
+ * before res_init() was first called. We can't replicate that semantic
+ * with dynamic initialization (they may have turned bits off that are
+ * set in RES_DEFAULT). Our solution is to declare such applications
+ * "broken". They could fool us by setting RES_INIT but none do (yet).
*/
if (!_res.retrans)
_res.retrans = RES_TIMEOUT;
if (!_res.retry)
_res.retry = 4;
- if (!_res.options)
+ if (!(_res.options & RES_INIT))
_res.options = RES_DEFAULT;
+ /*
+ * This one used to initialize implicitly to zero, so unless the app
+ * has set it to something in particular, we can randomize it now.
+ */
+ if (!_res.id)
+ _res.id = res_randomid();
+
#ifdef USELOOPBACK
_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
@@ -181,14 +203,19 @@ res_init()
*pp++ = 0;
}
+#define MATCH(line, name) \
+ (!strncmp(line, name, sizeof(name) - 1) && \
+ (line[sizeof(name) - 1] == ' ' || \
+ line[sizeof(name) - 1] == '\t'))
+
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
- if ((*buf == ';') || (*buf == '#'))
+ if (*buf == ';' || *buf == '#')
continue;
/* read default domain name */
- if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
+ if (MATCH(buf, "domain")) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("domain") - 1;
@@ -204,7 +231,7 @@ res_init()
continue;
}
/* set search list */
- if (!strncmp(buf, "search", sizeof("search") - 1)) {
+ if (MATCH(buf, "search")) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("search") - 1;
@@ -223,9 +250,7 @@ res_init()
cp = _res.defdname;
pp = _res.dnsrch;
*pp++ = cp;
- for (n = 0;
- *cp && pp < _res.dnsrch + MAXDNSRCH;
- cp++) {
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
if (*cp == ' ' || *cp == '\t') {
*cp = 0;
n = 1;
@@ -243,8 +268,7 @@ res_init()
continue;
}
/* read nameservers to query */
- if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
- nserv < MAXNS) {
+ if (MATCH(buf, "nameserver") && nserv < MAXNS) {
struct in_addr a;
cp = buf + sizeof("nameserver") - 1;
@@ -260,7 +284,7 @@ res_init()
continue;
}
#ifdef RESOLVSORT
- if (!strncmp(buf, "sortlist", sizeof("sortlist") -1)) {
+ if (MATCH(buf, "sortlist")) {
struct in_addr a;
cp = buf + sizeof("sortlist") - 1;
@@ -270,17 +294,18 @@ res_init()
if (*cp == '\0' || *cp == '\n' || *cp == ';')
break;
net = cp;
- while (*cp && *cp != '/' &&
+ while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
if (inet_aton(net, &a)) {
_res.sort_list[nsort].addr = a;
- if (n == '/') {
+ if (ISSORTMASK(n)) {
*cp++ = n;
net = cp;
- while (*cp && isascii(*cp) && !isspace(*cp))
+ while (*cp && *cp != ';' &&
+ isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
@@ -296,12 +321,12 @@ res_init()
}
nsort++;
}
- *cp++ = n;
+ *cp = n;
}
continue;
}
#endif
- if (!strncmp(buf, "options", sizeof("options") -1)) {
+ if (MATCH(buf, "options")) {
res_setoptions(buf + sizeof("options") - 1, "conf");
continue;
}
@@ -312,13 +337,11 @@ res_init()
_res.nsort = nsort;
#endif
(void) fclose(fp);
- } /*if(fopen)*/
- if (_res.defdname[0] == 0) {
- if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
- (cp = strchr(buf, '.'))) {
- (void)strcpy(_res.defdname, cp + 1);
- }
}
+ if (_res.defdname[0] == 0 &&
+ gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+ (cp = strchr(buf, '.')) != NULL)
+ strcpy(_res.defdname, cp + 1);
/* find components of local domain that might be searched */
if (havesearch == 0) {
@@ -333,32 +356,30 @@ res_init()
cp = _res.defdname;
while (pp < _res.dnsrch + MAXDFLSRCH) {
- if (dots < LOCALDOMAINPARTS) {
+ if (dots < LOCALDOMAINPARTS)
break;
- }
cp = strchr(cp, '.') + 1; /* we know there is one */
*pp++ = cp;
dots--;
}
*pp = NULL;
+#ifdef DEBUG
if (_res.options & RES_DEBUG) {
printf(";; res_init()... default dnsrch list:\n");
- for (pp = _res.dnsrch; *pp; pp++) {
+ for (pp = _res.dnsrch; *pp; pp++)
printf(";;\t%s\n", *pp);
- }
printf(";;\t..END..\n");
}
+#endif /* DEBUG */
#endif /*!RFC1535*/
}
- if ((cp = getenv("RES_OPTIONS")) != NULL) {
+ if ((cp = getenv("RES_OPTIONS")) != NULL)
res_setoptions(cp, "env");
- }
_res.options |= RES_INIT;
return (0);
}
-
static void
res_setoptions(options, source)
char *options, *source;
@@ -366,10 +387,11 @@ res_setoptions(options, source)
char *cp = options;
int i;
- if (_res.options & RES_DEBUG) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
printf(";; res_setoptions(\"%s\", \"%s\")...\n",
options, source);
- }
+#endif
while (*cp) {
/* skip leading and inner runs of spaces */
while (*cp == ' ' || *cp == '\t')
@@ -381,16 +403,19 @@ res_setoptions(options, source)
_res.ndots = i;
else
_res.ndots = RES_MAXNDOTS;
- if (_res.options & RES_DEBUG) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
printf(";;\tndots=%d\n", _res.ndots);
- }
+#endif
} else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
+#ifdef DEBUG
if (!(_res.options & RES_DEBUG)) {
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
options, source);
_res.options |= RES_DEBUG;
}
printf(";;\tdebug\n");
+#endif
} else {
/* XXX - print a warning here? */
}
@@ -401,6 +426,7 @@ res_setoptions(options, source)
}
#ifdef RESOLVSORT
+/* XXX - should really support CIDR which means explicit masks always. */
static u_int32_t
net_mask(in) /* XXX - should really use system's version of this */
struct in_addr in;
@@ -411,7 +437,15 @@ net_mask(in) /* XXX - should really use system's version of this */
return (htonl(IN_CLASSA_NET));
else if (IN_CLASSB(i))
return (htonl(IN_CLASSB_NET));
- else
- return (htonl(IN_CLASSC_NET));
+ return (htonl(IN_CLASSC_NET));
}
#endif
+
+u_int16_t
+res_randomid()
+{
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
+}
diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c
index 7788d165b2fff..2e38bf13d852a 100644
--- a/lib/libc/net/res_mkquery.c
+++ b/lib/libc/net/res_mkquery.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_mkquery.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
+static char rcsid[] = "$Id: res_mkquery.c,v 1.4 1995/05/30 05:40:56 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -63,6 +63,9 @@ static char rcsid[] = "$Id: res_mkquery.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
#include <stdio.h>
#include <resolv.h>
#include <string.h>
+#include <netdb.h>
+
+#include "res_config.h"
/*
* Form all types of queries.
@@ -82,12 +85,20 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
register HEADER *hp;
register u_char *cp;
register int n;
+#ifdef ALLOW_UPDATES
struct rrec *newrr = (struct rrec *) newrr_in;
+#endif
u_char *dnptrs[20], **dpp, **lastdnptr;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_mkquery(%d, %s, %d, %d)\n",
op, dname, class, type);
+#endif
/*
* Initialize header fields.
*/
@@ -97,7 +108,6 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
hp->opcode = op;
- hp->pr = (_res.options & RES_PRIMARY) != 0;
hp->rd = (_res.options & RES_RECURSE) != 0;
hp->rcode = NOERROR;
cp = buf + HFIXEDSZ;
@@ -110,7 +120,8 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
* perform opcode specific processing
*/
switch (op) {
- case QUERY:
+ case QUERY: /*FALLTHROUGH*/
+ case NS_NOTIFY_OP:
if ((buflen -= QFIXEDSZ) < 0)
return(-1);
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
@@ -222,8 +233,9 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
}
hp->ancount = htons(0);
break;
-
#endif /* ALLOW_UPDATES */
+ default:
+ return (-1);
}
return (cp - buf);
}
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c
index ed923eb6e31b1..f31a185bfd10d 100644
--- a/lib/libc/net/res_query.c
+++ b/lib/libc/net/res_query.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_query.c,v 1.3 1994/09/25 17:45:40 pst Exp $";
+static char rcsid[] = "$Id: res_query.c,v 1.4 1995/05/30 05:40:57 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -66,16 +66,10 @@ static char rcsid[] = "$Id: res_query.c,v 1.3 1994/09/25 17:45:40 pst Exp $";
#include <resolv.h>
#include <ctype.h>
#include <errno.h>
-#if defined(BSD) && (BSD >= 199306)
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <stdlib.h>
+#include <string.h>
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+#include "res_config.h"
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
@@ -109,31 +103,41 @@ res_query(name, class, type, answer, anslen)
hp->rcode = NOERROR; /* default */
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
return (-1);
+ }
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query(%s, %d, %d)\n", name, class, type);
+#endif
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
buf, sizeof(buf));
if (n <= 0) {
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query: mkquery failed\n");
+#endif
h_errno = NO_RECOVERY;
return (n);
}
n = res_send(buf, n, answer, anslen);
if (n < 0) {
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query: send error\n");
+#endif
h_errno = TRY_AGAIN;
return (n);
}
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; rcode = %d, ancount=%d\n", hp->rcode,
ntohs(hp->ancount));
+#endif
switch (hp->rcode) {
case NXDOMAIN:
h_errno = HOST_NOT_FOUND;
@@ -175,22 +179,23 @@ res_search(name, class, type, answer, anslen)
int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
return (-1);
-
+ }
errno = 0;
h_errno = HOST_NOT_FOUND; /* default, if we never query */
dots = 0;
for (cp = name; *cp; cp++)
dots += (*cp == '.');
trailing_dot = 0;
- if ((cp > name) && (*--cp == '.'))
+ if (cp > name && *--cp == '.')
trailing_dot++;
/*
* if there aren't any dots, it could be a user-level alias
*/
- if ((!dots) && (cp = __hostalias(name)))
+ if (!dots && (cp = __hostalias(name)) != NULL)
return (res_query(cp, class, type, answer, anslen));
/*
@@ -212,9 +217,8 @@ res_search(name, class, type, answer, anslen)
* - there is at least one dot, there is no trailing dot,
* and RES_DNSRCH is set.
*/
- if (((!dots) && _res.options & RES_DEFNAMES) ||
- (dots && (!trailing_dot) && _res.options & RES_DNSRCH)
- ) {
+ if ((!dots && (_res.options & RES_DEFNAMES)) ||
+ (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
int done = 0;
for (domain = (const char * const *)_res.dnsrch;
@@ -279,7 +283,6 @@ res_search(name, class, type, answer, anslen)
ret = res_querydomain(name, NULL, class, type, answer, anslen);
if (ret > 0)
return (ret);
- saved_herrno = h_errno;
}
/* if we got here, we didn't satisfy the search.
@@ -313,9 +316,15 @@ res_querydomain(name, domain, class, type, answer, anslen)
const char *longname = nbuf;
int n;
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_querydomain(%s, %s, %d, %d)\n",
name, domain?domain:"<Nil>", class, type);
+#endif
if (domain == NULL) {
/*
* Check for trailing '.';
@@ -327,10 +336,8 @@ res_querydomain(name, domain, class, type, answer, anslen)
nbuf[n] = '\0';
} else
longname = name;
- } else {
- sprintf(nbuf, "%.*s.%.*s",
- MAXDNAME, name, MAXDNAME, domain);
- }
+ } else
+ sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
return (res_query(longname, class, type, answer, anslen));
}
@@ -345,22 +352,28 @@ __hostalias(name)
char buf[BUFSIZ];
static char abuf[MAXDNAME];
+ if (_res.options & RES_NOALIASES)
+ return (NULL);
file = getenv("HOSTALIASES");
if (file == NULL || (fp = fopen(file, "r")) == NULL)
return (NULL);
+ setbuf(fp, NULL);
buf[sizeof(buf) - 1] = '\0';
while (fgets(buf, sizeof(buf), fp)) {
- for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1);
+ for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
+ ;
if (!*cp1)
break;
*cp1 = '\0';
if (!strcasecmp(buf, name)) {
- while (isspace(*++cp1));
+ while (isspace(*++cp1))
+ ;
if (!*cp1)
break;
- for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2);
+ for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
+ ;
abuf[sizeof(abuf) - 1] = *cp2 = '\0';
- (void)strncpy(abuf, cp1, sizeof(abuf) - 1);
+ strncpy(abuf, cp1, sizeof(abuf) - 1);
fclose(fp);
return (abuf);
}
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index 8ee0a928f4fba..8d3e410f9e659 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
+static char rcsid[] = "$Id: res_send.c,v 1.4 1995/05/30 05:40:58 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
/* change this to "0"
@@ -61,7 +61,7 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
* of multi-homed SunOS
* ("broken") name servers.
*/
-#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
+#define CHECK_SRVR_ADDR 1 /* XXX - should be in res_config.h */
/*
* Send query to name server and wait for reply.
@@ -78,8 +78,12 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
#include <stdio.h>
#include <errno.h>
#include <resolv.h>
+#include <netdb.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+#include "res_config.h"
void _res_close __P((void));
@@ -87,12 +91,17 @@ static int s = -1; /* socket used for communications */
static int connected = 0; /* is the socket connected */
static int vc = 0; /* is the socket a virtual ciruit? */
+#ifndef DEBUG
+# define Dprint(cond, args) /*empty*/
+# define DprintQ(cond, args, query, size) /*empty*/
+# define Aerror(file, string, error, address) /*empty*/
+# define Perror(file, string, error) /*empty*/
+#else
# define Dprint(cond, args) if (cond) {fprintf args;} else {}
-# define DprintQ(cond, args, query) if (cond) {\
+# define DprintQ(cond, args, query, size) if (cond) {\
fprintf args;\
- __p_query(query);\
+ __fp_nquery(query, size, stdout);\
} else {}
-
static void
Aerror(file, string, error, address)
FILE *file;
@@ -103,15 +112,14 @@ Aerror(file, string, error, address)
int save = errno;
if (_res.options & RES_DEBUG) {
- fprintf(file, "res_send: %s ([%s].%d): %s\n",
+ fprintf(file, "res_send: %s ([%s].%u): %s\n",
string,
inet_ntoa(address.sin_addr),
- address.sin_port,
+ ntohs(address.sin_port),
strerror(error));
}
errno = save;
}
-
static void
Perror(file, string, error)
FILE *file;
@@ -126,6 +134,7 @@ Perror(file, string, error)
}
errno = save;
}
+#endif
static res_send_qhook Qhook = NULL;
static res_send_rhook Rhook = NULL;
@@ -134,6 +143,7 @@ void
res_send_setqhook(hook)
res_send_qhook hook;
{
+
Qhook = hook;
}
@@ -141,11 +151,12 @@ void
res_send_setrhook(hook)
res_send_rhook hook;
{
+
Rhook = hook;
}
/* int
- * our_server(ina)
+ * res_isourserver(ina)
* looks up "ina" in _res.ns_addr_list[]
* returns:
* 0 : not found
@@ -153,8 +164,8 @@ res_send_setrhook(hook)
* author:
* paul vixie, 29may94
*/
-static int
-our_server(inp)
+int
+res_isourserver(inp)
const struct sockaddr_in *inp;
{
struct sockaddr_in ina;
@@ -177,15 +188,17 @@ our_server(inp)
}
/* int
- * name_in_query(name, type, class, buf, eom)
+ * res_nameinquery(name, type, class, buf, eom)
* look for (name,type,class) in the query section of packet (buf,eom)
* returns:
* -1 : format error
* 0 : not found
* >0 : found
+ * author:
+ * paul vixie, 29may94
*/
-static int
-name_in_query(name, type, class, buf, eom)
+int
+res_nameinquery(name, type, class, buf, eom)
const char *name;
register int type, class;
const u_char *buf, *eom;
@@ -212,16 +225,18 @@ name_in_query(name, type, class, buf, eom)
}
/* int
- * queries_match(buf1, eom1, buf2, eom2)
+ * res_queriesmatch(buf1, eom1, buf2, eom2)
* is there a 1:1 mapping of (name,type,class)
* in (buf1,eom1) and (buf2,eom2)?
* returns:
* -1 : format error
* 0 : not a 1:1 mapping
* >0 : is a 1:1 mapping
+ * author:
+ * paul vixie, 29may94
*/
-static int
-queries_match(buf1, eom1, buf2, eom2)
+int
+res_queriesmatch(buf1, eom1, buf2, eom2)
const u_char *buf1, *eom1;
const u_char *buf2, *eom2;
{
@@ -240,7 +255,7 @@ queries_match(buf1, eom1, buf2, eom2)
cp += n;
ttype = _getshort(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ;
- if (!name_in_query(tname, ttype, tclass, buf2, eom2))
+ if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
return (0);
}
return (1);
@@ -255,21 +270,20 @@ res_send(buf, buflen, ans, anssiz)
{
HEADER *hp = (HEADER *) buf;
HEADER *anhp = (HEADER *) ans;
- int gotsomewhere = 0,
- connreset = 0,
- terrno = ETIMEDOUT;
-
+ int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
register int n;
- int try, v_circuit, resplen, ns;
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
- DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
- (stdout, ";; res_send()\n"), buf);
- if (!(_res.options & RES_INIT)) {
- if (res_init() == -1)
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ /* errno should have been set by res_init() in this case. */
return (-1);
}
+ DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+ (stdout, ";; res_send()\n"), buf, buflen);
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ gotsomewhere = 0;
+ connreset = 0;
+ terrno = ETIMEDOUT;
badns = 0;
/*
@@ -290,12 +304,8 @@ res_send(buf, buflen, ans, anssiz)
do {
res_sendhookact act;
- act = (*Qhook)(&nsap,
- &buf,
- &buflen,
- ans,
- anssiz,
- &resplen);
+ act = (*Qhook)(&nsap, &buf, &buflen,
+ ans, anssiz, &resplen);
switch (act) {
case res_goahead:
done = 1;
@@ -338,16 +348,15 @@ res_send(buf, buflen, ans, anssiz)
if (s >= 0)
_res_close();
- s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
+ s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
terrno = errno;
Perror(stderr, "socket(vc)", errno);
return (-1);
}
- if (connect(s,
- (struct sockaddr *)nsap,
- sizeof(struct sockaddr))
- < 0) {
+ errno = 0;
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof(struct sockaddr)) < 0) {
terrno = errno;
Aerror(stderr, "connect/vc",
errno, *nsap);
@@ -414,8 +423,7 @@ res_send(buf, buflen, ans, anssiz)
len = resplen;
cp = ans;
while (len != 0 &&
- (n = read(s, (char *)cp, (int)len)) > 0
- ) {
+ (n = read(s, (char *)cp, (int)len)) > 0) {
cp += n;
len -= n;
}
@@ -433,7 +441,7 @@ res_send(buf, buflen, ans, anssiz)
anhp->tc = 1;
len = resplen - anssiz;
while (len != 0) {
- char junk[512];
+ char junk[PACKETSZ];
n = (len > sizeof(junk)
? sizeof(junk)
@@ -456,9 +464,9 @@ res_send(buf, buflen, ans, anssiz)
if ((s < 0) || vc) {
if (vc)
_res_close();
- s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
+ s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
- bad_dg_sock: terrno = errno;
+ terrno = errno;
Perror(stderr, "socket(dg)", errno);
return (-1);
}
@@ -485,11 +493,9 @@ res_send(buf, buflen, ans, anssiz)
* receive a response from another server.
*/
if (!connected) {
- if (connect(s,
- (struct sockaddr *)nsap,
+ if (connect(s, (struct sockaddr *)nsap,
sizeof(struct sockaddr)
- ) < 0
- ) {
+ ) < 0) {
Aerror(stderr,
"connect(dg)",
errno, *nsap);
@@ -499,7 +505,7 @@ res_send(buf, buflen, ans, anssiz)
}
connected = 1;
}
- if (send(s, buf, buflen, 0) != buflen) {
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
Perror(stderr, "send", errno);
badns |= (1<<ns);
_res_close();
@@ -523,7 +529,7 @@ res_send(buf, buflen, ans, anssiz)
connected = 0;
errno = 0;
}
- if (sendto(s, buf, buflen, 0,
+ if (sendto(s, (char*)buf, buflen, 0,
(struct sockaddr *)nsap,
sizeof(struct sockaddr))
!= buflen) {
@@ -558,14 +564,14 @@ res_send(buf, buflen, ans, anssiz)
* timeout
*/
Dprint(_res.options & RES_DEBUG,
- (stdout, ";; timeout\n")
- );
+ (stdout, ";; timeout\n"));
gotsomewhere = 1;
_res_close();
goto next_ns;
}
+ errno = 0;
fromlen = sizeof(struct sockaddr_in);
- resplen = recvfrom(s, ans, anssiz, 0,
+ resplen = recvfrom(s, (char*)ans, anssiz, 0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
Perror(stderr, "recvfrom", errno);
@@ -582,12 +588,12 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; old answer:\n"),
- ans);
+ ans, resplen);
goto wait;
}
#if CHECK_SRVR_ADDR
if (!(_res.options & RES_INSECURE1) &&
- !our_server(&from)) {
+ !res_isourserver(&from)) {
/*
* response from wrong server? ignore it.
* XXX - potential security hazard could
@@ -596,12 +602,12 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; not our server:\n"),
- ans);
+ ans, resplen);
goto wait;
}
#endif
if (!(_res.options & RES_INSECURE2) &&
- !queries_match(buf, buf + buflen,
+ !res_queriesmatch(buf, buf + buflen,
ans, ans + anssiz)) {
/*
* response contains wrong query? ignore it.
@@ -611,7 +617,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; wrong query name:\n"),
- ans);
+ ans, resplen);
goto wait;
}
if (anhp->rcode == SERVFAIL ||
@@ -619,9 +625,11 @@ res_send(buf, buflen, ans, anssiz)
anhp->rcode == REFUSED) {
DprintQ(_res.options & RES_DEBUG,
(stdout, "server rejected query:\n"),
- ans);
+ ans, resplen);
badns |= (1<<ns);
_res_close();
+ /* don't retry if called from dig */
+ if (!_res.pfcode)
goto next_ns;
}
if (!(_res.options & RES_IGNTC) && anhp->tc) {
@@ -630,8 +638,7 @@ res_send(buf, buflen, ans, anssiz)
* use TCP with same server.
*/
Dprint(_res.options & RES_DEBUG,
- (stdout, ";; truncated answer\n")
- );
+ (stdout, ";; truncated answer\n"));
v_circuit = 1;
_res_close();
goto same_ns;
@@ -640,7 +647,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; got answer:\n"),
- ans);
+ ans, resplen);
/*
* If using virtual circuits, we assume that the first server
* is preferred over the rest (i.e. it is on the local
@@ -659,12 +666,8 @@ res_send(buf, buflen, ans, anssiz)
do {
res_sendhookact act;
- act = (*Rhook)(nsap,
- buf,
- buflen,
- ans,
- anssiz,
- &resplen);
+ act = (*Rhook)(nsap, buf, buflen,
+ ans, anssiz, &resplen);
switch (act) {
case res_goahead:
case res_done:
@@ -691,14 +694,13 @@ res_send(buf, buflen, ans, anssiz)
} /*foreach ns*/
} /*foreach retry*/
_res_close();
- if (!v_circuit) {
+ if (!v_circuit)
if (!gotsomewhere)
errno = ECONNREFUSED; /* no nameservers found */
else
errno = ETIMEDOUT; /* no answer obtained */
- } else {
+ else
errno = terrno;
- }
return (-1);
}
diff --git a/usr.bin/dig/dig.c b/usr.bin/dig/dig.c
index e88b5d57d83da..0557412088d9e 100644
--- a/usr.bin/dig/dig.c
+++ b/usr.bin/dig/dig.c
@@ -1,5 +1,5 @@
#ifndef lint
-static char rcsid[] = "$Id: dig.c,v 1.3 1995/05/09 13:13:21 rgrimes Exp $";
+static char rcsid[] = "$Id: dig.c,v 1.4 1995/05/30 06:29:46 rgrimes Exp $";
#endif
/*
@@ -164,7 +164,7 @@ static char rcsid[] = "$Id: dig.c,v 1.3 1995/05/09 13:13:21 rgrimes Exp $";
#include <fcntl.h>
#include <stdlib.h>
-#include "../../usr.sbin/nslookup/res.h"
+#include "res.h"
#define PRF_DEF 0x2ff9
#define PRF_MIN 0xA930
@@ -197,8 +197,7 @@ jmp_buf env;
HostInfo *defaultPtr = NULL;
HostInfo curHostInfo, defaultRec;
int curHostValid = FALSE;
-int queryType = T_A;
-int queryClass = C_IN;
+int queryType, queryClass;
extern int StringToClass(), StringToType(); /* subr.c */
#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD)
FILE *yyin = NULL;
@@ -221,7 +220,7 @@ stackarg(y, l)
case '\t':
case ' ':
l++; break;
- case NULL:
+ case '\0':
case '\n':
done++;
*y = NULL;
@@ -246,7 +245,12 @@ main(argc, argv)
{
struct hostent *hp;
short port = htons(NAMESERVER_PORT);
- u_char packet[PACKETSZ];
+ /* Wierd stuff for SPARC alignment, hurts nothing else. */
+ union {
+ HEADER header_;
+ u_char packet_[PACKETSZ];
+ } packet_;
+#define packet (packet_.packet_)
u_char answer[8*1024];
int n;
char doping[90];
@@ -259,8 +263,8 @@ main(argc, argv)
char *srv;
int anyflag = 0;
int sticky = 0;
- int tmp;
- int qtype = 1, qclass = 1;
+ int tmp;
+ int qtypeSet;
int addrflag = 0;
int zone = 0;
int bytes_out, bytes_in;
@@ -283,6 +287,7 @@ main(argc, argv)
res_init();
_res.pfcode = PRF_DEF;
+ qtypeSet = 0;
gethostname(myhostname, (sizeof myhostname));
defsrv = strcat(defbuf, inet_ntoa(_res.nsaddr.sin_addr));
res_x = _res;
@@ -296,7 +301,7 @@ main(argc, argv)
if ((((afile = (char *) getenv("LOCALDEF")) != (char *) NULL) &&
((fp = open(afile, O_RDONLY)) > 0)) ||
((fp = open(SAVEENV, O_RDONLY)) > 0)) {
- read(fp, &res_x, (sizeof res_x));
+ read(fp, (char *)&res_x, (sizeof res_x));
close(fp);
_res = res_x;
}
@@ -362,7 +367,8 @@ main(argc, argv)
stackarg(ay, qptr);
/* defaults */
- qtype = qclass = 1;
+ queryType = T_NS;
+ queryClass = C_IN;
zone = 0;
*pingstr = 0;
srv = NULL;
@@ -408,11 +414,11 @@ main(argc, argv)
case 'c':
if ((tmp = atoi(*++argv))
|| *argv[0]=='0') {
- qclass = tmp;
+ queryClass = tmp;
} else if (tmp = StringToClass(*argv,
0, NULL)
) {
- qclass = tmp;
+ queryClass = tmp;
} else {
printf(
"; invalid class specified\n"
@@ -422,11 +428,13 @@ main(argc, argv)
case 't':
if ((tmp = atoi(*++argv))
|| *argv[0]=='0') {
- qtype = tmp;
+ queryType = tmp;
+ qtypeSet++;
} else if (tmp = StringToType(*argv,
0, NULL)
) {
- qtype = tmp;
+ queryType = tmp;
+ qtypeSet++;
} else {
printf(
"; invalid type specified\n"
@@ -434,8 +442,10 @@ main(argc, argv)
}
break;
case 'x':
- if (qtype == T_A)
- qtype = T_ANY;
+ if (!qtypeSet) {
+ queryType = T_ANY;
+ qtypeSet++;
+ }
if (!(addrc = *++argv)) {
printf(
"; no arg for -x?\n"
@@ -470,20 +480,21 @@ main(argc, argv)
continue;
} /* if '-' */
- if ((tmp = StringToType(*argv, -1, NULL)) != -1) {
- if ((T_ANY == tmp) && anyflag++) {
- qclass = C_ANY;
- continue;
+ if ((tmp = StringToType(*argv, -1, NULL)) != -1) {
+ if ((T_ANY == tmp) && anyflag++) {
+ queryClass = C_ANY;
+ continue;
}
if (T_AXFR == tmp) {
_res.pfcode = PRF_ZONE;
zone++;
} else {
- qtype = tmp;
+ queryType = tmp;
+ qtypeSet++;
}
} else if ((tmp = StringToClass(*argv, -1, NULL))
- != -1) {
- qclass = tmp;
+ != -1) {
+ queryClass = tmp;
} else {
bzero(domain, (sizeof domain));
sprintf(domain,"%s",*argv);
@@ -518,7 +529,7 @@ main(argc, argv)
((fp = open(SAVEENV,
O_WRONLY|O_CREAT|O_TRUNC,
S_IREAD|S_IWRITE)) > 0)) {
- write(fp, &_res, (sizeof _res));
+ write(fp, (char *)&_res, (sizeof _res));
close(fp);
}
envsave = 0;
@@ -622,7 +633,13 @@ main(argc, argv)
continue;
}
- bytes_out = n = res_mkquery(QUERY, domain, qclass, qtype,
+ if (*domain && !qtypeSet) {
+ queryType = T_A;
+ qtypeSet++;
+ }
+
+ bytes_out = n = res_mkquery(QUERY, domain,
+ queryClass, queryType,
NULL, 0, NULL,
packet, sizeof(packet));
if (n < 0) {
@@ -1011,7 +1028,7 @@ printZone(zone, sin)
__putshort(msglen, (u_char *)&len);
if (write(sockFD, (char *)&len, INT16SZ) != INT16SZ ||
- write(sockFD, (char *) &buf, msglen) != msglen) {
+ write(sockFD, (char *)&buf, msglen) != msglen) {
int e = errno;
perror(";; write");
(void) close(sockFD);
@@ -1046,7 +1063,7 @@ printZone(zone, sin)
* The server sent too much data to fit the existing buffer --
* allocate a new one.
*/
- if (len > answerLen) {
+ if (len > (u_int)answerLen) {
if (answerLen != 0) {
free(answer);
}
diff --git a/usr.bin/host/host.c b/usr.bin/host/host.c
index 8a138783a6d14..22839c3b76d48 100644
--- a/usr.bin/host/host.c
+++ b/usr.bin/host/host.c
@@ -67,7 +67,7 @@ char copyright[] =
*/
#ifndef lint
-static char rcsid[] = "$Id: host.c,v 1.2 1994/09/22 21:52:03 pst Exp $";
+static char rcsid[] = "$Id: host.c,v 1.3 1995/05/30 06:30:50 rgrimes Exp $";
#endif /* not lint */
#include <sys/types.h>
@@ -360,10 +360,10 @@ printanswer(hp)
printf("\n\n");
}
-hperror(errno)
-int errno;
+hperror(errnum)
+int errnum;
{
-switch(errno) {
+switch(errnum) {
case HOST_NOT_FOUND:
fprintf(stderr,"Host not found.\n");
break;
@@ -459,7 +459,7 @@ gethostinfo(name)
char *name;
{
register char *cp, **domain;
- int n;
+ u_int n;
int hp;
int nDomain;
int asis = 0;
@@ -765,15 +765,20 @@ pr_rr(cp, msg, file, filter)
case T_HINFO:
case T_ISDN:
- if (n = *cp++) {
- if (doprint)
- fprintf(file,"%c%.*s", punc, n, cp);
- cp += n;
- }
- if (n = *cp++) {
- if (doprint)
- fprintf(file,"%c%.*s", punc, n, cp);
- cp += n;
+ {
+ u_char *cp2 = cp + dlen;
+ if (n = *cp++) {
+ if (doprint)
+ fprintf(file,"%c%.*s", punc, n, cp);
+ cp += n;
+ }
+ if ((cp < cp2) && (n = *cp++)) {
+ if (doprint)
+ fprintf(file,"%c%.*s", punc, n, cp);
+ cp += n;
+ } else if (type == T_HINFO)
+ if (doprint)
+ fprintf(file,"\n; *** Warning *** OS-type missing");
}
break;
@@ -805,10 +810,13 @@ pr_rr(cp, msg, file, filter)
case T_AFSDB:
case T_RT:
if (doprint)
- if (verbose)
- fprintf(file,"\t%ld ",_getshort(cp));
+ if (type == T_MX)
+ fprintf(file," (pri=%d) by ", _getshort(cp));
else
- fprintf(file," ");
+ if (verbose)
+ fprintf(file,"\t%d ", _getshort(cp));
+ else
+ fprintf(file," ");
cp += sizeof(u_short);
cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name));
if (doprint)
@@ -842,7 +850,7 @@ pr_rr(cp, msg, file, filter)
while (cp < end) {
if (n = *cp++) {
for (j = n; j > 0 && cp < end ; j --)
- if (*cp == '\n') {
+ if ((*cp == '\n') || (*cp == '"')) {
if (doprint){
(void) putc('\\', file);
(void) putc(*cp++, file);
@@ -947,7 +955,7 @@ pr_type(type)
case T_MG: /* mail group member */
return("MG");
case T_MX: /* mail routing info */
- return(verbose? "MX" : "mail is handled by");
+ return(verbose? "MX" : "mail is handled");
case T_TXT: /* TXT - descriptive info */
return(verbose? "TXT" : "descriptive text");
case T_AFSDB: /* AFS/DCE info */
@@ -1447,7 +1455,9 @@ DecodeError(result)
case NXDOMAIN: return("Non-existent domain"); break;
case NOTIMP: return("Not implemented"); break;
case REFUSED: return("Query refused"); break;
+#ifdef NOCHANGE
case NOCHANGE: return("No change"); break;
+#endif
case NO_INFO: return("No information"); break;
case ERROR: return("Unspecified error"); break;
case TIME_OUT: return("Timed out"); break;
diff --git a/usr.sbin/named/db_defs.h b/usr.sbin/named/db_defs.h
index 25842760c39b2..115615f716695 100644
--- a/usr.sbin/named/db_defs.h
+++ b/usr.sbin/named/db_defs.h
@@ -1,6 +1,6 @@
/*
* from db.h 4.16 (Berkeley) 6/1/90
- * $Id: db_defs.h,v 1.1.1.1 1994/09/22 19:46:14 pst Exp $
+ * $Id: db_defs.h,v 1.2 1995/05/30 03:48:34 rgrimes Exp $
*/
/*
@@ -152,8 +152,9 @@ struct hashbuf {
#define DB_DELETE 0x04 /* delete data if it exists */
#define DB_NOTAUTH 0x08 /* must not update authoritative data */
#define DB_NOHINTS 0x10 /* don't reflect update in fcachetab */
+#define DB_PRIMING 0x20 /* is this update the result of priming? */
-#define DB_Z_CACHE (0) /* cache-zone-only db_dump() */
+#define DB_Z_CACHE (0) /* cache-zone-only db_dump() */
#define DB_Z_ALL (-1) /* normal db_dump() */
/*
@@ -170,3 +171,10 @@ struct hashbuf {
#define GOODDB -8
#define NEWDB -9
#define AUTH -10
+
+/*
+ * getnum() options
+ */
+#define GETNUM_NONE 0x00 /* placeholder */
+#define GETNUM_SERIAL 0x01 /* treat as serial number */
+#define GETNUM_SCALED 0x02 /* permit "k", "m" suffixes, scale result */
diff --git a/usr.sbin/named/db_dump.c b/usr.sbin/named/db_dump.c
index 2501f2d25cbde..d1256ffbd4150 100644
--- a/usr.sbin/named/db_dump.c
+++ b/usr.sbin/named/db_dump.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_dump.c 4.33 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: db_dump.c,v 1.2 1994/09/22 20:45:00 pst Exp $";
+static char rcsid[] = "$Id: db_dump.c,v 1.3 1995/05/30 03:48:35 rgrimes Exp $";
#endif /* not lint */
/*
@@ -108,7 +108,7 @@ doachkpt()
}
(void) gettime(&tt);
- fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec));
+ fprintf(fp, "; Dumped at %s", ctimel(tt.tv_sec));
fflush(fp);
if (ferror(fp)) {
dprintf(3, (ddt, "doachkpt(write to checkpoint file failed)\n"));
@@ -119,7 +119,7 @@ doachkpt()
int n = scan_root(hashtab);
if (n < MINROOTS) {
- syslog(LOG_ERR, "%d root hints... (too low)", n);
+ syslog(LOG_NOTICE, "%d root hints... (too low)", n);
fprintf(fp, "; ---- Root hint cache dump ----\n");
(void) db_dump(fcachetab, fp, DB_Z_CACHE, "");
}
@@ -134,7 +134,6 @@ doachkpt()
}
}
- (void) fsync(fileno(fp));
if (my_fclose(fp) == EOF) {
return;
}
@@ -161,7 +160,7 @@ scan_root(htp)
struct timeval soon;
int roots = 0;
- dprintf(1, (ddt, "scan_root(0x%x)\n", htp));
+ dprintf(1, (ddt, "scan_root(0x%lx)\n", (u_long)htp));
/* metric by which we determine whether a root NS pointer is still */
/* valid (will be written out if we do a dump). we also add some */
@@ -236,11 +235,12 @@ doadump()
FILE *fp;
dprintf(3, (ddt, "doadump()\n"));
+ syslog(LOG_NOTICE, "dumping nameserver data\n");
if ((fp = fopen(dumpfile, "w")) == NULL)
return;
gettime(&tt);
- fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec));
+ fprintf(fp, "; Dumped at %s", ctimel(tt.tv_sec));
if (zones && nzones)
zt_dump(fp);
fputs(
@@ -256,6 +256,7 @@ doadump()
if (fcachetab != NULL)
(void) db_dump(fcachetab, fp, DB_Z_ALL, "");
(void) my_fclose(fp);
+ syslog(LOG_NOTICE, "finished dumping nameserver data\n");
}
#ifdef ALLOW_UPDATES
@@ -315,7 +316,7 @@ zt_dump(fp)
zp->z_expire, zp->z_minimum);
fprintf(fp, ";\tftime=%ld, xaddr=[%s], state=%04x, pid=%d\n",
zp->z_ftime, inet_ntoa(zp->z_xaddr),
- zp->z_flags, zp->z_xferpid);
+ zp->z_flags, (int)zp->z_xferpid);
sprintf(buf, ";\tz_addr[%d]: ", zp->z_addrcnt);
pre = buf;
for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {
@@ -324,8 +325,19 @@ zt_dump(fp)
}
if (zp->z_addrcnt)
fputc('\n', fp);
+#ifdef BIND_NOTIFY
+ if (zp->z_notifylist) {
+ register struct notify *ap;
+
+ for (ap = zp->z_notifylist; ap; ap = ap->next)
+ fprintf(fp, ";\tNotify [%s] %s",
+ inet_ntoa(ap->addr),
+ ctime(&ap->last));
+ }
+#endif
}
fprintf(fp, ";; --zone table--\n");
+ return (0);
}
int
@@ -388,7 +400,7 @@ db_dump(htp, fp, zone, origin)
fprintf(fp, ".%s.\t", origin); /* ??? */
} else
fprintf(fp, "%s\t", np->n_dname);
- if (strlen(np->n_dname) < 8)
+ if (strlen(np->n_dname) < (size_t)8)
tab = 1;
found_data++;
} else {
@@ -440,8 +452,8 @@ db_dump(htp, fp, zone, origin)
case C_HS:
GETLONG(n, cp);
n = htonl(n);
- fprintf(fp, "%s",
- inet_ntoa(*(struct in_addr *)&n));
+ fputs(inet_ntoa(*(struct in_addr *)&n),
+ fp);
break;
}
if (dp->d_nstime) {
@@ -489,15 +501,15 @@ db_dump(htp, fp, zone, origin)
#endif
cp += strlen((char *)cp) + 1;
GETLONG(n, cp);
- fprintf(fp, "\t\t%lu", n);
+ fprintf(fp, "\t\t%lu", (u_long)n);
GETLONG(n, cp);
- fprintf(fp, " %lu", n);
+ fprintf(fp, " %lu", (u_long)n);
GETLONG(n, cp);
- fprintf(fp, " %lu", n);
+ fprintf(fp, " %lu", (u_long)n);
GETLONG(n, cp);
- fprintf(fp, " %lu", n);
+ fprintf(fp, " %lu", (u_long)n);
GETLONG(n, cp);
- fprintf(fp, " %lu )", n);
+ fprintf(fp, " %lu )", (u_long)n);
#if defined(RETURNSOA) && defined(NCACHE)
if (dp->d_rcode == NXDOMAIN) {
fprintf(fp,";%s.;NXDOMAIN%s-$",cp,sep);
@@ -509,8 +521,16 @@ db_dump(htp, fp, zone, origin)
case T_AFSDB:
case T_RT:
GETSHORT(n, cp);
- fprintf(fp,"%lu", n);
- fprintf(fp," %s.", cp);
+ fprintf(fp, "%lu", (u_long)n);
+ fprintf(fp, " %s.", cp);
+ break;
+
+ case T_PX:
+ GETSHORT(n, cp);
+ fprintf(fp, "%lu", (u_long)n);
+ fprintf(fp, " %s.", cp);
+ cp += strlen((char *)cp) + 1;
+ fprintf(fp, " %s.", cp);
break;
case T_TXT:
@@ -538,7 +558,11 @@ db_dump(htp, fp, zone, origin)
isoa.isoa_len);
(void) fputs(iso_ntoa(&isoa), fp);
break;
-
+#ifdef LOC_RR
+ case T_LOC:
+ (void) fputs(loc_ntoa(dp->d_data, NULL), fp);
+ break;
+#endif /* LOC_RR */
case T_UINFO:
fprintf(fp, "\"%s\"", cp);
break;
@@ -556,8 +580,7 @@ db_dump(htp, fp, zone, origin)
case T_WKS:
GETLONG(addr, cp);
addr = htonl(addr);
- fprintf(fp, "%s ",
- inet_ntoa(*(struct in_addr *)&addr));
+ fputs(inet_ntoa(*(struct in_addr *)&addr), fp);
proto = protocolname(*cp);
cp += sizeof(char);
fprintf(fp, "%s ", proto);
@@ -590,23 +613,10 @@ db_dump(htp, fp, zone, origin)
int TmpSize = 2 * dp->d_size + 30;
char *TmpBuf = (char *) malloc(TmpSize);
if (TmpBuf == NULL) {
- dprintf(1,
- (ddt,
- "Dump T_UNSPEC: bad malloc\n"
- )
- );
- syslog(LOG_ERR,
- "Dump T_UNSPEC: malloc: %m");
TmpBuf = "BAD_MALLOC";
}
if (btoa(cp, dp->d_size, TmpBuf, TmpSize)
== CONV_OVERFLOW) {
- dprintf(1, (ddt,
- "Dump T_UNSPEC: Output buffer overflow\n"
- )
- );
- syslog(LOG_ERR,
- "Dump T_UNSPEC: Output buffer overflow\n");
TmpBuf = "OVERFLOW";
}
fprintf(fp, "%s", TmpBuf);
diff --git a/usr.sbin/named/db_func.h b/usr.sbin/named/db_func.h
index 4237f166ca8fa..57a69fe63813f 100644
--- a/usr.sbin/named/db_func.h
+++ b/usr.sbin/named/db_func.h
@@ -1,6 +1,6 @@
/* db_proc.h - prototypes for functions in db_*.c
*
- * $Id: db_func.h,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $
+ * $Id: db_func.h,v 1.2 1995/05/30 03:48:36 rgrimes Exp $
*/
/* ++from db_update.c++ */
@@ -8,7 +8,8 @@ extern int db_update __P((char name[],
struct databuf *odp,
struct databuf *newdp,
int flags,
- struct hashbuf *htp));
+ struct hashbuf *htp)),
+ findMyZone __P((struct namebuf *np, int class));
/* --from db_update.c-- */
/* ++from db_reload.c++ */
@@ -16,7 +17,7 @@ extern void db_reload __P((void));
/* --from db_reload.c-- */
/* ++from db_save.c++ */
-extern struct namebuf *savename __P((char *));
+extern struct namebuf *savename __P((const char *, int));
#ifdef DMALLOC
extern struct databuf *savedata_tagged __P((char *, int,
int, int, u_int32_t,
@@ -39,6 +40,7 @@ extern void doachkpt __P((void)),
#ifdef ALLOW_UPDATES
extern void zonedump __P((struct zoneinfo *));
#endif
+extern u_int db_getclev __P((const char *));
/* --from db_dump.c-- */
/* ++from db_load.c++ */
@@ -47,8 +49,9 @@ extern void endline __P((FILE *)),
int, char *)),
free_netlist __P((struct netinfo **));
extern int getword __P((char *, int, FILE *)),
- getnum __P((FILE *, char *, int)),
- db_load __P((char *, char *, struct zoneinfo *, int)),
+ getnum __P((FILE *, const char *, int)),
+ db_load __P((const char *, const char *,
+ struct zoneinfo *, const char *)),
position_on_netlist __P((struct in_addr,
struct netinfo *));
extern struct netinfo *addr_on_netlist __P((struct in_addr,
@@ -56,7 +59,9 @@ extern struct netinfo *addr_on_netlist __P((struct in_addr,
/* --from db_load.c-- */
/* ++from db_glue.c++ */
-extern void buildservicelist __P((void)),
+extern const char *sin_ntoa __P((const struct sockaddr_in *));
+extern void panic __P((int, const char *)),
+ buildservicelist __P((void)),
buildprotolist __P((void)),
gettime __P((struct timeval *)),
getname __P((struct namebuf *, char *, int));
@@ -68,11 +73,13 @@ extern int servicenumber __P((char *)),
get_class __P((char *)),
#endif
writemsg __P((int, u_char *, int)),
- dhash __P((u_char *, int)),
+ dhash __P((const u_char *, int)),
+ nhash __P((const char *)),
samedomain __P((const char *, const char *));
extern char *protocolname __P((int)),
*servicename __P((u_int16_t, char *)),
- *savestr __P((char *));
+ *savestr __P((const char *));
+extern const char *inet_etoa __P((const struct sockaddr_in *));
#ifndef BSD
extern int getdtablesize __P((void));
#endif
@@ -87,11 +94,17 @@ extern void addinv __P((struct namebuf *, struct databuf *)),
rminv __P((struct databuf *));
struct invbuf *saveinv __P((void));
#endif
+#ifdef LOC_RR
+extern u_int32_t loc_aton __P((const char *ascii, u_char *binary));
+extern char * loc_ntoa __P((const u_char *binary, char *ascii));
+#endif
+extern char * ctimel __P((long));
+extern struct in_addr data_inaddr __P((const u_char *data));
/* --from db_glue.c-- */
/* ++from db_lookup.c++ */
-extern struct namebuf *nlookup __P((char *, struct hashbuf **,
- char **, int));
+extern struct namebuf *nlookup __P((const char *, struct hashbuf **,
+ const char **, int));
extern int match __P((struct databuf *, int, int));
/* --from db_lookup.c-- */
diff --git a/usr.sbin/named/db_glue.c b/usr.sbin/named/db_glue.c
index f061acd3ba11d..17d6085f5f125 100644
--- a/usr.sbin/named/db_glue.c
+++ b/usr.sbin/named/db_glue.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_glue.c 4.4 (Berkeley) 6/1/90";
-static char rcsid[] = "$Id: db_glue.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
+static char rcsid[] = "$Id: db_glue.c,v 1.2 1995/05/30 03:48:39 rgrimes Exp $";
#endif /* not lint */
/*
@@ -63,6 +63,7 @@ static char rcsid[] = "$Id: db_glue.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
#include <sys/param.h>
#include <sys/stat.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <stdio.h>
#include <syslog.h>
@@ -70,6 +71,7 @@ static char rcsid[] = "$Id: db_glue.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
#include <netdb.h>
#include <resolv.h>
#include <errno.h>
+#include <signal.h>
#include "named.h"
@@ -91,6 +93,37 @@ static const int (*unused_junk)__P((const u_char *, int, u_char *, int)) =
;
#endif
+/*XXX: sin_ntoa() should probably be in libc*/
+const char *
+sin_ntoa(sin)
+ const struct sockaddr_in *sin;
+{
+ static char ret[sizeof("[111.222.333.444].55555")];
+
+ if (!sin)
+ strcpy(ret, "[sin_ntoa(NULL)]");
+ else
+ sprintf(ret, "[%s].%u",
+ inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ return (ret);
+}
+
+/*
+ * XXX: some day we'll make this a varargs function
+ */
+void
+panic(err, msg)
+ int err;
+ const char *msg;
+{
+ if (err == -1)
+ syslog(LOG_CRIT, "%s - ABORT", msg);
+ else
+ syslog(LOG_CRIT, "%s: %s - ABORT", msg, strerror(err));
+ signal(SIGIOT, SIG_DFL);
+ abort();
+}
+
void
buildservicelist()
{
@@ -283,19 +316,19 @@ servicename(port, proto)
return (ss->s_name);
}
-int
+u_int
db_getclev(origin)
- char *origin;
+ const char *origin;
{
- int lev = 0;
- dprintf(1, (ddt, "db_getclev of \"%s\"", origin));
+ u_int lev = 0;
+ dprintf(12, (ddt, "db_getclev of \"%s\"", origin));
if (origin && *origin)
lev++;
while (origin && (origin = strchr(origin, '.'))) {
origin++;
lev++;
}
- dprintf(1, (ddt, " = %d\n", lev));
+ dprintf(12, (ddt, " = %d\n", lev));
return (lev);
}
@@ -326,15 +359,17 @@ int
my_close(fd)
int fd;
{
- int s = close(fd);
+ int s;
- if (s < 0) {
- syslog(LOG_ERR, "close(%d) failed: %m", fd);
- dprintf(3, (ddt, "close(%d) failed: %s\n",
- fd, strerror(errno)));
- } else {
+ do {
+ errno = 0;
+ s = close(fd);
+ } while (s < 0 && errno == EINTR);
+
+ if (s < 0 && errno != EBADF)
+ syslog(LOG_INFO, "close(%d) failed: %m", fd);
+ else
dprintf(3, (ddt, "close(%d) succeeded\n", fd));
- }
return (s);
}
@@ -348,10 +383,10 @@ struct map {
};
static struct map map_class[] = {
- "in", C_IN,
- "chaos", C_CHAOS,
- "hs", C_HS,
- NULL, 0,
+ { "in", C_IN },
+ { "chaos", C_CHAOS },
+ { "hs", C_HS },
+ { NULL, 0 }
};
int
@@ -376,13 +411,10 @@ my_fclose(fp)
int fd = fileno(fp),
s = fclose(fp);
- if (s < 0) {
- syslog(LOG_ERR, "fclose(%d) failed: %m", fd);
- dprintf(3, (ddt, "fclose(%d) failed: %s\n",
- fd, strerror(errno)));
- } else {
+ if (s < 0)
+ syslog(LOG_INFO, "fclose(%d) failed: %m", fd);
+ else
dprintf(3, (ddt, "fclose(%d) succeeded\n", fd));
- }
return (s);
}
@@ -391,19 +423,32 @@ my_fclose(fp)
*/
char *
savestr(str)
- char *str;
+ const char *str;
{
char *cp;
cp = (char *)malloc(strlen(str) + 1);
- if (cp == NULL) {
- syslog(LOG_ERR, "savestr: %m");
- exit(1);
- }
+ if (cp == NULL)
+ panic(errno, "savestr: malloc");
(void) strcpy(cp, str);
return (cp);
}
+/*
+ * Uniform formatting of IP/UDP addresses.
+ */
+const char *
+inet_etoa(sin)
+ const struct sockaddr_in *sin;
+{
+ static char retbuf[sizeof("[xxx.xxx.xxx.xxx].xxxxx")];
+
+ (void) sprintf(retbuf, "[%s].%u",
+ inet_ntoa(sin->sin_addr),
+ ntohs(sin->sin_port));
+ return (retbuf);
+}
+
int
writemsg(rfd, msg, msglen)
int rfd;
@@ -438,8 +483,8 @@ rm_datum(dp, np, pdp)
{
register struct databuf *ndp = dp->d_next;
- dprintf(3, (ddt, "rm_datum(%x, %x, %x) -> %x\n",
- dp, np->n_data, pdp, ndp));
+ dprintf(3, (ddt, "rm_datum(%lx, %lx, %lx) -> %lx\n",
+ (u_long)dp, (u_long)np->n_data, (u_long)pdp, (u_long)ndp));
#ifdef INVQ
rminv(dp);
#endif
@@ -483,13 +528,10 @@ rm_name(np, pp, pnp)
if ( (np->n_data && (msg = "data"))
|| (np->n_hash && (msg = "hash"))
) {
- dprintf(1, (ddt,
- "rm_name(%x(%s)): non-nil %s pointer\n",
- np, np->n_dname?np->n_dname:"Nil", msg));
syslog(LOG_ERR,
- "rm_name(%x(%s)): non-nil %s pointer\n",
- np, np->n_dname?np->n_dname:"Nil", msg);
- abort();
+ "rm_name(%#lx(%s)): non-nil %s pointer\n",
+ (u_long)np, np->n_dname?np->n_dname:"Nil", msg);
+ panic(-1, "rm_name");
}
/* unlink */
@@ -523,7 +565,7 @@ getname(np, buf, buflen)
while (np != NULL) {
if ((i = strlen(np->n_dname))+1 >= buflen) {
*cp = '\0';
- syslog(LOG_ERR, "domain name too long: %s...\n", buf);
+ syslog(LOG_INFO, "domain name too long: %s...\n", buf);
strcpy(buf, "Name_Too_Long");
return;
}
@@ -613,21 +655,20 @@ saveinv()
ip = (struct invbuf *) malloc(sizeof(struct invbuf));
if (ip == NULL) {
- syslog(LOG_ERR, "saveinv: %m");
+ syslog(LOG_ERR, "saveinv: malloc: %m");
exit(1);
}
ip->i_next = NULL;
bzero((char *)ip->i_dname, sizeof(ip->i_dname));
return (ip);
}
-#endif /*INVQ*/
/*
* Compute hash value from data.
*/
int
dhash(dp, dlen)
- u_char *dp;
+ register const u_char *dp;
int dlen;
{
register u_char *cp;
@@ -638,9 +679,31 @@ dhash(dp, dlen)
if (n > 8)
n = 8;
hval = 0;
- for (cp = dp; --n >= 0; ) {
+ while (--n >= 0) {
hval <<= 1;
- hval += *cp++;
+ hval += *dp++;
+ }
+ return (hval % INVHASHSZ);
+}
+#endif /*INVQ*/
+
+/* int
+ * nhash(name)
+ * compute hash for this name and return it; ignore case differences
+ */
+int
+nhash(name)
+ register const char *name;
+{
+ register u_char ch;
+ register unsigned hval;
+
+ hval = 0;
+ while ((ch = (u_char)*name++) != (u_char)'\0') {
+ if (isascii(ch) && isupper(ch))
+ ch = tolower(ch);
+ hval <<= 1;
+ hval += ch;
}
return (hval % INVHASHSZ);
}
@@ -708,3 +771,422 @@ samedomain(a, b)
* ignore trailing dots. */
return (strncasecmp(cp, b, lb)==0);
}
+
+#ifdef LOC_RR
+/*
+ * routines to convert between on-the-wire RR format and zone file format.
+ * Does not contain conversion to/from decimal degrees; divide or multiply
+ * by 60*60*1000 for that.
+ */
+
+static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
+ 1000000,10000000,100000000,1000000000};
+
+/* takes an XeY precision/size value, returns a string representation. */
+static const char *
+precsize_ntoa(prec)
+ u_int8_t prec;
+{
+ static char retbuf[sizeof("90000000.00")];
+ unsigned long val;
+ int mantissa, exponent;
+
+ mantissa = (int)((prec >> 4) & 0x0f) % 10;
+ exponent = (int)((prec >> 0) & 0x0f) % 10;
+
+ val = mantissa * poweroften[exponent];
+
+ (void) sprintf(retbuf,"%d.%.2d", val/100, val%100);
+ return (retbuf);
+}
+
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
+static u_int8_t
+precsize_aton(strptr)
+ char **strptr;
+{
+ unsigned int mval = 0, cmval = 0;
+ u_int8_t retval = 0;
+ register char *cp;
+ register int exponent;
+ register int mantissa;
+
+ cp = *strptr;
+
+ while (isdigit(*cp))
+ mval = mval * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* centimeters */
+ cp++;
+ if (isdigit(*cp)) {
+ cmval = (*cp++ - '0') * 10;
+ if (isdigit(*cp)) {
+ cmval += (*cp++ - '0');
+ }
+ }
+ }
+ cmval = (mval * 100) + cmval;
+
+ for (exponent = 0; exponent < 9; exponent++)
+ if (cmval < poweroften[exponent+1])
+ break;
+
+ mantissa = cmval / poweroften[exponent];
+ if (mantissa > 9)
+ mantissa = 9;
+
+ retval = (mantissa << 4) | exponent;
+
+ *strptr = cp;
+
+ return (retval);
+}
+
+/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
+static u_int32_t
+latlon2ul(latlonstrptr,which)
+ char **latlonstrptr;
+ int *which;
+{
+ register char *cp;
+ u_int32_t retval;
+ int deg = 0, min = 0, secs = 0, secsfrac = 0;
+
+ cp = *latlonstrptr;
+
+ while (isdigit(*cp))
+ deg = deg * 10 + (*cp++ - '0');
+
+ while (isspace(*cp))
+ cp++;
+
+ if (!(isdigit(*cp)))
+ goto fndhemi;
+
+ while (isdigit(*cp))
+ min = min * 10 + (*cp++ - '0');
+
+ while (isspace(*cp))
+ cp++;
+
+ if (!(isdigit(*cp)))
+ goto fndhemi;
+
+ while (isdigit(*cp))
+ secs = secs * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal seconds */
+ cp++;
+ if (isdigit(*cp)) {
+ secsfrac = (*cp++ - '0') * 100;
+ if (isdigit(*cp)) {
+ secsfrac += (*cp++ - '0') * 10;
+ if (isdigit(*cp)) {
+ secsfrac += (*cp++ - '0');
+ }
+ }
+ }
+ }
+
+ while (!isspace(*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace(*cp))
+ cp++;
+
+ fndhemi:
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'E': case 'e':
+ retval = ((unsigned)1<<31)
+ + (((((deg * 60) + min) * 60) + secs) * 1000)
+ + secsfrac;
+ break;
+ case 'S': case 's':
+ case 'W': case 'w':
+ retval = ((unsigned)1<<31)
+ - (((((deg * 60) + min) * 60) + secs) * 1000)
+ - secsfrac;
+ break;
+ default:
+ retval = 0; /* invalid value -- indicates error */
+ break;
+ }
+
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'S': case 's':
+ *which = 1; /* latitude */
+ break;
+ case 'E': case 'e':
+ case 'W': case 'w':
+ *which = 2; /* longitude */
+ break;
+ default:
+ *which = 0; /* error */
+ break;
+ }
+
+ cp++; /* skip the hemisphere */
+
+ while (!isspace(*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace(*cp)) /* move to next field */
+ cp++;
+
+ *latlonstrptr = cp;
+
+ return (retval);
+}
+
+/* converts a zone file representation in a string to an RDATA on-the-wire
+ * representation. */
+u_int32_t
+loc_aton(ascii, binary)
+ const char *ascii;
+ u_char *binary;
+{
+ const char *cp, *maxcp;
+ u_char *bcp;
+
+ u_int32_t latit = 0, longit = 0, alt = 0;
+ u_int32_t lltemp1 = 0, lltemp2 = 0;
+ int altmeters = 0, altfrac = 0, altsign = 1;
+ u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
+ u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
+ u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
+ int which1 = 0, which2 = 0;
+
+ cp = ascii;
+ maxcp = cp + strlen(ascii);
+
+ lltemp1 = latlon2ul(&cp, &which1);
+
+ lltemp2 = latlon2ul(&cp, &which2);
+
+ switch (which1 + which2) {
+ case 3: /* 1 + 2, the only valid combination */
+ if ((which1 == 1) && (which2 == 2)) { /* normal case */
+ latit = lltemp1;
+ longit = lltemp2;
+ } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
+ longit = lltemp1;
+ latit = lltemp2;
+ } else { /* some kind of brokenness */
+ return 0;
+ }
+ break;
+ default: /* we didn't get one of each */
+ return 0;
+ }
+
+ /* altitude */
+ if (*cp == '-') {
+ altsign = -1;
+ cp++;
+ }
+
+ if (*cp == '+')
+ cp++;
+
+ while (isdigit(*cp))
+ altmeters = altmeters * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal meters */
+ cp++;
+ if (isdigit(*cp)) {
+ altfrac = (*cp++ - '0') * 10;
+ if (isdigit(*cp)) {
+ altfrac += (*cp++ - '0');
+ }
+ }
+ }
+
+ alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
+
+ while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace(*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ siz = precsize_aton(&cp);
+
+ while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace(*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ hp = precsize_aton(&cp);
+
+ while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace(*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ vp = precsize_aton(&cp);
+
+ defaults:
+
+ bcp = binary;
+ *bcp++ = (u_int8_t) 0; /* version byte */
+ *bcp++ = siz;
+ *bcp++ = hp;
+ *bcp++ = vp;
+ PUTLONG(latit,bcp);
+ PUTLONG(longit,bcp);
+ PUTLONG(alt,bcp);
+
+ return (16); /* size of RR in octets */
+}
+
+/* takes an on-the-wire LOC RR and prints it in zone file (human readable)
+ format. */
+char *
+loc_ntoa(binary,ascii)
+ const u_char *binary;
+ char *ascii;
+{
+ char tmpbuf[255*3];
+
+ register char *cp;
+ register const u_char *rcp;
+
+ int latdeg, latmin, latsec, latsecfrac;
+ int longdeg, longmin, longsec, longsecfrac;
+ char northsouth, eastwest;
+ int altmeters, altfrac, altsign;
+
+ const int referencealt = 100000 * 100;
+
+ int32_t latval, longval, altval;
+ u_int32_t templ;
+ u_int8_t sizeval, hpval, vpval, versionval;
+
+ char *sizestr, *hpstr, *vpstr;
+
+ rcp = binary;
+ if (ascii)
+ cp = ascii;
+ else {
+ ascii = tmpbuf;
+ cp = tmpbuf;
+ }
+
+ versionval = *rcp++;
+
+ if (versionval) {
+ sprintf(cp,"; error: unknown LOC RR version");
+ return (cp);
+ }
+
+ sizeval = *rcp++;
+
+ hpval = *rcp++;
+ vpval = *rcp++;
+
+ GETLONG(templ,rcp);
+ latval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ,rcp);
+ longval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ,rcp);
+ if (templ < referencealt) { /* below WGS 84 spheroid */
+ altval = referencealt - templ;
+ altsign = -1;
+ } else {
+ altval = templ - referencealt;
+ altsign = 1;
+ }
+
+ if (latval < 0) {
+ northsouth = 'S';
+ latval = -latval;
+ }
+ else
+ northsouth = 'N';
+
+ latsecfrac = latval % 1000;
+ latval = latval / 1000;
+ latsec = latval % 60;
+ latval = latval / 60;
+ latmin = latval % 60;
+ latval = latval / 60;
+ latdeg = latval;
+
+ if (longval < 0) {
+ eastwest = 'W';
+ longval = -longval;
+ }
+ else
+ eastwest = 'E';
+
+ longsecfrac = longval % 1000;
+ longval = longval / 1000;
+ longsec = longval % 60;
+ longval = longval / 60;
+ longmin = longval % 60;
+ longval = longval / 60;
+ longdeg = longval;
+
+ altfrac = altval % 100;
+ altmeters = (altval / 100) * altsign;
+
+ sizestr = savestr(precsize_ntoa(sizeval));
+ hpstr = savestr(precsize_ntoa(hpval));
+ vpstr = savestr(precsize_ntoa(vpval));
+
+ sprintf(cp,
+ "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
+ latdeg, latmin, latsec, latsecfrac, northsouth,
+ longdeg, longmin, longsec, longsecfrac, eastwest,
+ altmeters, altfrac, sizestr, hpstr, vpstr);
+
+ free(sizestr);
+ free(hpstr);
+ free(vpstr);
+
+ return (cp);
+}
+
+#endif /* LOC_RR */
+
+/*
+ * Since the fields in a "struct timeval" are longs, and the argument to ctime
+ * is a pointer to a time_t (which might not be a long), here's a bridge.
+ */
+char *
+ctimel(l)
+ long l;
+{
+ time_t t = (time_t)l;
+
+ return (ctime(&t));
+}
+
+/*
+ * This is nec'y for systems that croak when deref'ing unaligned pointers.
+ * SPARC is an example.
+ */
+struct in_addr
+data_inaddr(data)
+ const u_char *data;
+{
+ struct in_addr ret;
+
+ bcopy((char *)data, (char *)&ret, INADDRSZ);
+ return (ret);
+}
diff --git a/usr.sbin/named/db_load.c b/usr.sbin/named/db_load.c
index acf6ec786d125..cbb6ad265266d 100644
--- a/usr.sbin/named/db_load.c
+++ b/usr.sbin/named/db_load.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_load.c 4.38 (Berkeley) 3/2/91";
-static char rcsid[] = "$Id: db_load.c,v 1.2 1994/09/22 20:45:03 pst Exp $";
+static char rcsid[] = "$Id: db_load.c,v 1.3 1995/05/30 03:48:39 rgrimes Exp $";
#endif /* not lint */
/*
@@ -72,15 +72,17 @@ static char rcsid[] = "$Id: db_load.c,v 1.2 1994/09/22 20:45:03 pst Exp $";
#include <syslog.h>
#include <ctype.h>
#include <netdb.h>
+#include <resolv.h>
#include "named.h"
-static int gettoken __P((register FILE *, char *)),
- getnonblank __P((FILE *, char *)),
- getprotocol __P((FILE *, char *)),
- getservices __P((int, char *, FILE *, char *));
-static void makename __P((char *, char *));
+static int gettoken __P((register FILE *, const char *)),
+ getnonblank __P((FILE *, const char *)),
+ getprotocol __P((FILE *, const char *)),
+ getservices __P((int, char *, FILE *, const char *));
+static void makename __P((char *, const char *));
static int empty_token = 0;
+int getnum_error;
/*
* Map class and type names to number
@@ -91,47 +93,52 @@ struct map {
};
struct map m_class[] = {
- "in", C_IN,
+ { "in", C_IN },
#ifdef notdef
- "any", C_ANY, /* any is a QCLASS, not CLASS */
+ { "any", C_ANY }, /* any is a QCLASS, not CLASS */
#endif
- "chaos", C_CHAOS,
- "hs", C_HS,
+ { "chaos", C_CHAOS },
+ { "hs", C_HS },
};
-#define NCLASS (sizeof(m_class) / sizeof(struct map))
+#define M_CLASS_CNT (sizeof(m_class) / sizeof(struct map))
struct map m_type[] = {
- "a", T_A,
- "ns", T_NS,
- "cname", T_CNAME,
- "soa", T_SOA,
- "mb", T_MB,
- "mg", T_MG,
- "mr", T_MR,
- "null", T_NULL,
- "wks", T_WKS,
- "ptr", T_PTR,
- "hinfo", T_HINFO,
- "minfo", T_MINFO,
- "mx", T_MX,
- "uinfo", T_UINFO,
- "txt", T_TXT,
- "rp", T_RP,
- "afsdb", T_AFSDB,
- "x25", T_X25,
- "isdn", T_ISDN,
- "rt", T_RT,
- "nsap", T_NSAP,
- "uid", T_UID,
- "gid", T_GID,
+ { "a", T_A },
+ { "ns", T_NS },
+ { "cname", T_CNAME },
+ { "soa", T_SOA },
+ { "mb", T_MB },
+ { "mg", T_MG },
+ { "mr", T_MR },
+ { "null", T_NULL },
+ { "wks", T_WKS },
+ { "ptr", T_PTR },
+ { "hinfo", T_HINFO },
+ { "minfo", T_MINFO },
+ { "mx", T_MX },
+ { "uinfo", T_UINFO },
+ { "txt", T_TXT },
+ { "rp", T_RP },
+ { "afsdb", T_AFSDB },
+ { "x25", T_X25 },
+ { "isdn", T_ISDN },
+ { "rt", T_RT },
+ { "nsap", T_NSAP },
+ { "nsap_ptr", T_NSAP_PTR },
+ { "uid", T_UID },
+ { "gid", T_GID },
+ { "px", T_PX },
#ifdef notdef
- "any", T_ANY, /* any is a QTYPE, not TYPE */
+ { "any", T_ANY }, /* any is a QTYPE, not TYPE */
#endif
+#ifdef LOC_RR
+ { "loc", T_LOC },
+#endif /* LOC_RR */
#ifdef ALLOW_T_UNSPEC
- "unspec", T_UNSPEC,
+ { "unspec", T_UNSPEC },
#endif /* ALLOW_T_UNSPEC */
};
-#define NTYPE (sizeof(m_type) / sizeof(struct map))
+#define M_TYPE_CNT (sizeof(m_type) / sizeof(struct map))
/*
* Parser token values
@@ -147,21 +154,22 @@ struct map m_type[] = {
static int clev; /* a zone deeper in a heirachy has more credability */
/* int
- * db_load(filename, in_origin, zp, doinginclude)
- * load a database from `filename' into zone `zp'. append `origin'
- * to all nonterminal domain names in the file. `doinginclude' is
- * true if this is a $INCLUDE file.
+ * db_load(filename, in_origin, zp, def_domain)
+ * load a database from `filename' into zone `zp'. append `in_origin'
+ * to all nonterminal domain names in the file. `def_domain' is the
+ * default domain for include files or NULL for zone base files.
* returns:
* -1 = can't open file
* 0 = success
* >0 = number of errors encountered
*/
int
-db_load(filename, in_origin, zp, doinginclude)
- char *filename, *in_origin;
+db_load(filename, in_origin, zp, def_domain)
+ const char *filename, *in_origin;
struct zoneinfo *zp;
- int doinginclude;
+ const char *def_domain;
{
+ static int read_soa, read_ns;
register char *cp;
register struct map *mp;
char domain[MAXDNAME];
@@ -169,29 +177,36 @@ db_load(filename, in_origin, zp, doinginclude)
char tmporigin[MAXDNAME];
char buf[MAXDATA];
char data[MAXDATA];
- char *cp1;
- char *op;
+ const char *cp1, *op;
int c, class, type, ttl, dbflags, dataflags, multiline;
- static int read_soa; /* number of soa's read */
struct databuf *dp;
struct iso_addr *isoa;
FILE *fp;
- int slineno, i, errs = 0, didinclude = 0;
+ int slineno, i, errs, didinclude, rrcount;
register u_int32_t n;
struct stat sb;
struct in_addr ina;
+#ifdef DO_WARN_SERIAL
+ u_int32_t serial;
+#endif
- if (!doinginclude) {
- read_soa = 0;
- clev = db_getclev(in_origin);
+ errs = 0;
+ didinclude = 0;
+ rrcount = 0;
+ if (!def_domain) {
+ /* This is not the result of a $INCLUDE. */
+ read_soa = 0;
+ read_ns = 0;
+ clev = db_getclev(in_origin);
}
- dprintf(1, (ddt,"db_load(%s, %s, %d, %d)\n",
- filename, in_origin, zp - zones, doinginclude));
+ dprintf(1, (ddt,"db_load(%s, %s, %d, %s)\n",
+ filename, in_origin, zp - zones,
+ def_domain ? def_domain : "Nil"));
(void) strcpy(origin, in_origin);
if ((fp = fopen(filename, "r")) == NULL) {
- syslog(LOG_ERR, "%s: %m", filename);
+ syslog(LOG_NOTICE, "%s: %m", filename);
dprintf(1, (ddt, "db_load: error opening file %s\n",
filename));
return (-1);
@@ -199,18 +214,26 @@ db_load(filename, in_origin, zp, doinginclude)
if (zp->z_type == Z_CACHE) {
dbflags = DB_NODATA | DB_NOHINTS;
dataflags = DB_F_HINT;
+#ifdef STUBS
+ } else if (zp->z_type == Z_STUB && clev == 0) {
+ dbflags = DB_NODATA | DB_NOHINTS;
+ dataflags = DB_F_HINT;
+#endif
} else {
dbflags = DB_NODATA;
dataflags = 0;
}
gettime(&tt);
if (fstat(fileno(fp), &sb) < 0) {
- syslog(LOG_ERR, "%s: %m", filename);
+ syslog(LOG_NOTICE, "%s: %m", filename);
sb.st_mtime = (int)tt.tv_sec;
}
slineno = lineno;
lineno = 1;
- domain[0] = '\0';
+ if (def_domain)
+ strcpy(domain, def_domain);
+ else
+ domain[0] = '\0';
class = zp->z_class;
zp->z_flags &= ~(Z_INCLUDE|Z_DB_BAD);
while ((c = gettoken(fp, filename)) != EOF) {
@@ -226,7 +249,7 @@ db_load(filename, in_origin, zp, doinginclude)
endline(fp);
}
didinclude = 1;
- errs += db_load((char *)buf, tmporigin, zp, 1);
+ errs += db_load((char *)buf, tmporigin, zp, domain);
continue;
case ORIGIN:
@@ -257,7 +280,7 @@ db_load(filename, in_origin, zp, doinginclude)
case DOT:
domain[0] = '\0';
- /* fall thru ... */
+ /* FALLTHROUGH */
case CURRENT:
gotdomain:
if (!getword((char *)buf, sizeof(buf), fp)) {
@@ -271,12 +294,9 @@ db_load(filename, in_origin, zp, doinginclude)
n = 0;
do {
if (n > (INT_MAX - (*cp - '0')) / 10) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"%s: line %d: number > %lu\n",
- filename, lineno, INT_MAX);
- dprintf(1, (ddt,
- "%s: line %d: number > %lu\n",
- filename, lineno, INT_MAX));
+ filename, lineno, (u_long)INT_MAX);
n = INT_MAX;
cp++;
} else
@@ -294,14 +314,14 @@ db_load(filename, in_origin, zp, doinginclude)
if (!getword((char *)buf, sizeof(buf), fp))
break;
}
- for (mp = m_class; mp < m_class+NCLASS; mp++)
+ for (mp = m_class; mp < m_class+M_CLASS_CNT; mp++)
if (!strcasecmp((char *)buf, mp->token)) {
class = mp->val;
(void) getword((char *)buf,
sizeof(buf), fp);
break;
}
- for (mp = m_type; mp < m_type+NTYPE; mp++)
+ for (mp = m_type; mp < m_type+M_TYPE_CNT; mp++)
if (!strcasecmp((char *)buf, mp->token)) {
type = mp->val;
goto fndtype;
@@ -309,7 +329,7 @@ db_load(filename, in_origin, zp, doinginclude)
dprintf(1, (ddt, "%s: Line %d: Unknown type: %s.\n",
filename, lineno, buf));
errs++;
- syslog(LOG_ERR, "%s: Line %d: Unknown type: %s.\n",
+ syslog(LOG_INFO, "%s: Line %d: Unknown type: %s.\n",
filename, lineno, buf);
break;
fndtype:
@@ -346,9 +366,10 @@ db_load(filename, in_origin, zp, doinginclude)
case T_ISDN:
n = strlen((char *)buf);
if (n > 255) {
- syslog(LOG_WARNING,
- "%s: line %d: CPU type too long",
- filename, lineno);
+ syslog(LOG_INFO,
+ "%s: line %d: %s too long",
+ filename, lineno, (type == T_ISDN) ?
+ "ISDN-address" : "CPU type");
n = 255;
}
data[0] = n;
@@ -363,16 +384,26 @@ db_load(filename, in_origin, zp, doinginclude)
i = strlen((char *)buf);
}
if (i == 0) {
- /* goto err; */
- /* XXX tolerate for now */
- data[n++] = 1;
- data[n++] = '?';
- break;
+ if (type == T_ISDN) {
+ data[n++] = 0;
+ break;
+ }
+ else
+ /* goto err; */
+ /* XXX tolerate for now */
+ data[n++] = 1;
+ data[n++] = '?';
+ syslog(LOG_INFO,
+ "%s: line %d: OS-type missing",
+ filename,
+ empty_token ? (lineno - 1) : lineno);
+ break;
}
if (i > 255) {
- syslog(LOG_WARNING,
- "%s:%d: OS type too long",
- filename, lineno);
+ syslog(LOG_INFO,
+ "%s:%d: %s too long",
+ filename, lineno, (type == T_ISDN) ?
+ "ISDN-sa" : "OS type");
i = 255;
}
data[n] = i;
@@ -387,7 +418,7 @@ db_load(filename, in_origin, zp, doinginclude)
makename(data, origin);
cp = data + strlen((char *)data) + 1;
if (!getword((char *)cp,
- sizeof(data) - (cp - data), fp))
+ (sizeof data) - (cp - data), fp))
goto err;
makename(cp, origin);
cp += strlen((char *)cp) + 1;
@@ -396,11 +427,19 @@ db_load(filename, in_origin, zp, doinginclude)
break;
}
if (class != zp->z_class) {
- syslog(LOG_WARNING,
+ errs++;
+ syslog(LOG_INFO,
"%s:%d: %s",
filename, lineno,
"SOA class not same as zone's");
}
+ if (strcasecmp(zp->z_origin, domain) != 0) {
+ errs++;
+ syslog(LOG_ERR,
+ "%s: line %d: SOA for \"%s\" not at zone top \"%s\"",
+ filename, lineno, domain,
+ zp->z_origin);
+ }
c = getnonblank(fp, filename);
if (c == '(') {
multiline = 1;
@@ -408,10 +447,29 @@ db_load(filename, in_origin, zp, doinginclude)
multiline = 0;
ungetc(c, fp);
}
- zp->z_serial = getnum(fp, filename, 1);
+#ifdef DO_WARN_SERIAL
+ serial = zp->z_serial;
+#endif
+ zp->z_serial = getnum(fp, filename,
+ GETNUM_SERIAL);
+ if (getnum_error)
+ errs++;
n = (u_int32_t) zp->z_serial;
PUTLONG(n, cp);
- zp->z_refresh = getnum(fp, filename, 0);
+#ifdef DO_WARN_SERIAL
+ if (serial && SEQ_GT(serial, zp->z_serial)) {
+ syslog(LOG_NOTICE,
+ "%s:%d: WARNING: new serial number < old (%lu < %lu)",
+ filename , lineno,
+ zp->z_serial, serial);
+ }
+#endif
+ zp->z_refresh = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_refresh = INIT_REFRESH;
+ }
n = (u_int32_t) zp->z_refresh;
PUTLONG(n, cp);
if (zp->z_type == Z_SECONDARY
@@ -419,16 +477,31 @@ db_load(filename, in_origin, zp, doinginclude)
|| zp->z_type == Z_STUB
#endif
) {
- zp->z_time = sb.st_mtime
- + zp->z_refresh;
+ ns_refreshtime(zp, MIN(sb.st_mtime,
+ tt.tv_sec));
+ }
+ zp->z_retry = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_retry = INIT_REFRESH;
}
- zp->z_retry = getnum(fp, filename, 0);
n = (u_int32_t) zp->z_retry;
PUTLONG(n, cp);
- zp->z_expire = getnum(fp, filename, 0);
+ zp->z_expire = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_expire = INIT_REFRESH;
+ }
n = (u_int32_t) zp->z_expire;
PUTLONG (n, cp);
- zp->z_minimum = getnum(fp, filename, 0);
+ zp->z_minimum = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_minimum = 120;
+ }
n = (u_int32_t) zp->z_minimum;
PUTLONG (n, cp);
n = cp - data;
@@ -437,6 +510,11 @@ db_load(filename, in_origin, zp, doinginclude)
goto err;
}
read_soa++;
+ if (zp->z_expire < zp->z_refresh ) {
+ syslog(LOG_WARNING,
+ "%s: WARNING SOA expire value is less then SOA refresh (%lu < %lu)",
+ filename, zp->z_expire, zp->z_refresh);
+ }
endline(fp);
break;
@@ -468,6 +546,9 @@ db_load(filename, in_origin, zp, doinginclude)
break;
case T_NS:
+ if (strcasecmp(zp->z_origin, domain) == 0)
+ read_ns++;
+ /* FALLTHROUGH */
case T_CNAME:
case T_MB:
case T_MG:
@@ -480,7 +561,7 @@ db_load(filename, in_origin, zp, doinginclude)
case T_UINFO:
cp = strchr((char *)buf, '&');
- bzero(data, sizeof(data));
+ bzero(data, sizeof data);
if ( cp != NULL) {
(void) strncpy((char *)data,
(char *)buf, cp - buf);
@@ -523,19 +604,37 @@ db_load(filename, in_origin, zp, doinginclude)
n = (cp - data);
break;
+ case T_PX:
+ n = 0;
+ data[0] = '\0';
+ cp = buf;
+ while (isdigit(*cp))
+ n = n * 10 + (*cp++ - '0');
+ /* catch bad values */
+ if ((cp == buf) || (n > 65535))
+ goto err;
+ cp = data;
+ PUTSHORT((u_int16_t)n, cp);
+
+ if (!getword((char *)buf, sizeof(buf), fp))
+ goto err;
+ (void) strcpy((char *)cp, (char *)buf);
+ makename(cp, origin);
+ /* advance pointer to next field */
+ cp += strlen((char *)cp) +1;
+ if (!getword((char *)buf, sizeof(buf), fp))
+ goto err;
+ (void) strcpy((char *)cp, (char *)buf);
+ makename(cp, origin);
+ /* advance pointer to end of data */
+ cp += strlen((char *)cp) + 1;
+
+ /* now save length */
+ n = (cp - data);
+ break;
+
case T_TXT:
case T_X25:
- cp = buf + (n = strlen(buf));
- while ((i = getc(fp), *cp = i, i != EOF)
- && *cp != '\n'
- && (n < MAXDATA)) {
- cp++; n++;
- }
- if (*cp == '\n') /* leave \n for getword */
- ungetc(*cp, fp);
- *cp = '\0';
- /* now do normal processing */
-
i = strlen((char *)buf);
cp = data;
cp1 = buf;
@@ -543,11 +642,11 @@ db_load(filename, in_origin, zp, doinginclude)
* there is expansion here so make sure we
* don't overflow data
*/
- if (i > sizeof(data) * 255 / 256) {
- syslog(LOG_WARNING,
+ if (i > (sizeof data) * 255 / 256) {
+ syslog(LOG_INFO,
"%s: line %d: TXT record truncated",
filename, lineno);
- i = sizeof(data) * 255 / 256;
+ i = (sizeof data) * 255 / 256;
}
while (i > 255) {
*cp++ = 255;
@@ -569,8 +668,28 @@ db_load(filename, in_origin, zp, doinginclude)
goto err;
n = isoa->isoa_len;
bcopy(isoa->isoa_genaddr, data, n);
+ endline(fp);
+ break;
+#ifdef LOC_RR
+ case T_LOC:
+ cp = buf + (n = strlen(buf));
+ *cp = ' ';
+ cp++;
+ while ((i = getc(fp), *cp = i, i != EOF)
+ && *cp != '\n'
+ && (n < MAXDATA)) {
+ cp++; n++;
+ }
+ if (*cp == '\n') /* leave \n for getword */
+ ungetc(*cp, fp);
+ *cp = '\0';
+ /* now process the whole line */
+ n = loc_aton(buf, (u_char *)data);
+ if (n == 0)
+ goto err;
endline(fp);
break;
+#endif /* LOC_RR */
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
{
@@ -579,25 +698,15 @@ db_load(filename, in_origin, zp, doinginclude)
dprintf(1, (ddt, "loading T_UNSPEC\n"));
if (rcode = atob(buf,
strlen((char*)buf),
- data, sizeof(data),
+ data, sizeof data,
&n)) {
if (rcode == CONV_OVERFLOW) {
- dprintf(1,
- (ddt,
- "Load T_UNSPEC: input buffer overflow\n"
- )
- );
errs++;
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"Load T_UNSPEC: input buffer overflow");
} else {
- dprintf(1,
- (ddt,
- "Load T_UNSPEC: Data in bad atob format\n"
- )
- );
errs++;
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"Load T_UNSPEC: Data in bad atob format");
}
}
@@ -608,10 +717,12 @@ db_load(filename, in_origin, zp, doinginclude)
default:
goto err;
}
+#ifndef PURGE_ZONE
#ifdef STUBS
if (type == T_SOA && zp->z_type == Z_STUB)
continue;
#endif
+#endif
#ifdef NO_GLUE
/*
* Ignore data outside the zone.
@@ -619,13 +730,12 @@ db_load(filename, in_origin, zp, doinginclude)
if (zp->z_type != Z_CACHE &&
!samedomain(domain, zp->z_origin))
{
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"%s:%d: data \"%s\" outside zone \"%s\" (ignored)",
filename, lineno, domain, zp->z_origin);
continue;
}
#endif /*NO_GLUE*/
-
dp = savedata(class, type, (u_int32_t)ttl,
(u_char *)data, (int)n);
dp->d_zone = zp - zones;
@@ -643,55 +753,75 @@ db_load(filename, in_origin, zp, doinginclude)
domain, type);
#endif
free((char*) dp);
+ } else {
+ rrcount++;
}
continue;
case ERROR:
break;
}
- err:
+ err:
errs++;
- syslog(LOG_ERR, "%s: line %d: database format error (%s)",
+ syslog(LOG_NOTICE, "%s: line %d: database format error (%s)",
filename, empty_token ? (lineno - 1) : lineno, buf);
- dprintf(1, (ddt,
- "%s: line %d: database format error ('%s', %d)\n",
- filename, empty_token ? (lineno - 1) : lineno,
- buf, n));
- while ((c = getc(fp)) != EOF && c != '\n')
- ;
- if (c == '\n')
- lineno++;
+ if (!empty_token)
+ endline(fp);
}
(void) my_fclose(fp);
lineno = slineno;
- if (doinginclude == 0) {
+ if (!def_domain) {
if (didinclude) {
zp->z_flags |= Z_INCLUDE;
zp->z_ftime = 0;
} else
zp->z_ftime = sb.st_mtime;
zp->z_lastupdate = sb.st_mtime;
- if (zp->z_type != Z_CACHE && read_soa != 1) {
- errs++;
+ if (zp->z_type != Z_CACHE) {
+ const char *msg = NULL;
+
if (read_soa == 0)
- syslog(LOG_ERR, "%s: no SOA record", filename);
- else
- syslog(LOG_ERR, "%s: multiple SOA records",
- filename);
+ msg = "no SOA RR found";
+ else if (read_soa != 1)
+ msg = "multiple SOA RRs found";
+ else if (read_ns == 0)
+ msg = "no NS RRs found at zone top";
+ else if (!rrcount)
+ msg = "no relevant RRs found";
+ if (msg != NULL) {
+ errs++;
+ syslog(LOG_NOTICE, "Zone \"%s\" (file %s): %s",
+ zp->z_origin, filename, msg);
+ }
}
}
#ifdef SECURE_ZONES
build_secure_netlist(zp);
#endif
+ if (!def_domain)
+ syslog(LOG_INFO,
+ "%s zone \"%s\" %s (serial %lu)",
+ zoneTypeString(zp), zp->z_origin,
+ errs ? "rejected due to errors" : "loaded",
+ (u_long)zp->z_serial);
if (errs)
zp->z_flags |= Z_DB_BAD;
+#ifdef BIND_NOTIFY
+ /* XXX: this needs to be delayed, both according to the spec, and
+ * because the metadata needed by sysnotify() (and its sysquery())
+ * could be in other zones that we (at startup) havn't loaded yet.
+ */
+ if (!errs && !def_domain &&
+ (zp->z_type == Z_PRIMARY || zp->z_type == Z_SECONDARY))
+ sysnotify(zp->z_origin, zp->z_class, T_SOA);
+#endif
return (errs);
}
static int
gettoken(fp, src)
register FILE *fp;
- char *src;
+ const char *src;
{
register int c;
char op[32];
@@ -710,10 +840,8 @@ gettoken(fp, src)
if (!strcasecmp("origin", op))
return (ORIGIN);
}
- dprintf(1, (ddt,
- "%s: line %d: Unknown $ option: $%s\n",
- src, lineno, op));
- syslog(LOG_ERR,"%s: line %d: Unknown $ option: $%s\n",
+ syslog(LOG_NOTICE,
+ "%s: line %d: Unknown $ option: $%s\n",
src, lineno, op);
return (ERROR);
@@ -849,10 +977,10 @@ smaller than "1.23" in their internal expressions.
*/
int
-getnum(fp, src, is_serial)
+getnum(fp, src, opt)
FILE *fp;
- char *src;
- int is_serial;
+ const char *src;
+ int opt;
{
register int c, n;
int seendigit = 0;
@@ -860,8 +988,10 @@ getnum(fp, src, is_serial)
int m = 0;
int allow_dots = 0;
+ getnum_error = 0;
#ifdef DOTTED_SERIAL
- allow_dots += is_serial;
+ if (opt & GETNUM_SERIAL)
+ allow_dots++;
#endif
for (n = 0; (c = getc(fp)) != EOF; ) {
if (isspace(c)) {
@@ -880,24 +1010,39 @@ getnum(fp, src, is_serial)
break;
continue;
}
+ if (getnum_error)
+ continue;
if (!isdigit(c)) {
if (c == ')' && seendigit) {
(void) ungetc(c, fp);
break;
}
+ if (seendigit && (opt & GETNUM_SCALED) &&
+ strchr("KkMmGg", c) != NULL) {
+ switch (c) {
+ case 'K': case 'k':
+ n *= 1024;
+ break;
+ case 'M': case 'm':
+ n *= (1024 * 1024);
+ break;
+ case 'G': case 'g':
+ n *= (1024 * 1024 * 1024);
+ break;
+ }
+ break;
+ }
if (seendecimal || c != '.' || !allow_dots) {
- syslog(LOG_ERR, "%s:%d: expected a number",
+ syslog(LOG_NOTICE, "%s:%d: expected a number",
src, lineno);
- dprintf(1, (ddt, "%s:%d: expected a number",
- src, lineno));
- exit(1); /* XXX why exit here?? */
+ getnum_error = 1;
} else {
if (!seendigit)
n = 1;
#ifdef SENSIBLE_DOTS
- n = n * 10000;
+ n *= 10000;
#else
- n = n * 1000;
+ n *= 1000;
#endif
seendigit = 1;
seendecimal = 1;
@@ -914,14 +1059,14 @@ getnum(fp, src, is_serial)
#endif
seendigit = 1;
}
+ if (getnum_error)
+ return (0);
if (m > 9999) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"%s:%d: number after the decimal point exceeds 9999",
src, lineno);
- dprintf(1, (ddt,
- "%s:%d: number after the decimal point exceeds 9999",
- src, lineno));
- exit(1); /* XXX why exit here?? */
+ getnum_error = 1;
+ return (0);
}
if (seendecimal) {
syslog(LOG_INFO,
@@ -934,7 +1079,7 @@ getnum(fp, src, is_serial)
static int
getnonblank(fp, src)
FILE *fp;
- char *src;
+ const char *src;
{
register int c;
@@ -953,8 +1098,7 @@ getnonblank(fp, src)
}
return(c);
}
- syslog(LOG_ERR, "%s: line %d: unexpected EOF", src, lineno);
- dprintf(1, (ddt, "%s: line %d: unexpected EOF", src, lineno));
+ syslog(LOG_INFO, "%s: line %d: unexpected EOF", src, lineno);
return (EOF);
}
@@ -967,7 +1111,8 @@ getnonblank(fp, src)
*/
static void
makename(name, origin)
- char *name, *origin;
+ char *name;
+ const char *origin;
{
int n;
@@ -1000,7 +1145,7 @@ endline(fp)
{
register int c;
- while (c = getc(fp)) {
+ while ((c = getc(fp)) != '\0') {
if (c == '\n') {
(void) ungetc(c,fp);
break;
@@ -1010,13 +1155,13 @@ endline(fp)
}
}
-#define MAXPORT 256
+#define MAXPORT 1024
#define MAXLEN 24
static int
getprotocol(fp, src)
FILE *fp;
- char *src;
+ const char *src;
{
int k;
char b[MAXLEN];
@@ -1024,17 +1169,18 @@ getprotocol(fp, src)
(void) getword(b, sizeof(b), fp);
k = protocolnumber(b);
- if(k == -1)
- syslog(LOG_ERR, "%s: line %d: unknown protocol: %s.",
- src, lineno, b);
+ if (k == -1)
+ syslog(LOG_INFO, "%s: line %d: unknown protocol: %s.",
+ src, lineno, b);
return(k);
}
static int
getservices(n, data, fp, src)
int n;
- char *data, *src;
+ char *data;
FILE *fp;
+ const char *src;
{
int j, ch;
int k;
@@ -1066,7 +1212,7 @@ getservices(n, data, fp, src)
}
k = servicenumber(b);
if (k == -1) {
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"%s: line %d: Unknown service '%s'",
src, lineno, b);
continue;
@@ -1077,20 +1223,20 @@ getservices(n, data, fp, src)
maxl=k;
}
else {
- syslog(LOG_WARNING,
- "%s: line %d: port no. (%d) too big\n",
- src, lineno, k);
+ syslog(LOG_INFO,
+ "%s: line %d: port no. (%d) too big\n",
+ src, lineno, k);
dprintf(1, (ddt,
"%s: line %d: port no. (%d) too big\n",
src, lineno, k));
}
}
if (bracket)
- syslog(LOG_WARNING, "%s: line %d: missing close paren\n",
- src, lineno);
+ syslog(LOG_INFO, "%s: line %d: missing close paren\n",
+ src, lineno);
maxl = maxl/8+1;
bcopy(bm, data+n, maxl);
- return(maxl+n);
+ return (maxl+n);
}
/* get_netlist(fp, netlistp, allow)
@@ -1106,10 +1252,13 @@ get_netlist(fp, netlistp, allow, print_tag)
int allow;
char *print_tag;
{
- struct netinfo *ntp = NULL, **end = netlistp;
+ struct netinfo *ntp, **end;
char buf[BUFSIZ], *maskp;
struct in_addr ina;
+ for (end = netlistp; *end; end = &(**end).next)
+ ;
+ ntp = NULL;
dprintf(1, (ddt, "get_netlist(%s)", print_tag));
while (getword(buf, sizeof(buf), fp)) {
if (strlen(buf) == 0)
@@ -1121,13 +1270,13 @@ get_netlist(fp, netlistp, allow, print_tag)
ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
}
if (!inet_aton(buf, &ntp->my_addr)) {
- syslog(LOG_ERR, "%s contains bogus element (%s)",
+ syslog(LOG_INFO, "%s contains bogus element (%s)",
print_tag, buf);
continue;
}
if (maskp) {
if (!inet_aton(maskp, &ina)) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"%s element %s has bad mask (%s)",
print_tag, buf, maskp);
continue;
@@ -1148,7 +1297,7 @@ get_netlist(fp, netlistp, allow, print_tag)
if (ntp->addr != ntp->my_addr.s_addr) {
ina.s_addr = ntp->addr;
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"%s element (%s) mask problem (%s)",
print_tag, buf, inet_ntoa(ina));
}
@@ -1164,11 +1313,13 @@ get_netlist(fp, netlistp, allow, print_tag)
#ifdef DEBUG
if (debug > 2)
for (ntp = *netlistp; ntp != NULL; ntp = ntp->next) {
- fprintf(ddt, "ntp x%x addr x%x mask x%x",
- ntp, ntp->addr, ntp->mask);
- fprintf(ddt, " my_addr x%x", ntp->my_addr);
+ fprintf(ddt, "ntp x%lx addr x%lx mask x%lx",
+ (u_long)ntp, (u_long)ntp->addr,
+ (u_long)ntp->mask);
+ fprintf(ddt, " my_addr x%lx",
+ (u_long)ntp->my_addr.s_addr);
fprintf(ddt, " %s", inet_ntoa(ntp->my_addr));
- fprintf(ddt, " next x%x\n", ntp->next);
+ fprintf(ddt, " next x%lx\n", (u_long)ntp->next);
}
#endif
}
diff --git a/usr.sbin/named/db_lookup.c b/usr.sbin/named/db_lookup.c
index 875e0ede60506..c1d047d063249 100644
--- a/usr.sbin/named/db_lookup.c
+++ b/usr.sbin/named/db_lookup.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_lookup.c 4.18 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: db_lookup.c,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $";
+static char rcsid[] = "$Id: db_lookup.c,v 1.2 1995/05/30 03:48:40 rgrimes Exp $";
#endif /* not lint */
/*
@@ -79,13 +79,13 @@ static char rcsid[] = "$Id: db_lookup.c,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $"
*/
struct namebuf *
nlookup(name, htpp, fname, insert)
- char *name;
+ const char *name;
struct hashbuf **htpp;
- char **fname;
+ const char **fname;
int insert;
{
register struct namebuf *np;
- register char *cp;
+ register const char *cp;
register int c;
register unsigned hval;
register struct hashbuf *htp;
@@ -117,8 +117,7 @@ nlookup(name, htpp, fname, insert)
hval <<= HASHSHIFT;
hval += (isupper(c) ? tolower(c) : c) & HASHMASK;
}
- c = *--cp;
- *cp = '\0';
+ cp--;
/*
* Lookup this label in current hash table.
*/
@@ -126,9 +125,8 @@ nlookup(name, htpp, fname, insert)
np != NULL;
np = np->n_next) {
if (np->n_hashval == hval &&
- strcasecmp(name, np->n_dname) == 0) {
+ strncasecmp(name, np->n_dname, cp - name) == 0) {
*fname = name;
- *cp = c;
return (np);
}
}
@@ -143,14 +141,12 @@ nlookup(name, htpp, fname, insert)
if (np->n_dname[0] == '*' && np->n_dname[1] == '\0' &&
np->n_data && np->n_data->d_zone != 0) {
*fname = name;
- *cp = c;
return (np);
}
}
- *cp = c;
return (parent);
}
- np = savename(name);
+ np = savename(name, cp - name);
np->n_parent = parent;
np->n_hashval = hval;
hval %= htp->h_size;
@@ -171,7 +167,6 @@ nlookup(name, htpp, fname, insert)
htp = *htpp;
}
*fname = name;
- *cp = c;
return (np);
}
@@ -186,8 +181,8 @@ match(dp, class, type)
register struct databuf *dp;
register int class, type;
{
- dprintf(5, (ddt, "match(0x%x, %d, %d) %d, %d\n",
- dp, class, type, dp->d_class, dp->d_type));
+ dprintf(5, (ddt, "match(0x%lx, %d, %d) %d, %d\n",
+ (u_long)dp, class, type, dp->d_class, dp->d_type));
if (dp->d_class != class && class != C_ANY)
return (0);
if (dp->d_type != type && type != T_ANY)
diff --git a/usr.sbin/named/db_save.c b/usr.sbin/named/db_save.c
index abe1896b78247..61471cef6f5ca 100644
--- a/usr.sbin/named/db_save.c
+++ b/usr.sbin/named/db_save.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_save.c 4.16 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: db_save.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
+static char rcsid[] = "$Id: db_save.c,v 1.2 1995/05/30 03:48:42 rgrimes Exp $";
#endif /* not lint */
/*
@@ -68,6 +68,7 @@ static char rcsid[] = "$Id: db_save.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
#include <arpa/nameser.h>
#include <syslog.h>
#include <stdio.h>
+#include <errno.h>
#include "named.h"
@@ -75,20 +76,21 @@ static char rcsid[] = "$Id: db_save.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
* Allocate a name buffer & save name.
*/
struct namebuf *
-savename(name)
- char *name;
+savename(name, len)
+ const char *name;
+ int len;
{
register struct namebuf *np;
np = (struct namebuf *) malloc(sizeof(struct namebuf));
- if (np == NULL) {
- syslog(LOG_ERR, "savename: %m");
- exit(1);
- }
- np->n_dname = savestr(name);
- np->n_next = NULL;
- np->n_data = NULL;
- np->n_hash = NULL;
+ if (np == NULL)
+ panic(errno, "savename: malloc");
+ bzero((char*)np, sizeof(struct namebuf));
+ np->n_dname = malloc(len + 1);
+ if (np == NULL)
+ panic(errno, "savename: malloc");
+ strncpy(np->n_dname, name, len);
+ np->n_dname[len] = '\0';
return (np);
}
@@ -109,27 +111,18 @@ savedata(class, type, ttl, data, size)
int size;
{
register struct databuf *dp;
+ int bytes = (type == T_NS) ? DATASIZE(size)+INT32SZ : DATASIZE(size);
- if (type == T_NS)
- dp = (struct databuf *)
+ dp = (struct databuf *)
#ifdef DMALLOC
- dmalloc(file, line,
+ dmalloc(file, line, bytes)
#else
- malloc(
+ malloc(bytes)
#endif
- (unsigned)DATASIZE(size)+INT32SZ);
- else
- dp = (struct databuf *)
-#ifdef DMALLOC
- dmalloc(file, line,
-#else
- malloc(
-#endif
- (unsigned)DATASIZE(size));
- if (dp == NULL) {
- syslog(LOG_ERR, "savedata: %m");
- exit(1);
- }
+ ;
+ if (dp == NULL)
+ panic(errno, "savedata: malloc");
+ bzero((char*)dp, bytes);
dp->d_next = NULL;
dp->d_type = type;
dp->d_class = class;
@@ -198,8 +191,8 @@ savehash(oldhtp)
htp->h_cnt = 0;
return (htp);
}
- dprintf(4, (ddt, "savehash(%#x) cnt=%d, sz=%d, newsz=%d\n",
- oldhtp, oldhtp->h_cnt, oldhtp->h_size, newsize));
+ dprintf(4, (ddt, "savehash(%#lx) cnt=%d, sz=%d, newsz=%d\n",
+ (u_long)oldhtp, oldhtp->h_cnt, oldhtp->h_size, newsize));
htp->h_cnt = oldhtp->h_cnt;
for (n = 0; n < oldhtp->h_size; n++) {
for (np = oldhtp->h_tab[n]; np != NULL; np = nnp) {
diff --git a/usr.sbin/named/db_secure.c b/usr.sbin/named/db_secure.c
index d6c7bedb5b815..62f2f9a85b99b 100644
--- a/usr.sbin/named/db_secure.c
+++ b/usr.sbin/named/db_secure.c
@@ -1,5 +1,5 @@
#ifndef LINT
-static char rcsid[] = "$Id: db_secure.c,v 1.1.1.1 1994/09/22 19:46:14 pst Exp $";
+static char rcsid[] = "$Id: db_secure.c,v 1.2 1995/05/30 03:48:43 rgrimes Exp $";
#endif
/* this file was contributed by Gregory Neil Shapiro of WPI in August 1993 */
@@ -32,7 +32,8 @@ build_secure_netlist(zp)
struct hashbuf *htp;
struct namebuf *snp;
struct databuf *dp;
- char *fname, *dname, dnbuf[MAXDNAME];
+ const char *fname;
+ char *dname, dnbuf[MAXDNAME];
int errs = 0, securezone = 0;
if (zp->secure_nets) {
@@ -59,7 +60,7 @@ build_secure_netlist(zp)
/* Collect secure nets into secure_nets */
for (dp = snp->n_data; dp != NULL; dp = dp->d_next) {
char *maskptr = NULL;
- if (!match(dp, C_ANY, T_TXT)) {
+ if (!match(dp, zp->z_class, T_TXT)) {
continue;
}
bzero(buf, sizeof(buf));
@@ -77,20 +78,17 @@ build_secure_netlist(zp)
dprintf(1, (ddt,
"build_secure_netlist (%s): malloc fail\n",
zp->z_origin));
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"build_secure_netlist (%s): Out of Memory",
zp->z_origin);
if (!securezone) {
- zp->secure_nets=NULL;
+ zp->secure_nets = NULL;
}
- return(1);
+ return (1);
}
}
if (!inet_aton(buf, &ntp->my_addr)) {
- dprintf(1, (ddt,
- "build_secure_netlist (%s): Bad address: %s\n",
- zp->z_origin, buf));
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"build_secure_netlist (%s): Bad address: %s",
zp->z_origin, buf);
errs++;
@@ -105,7 +103,7 @@ build_secure_netlist(zp)
dprintf(1, (ddt,
"build_secure_netlist (%s): Bad mask: %s\n",
zp->z_origin, maskptr));
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"build_secure_netlist (%s): Bad mask: %s",
zp->z_origin, maskptr);
errs++;
@@ -116,16 +114,11 @@ build_secure_netlist(zp)
ntp->mask = net_mask(ntp->my_addr);
}
if (ntp->my_addr.s_addr & ~(ntp->mask)) {
- dprintf(1, (ddt,
- "build_secure_netlist (%s): addr (%s) is not in mask (x%x)\n",
- zp->z_origin,
- inet_ntoa(ntp->my_addr),
- ntp->mask));
- syslog(LOG_WARNING,
- "build_secure_netlist (%s): addr (%s) is not in mask (x%x)",
+ syslog(LOG_INFO,
+ "build_secure_netlist (%s): addr (%s) is not in mask (%#lx)",
zp->z_origin,
inet_ntoa(ntp->my_addr),
- ntp->mask);
+ (u_long)ntp->mask);
errs++;
}
ntp->next = NULL;
@@ -133,10 +126,7 @@ build_secure_netlist(zp)
/* Check for duplicates */
if (addr_on_netlist(ntp->my_addr, *netlistp)) {
- dprintf(1, (ddt,
- "build_secure_netlist (%s): duplicate address %s\n",
- zp->z_origin, inet_ntoa(ntp->my_addr)));
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"build_secure_netlist (%s): duplicate address %s\n",
zp->z_origin, inet_ntoa(ntp->my_addr));
errs++;
@@ -151,20 +141,21 @@ build_secure_netlist(zp)
free((char *)ntp);
}
if (!securezone) {
- zp->secure_nets=NULL;
+ zp->secure_nets=NULL;
}
#ifdef DEBUG
if (debug > 1) {
for (ntp = *netlistp; ntp != NULL; ntp = ntp->next) {
- fprintf(ddt, "ntp x%x addr x%x mask x%x",
- ntp, ntp->addr, ntp->mask);
- fprintf(ddt, " my_addr x%x", ntp->my_addr);
+ fprintf(ddt, "ntp x%lx addr x%lx mask x%lx",
+ (u_long)ntp, ntp->addr, ntp->mask);
+ fprintf(ddt, " my_addr %#lx",
+ (u_long)ntp->my_addr.s_addr);
fprintf(ddt, " %s", inet_ntoa(ntp->my_addr));
- fprintf(ddt, " next x%x\n", ntp->next);
+ fprintf(ddt, " next x%lx\n", (u_long)ntp->next);
}
}
#endif
- return(errs);
+ return (errs);
}
#endif /*SECURE_ZONES*/
diff --git a/usr.sbin/named/db_update.c b/usr.sbin/named/db_update.c
index b322609630a72..40e88cd8e7db5 100644
--- a/usr.sbin/named/db_update.c
+++ b/usr.sbin/named/db_update.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_update.c 4.28 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: db_update.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
+static char rcsid[] = "$Id: db_update.c,v 1.2 1995/05/30 03:48:44 rgrimes Exp $";
#endif /* not lint */
/*
@@ -66,6 +66,7 @@ static char rcsid[] = "$Id: db_update.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
+#include <resolv.h>
#include "named.h"
@@ -91,18 +92,19 @@ isRefByNS(name, htp)
for (np = htp->h_tab[0]; np != NULL; np = np->n_next) {
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
- if ((dp->d_class == C_ANY || dp->d_class == C_IN) &&
- (dp->d_type == T_NS) &&
+ if ((dp->d_class == C_ANY ||
+ dp->d_class == C_IN ||
+ dp->d_class == C_HS) &&
+ dp->d_type == T_NS &&
#ifdef NCACHE
- (!dp->d_rcode) &&
+ !dp->d_rcode &&
#endif
!strcasecmp(name, (char *)dp->d_data)) {
return (1);
}
}
- if (np->n_hash && isRefByNS(name, np->n_hash)) {
+ if (np->n_hash && isRefByNS(name, np->n_hash))
return (1);
- }
}
return (0);
}
@@ -156,6 +158,13 @@ findMyZone(np, class)
}
+#ifdef NO_GLUE
+#define ISVALIDGLUE(xdp) ((xdp)->d_type == T_NS || (xdp)->d_type == T_A)
+#else
+#define ISVALIDGLUE(xdp) (1)
+#endif /*NO_GLUE*/
+
+
/* int
* db_update(name, odp, newdp, flags, htp)
* update data base node at `name'. `flags' controls the action.
@@ -207,22 +216,26 @@ db_update(name, odp, newdp, flags, htp)
register struct databuf *dp, *pdp;
register struct namebuf *np;
int zn, isHintNS;
- char *fname;
+ const char *fname;
- dprintf(3, (ddt, "db_update(%s, 0x%x, 0x%x, 0%o, 0x%x)%s\n",
- name, odp, newdp, flags, htp,
+ dprintf(3, (ddt, "db_update(%s, 0x%lx, 0x%lx, 0%o, 0x%lx)%s\n",
+ name, (u_long)odp, (u_long)newdp, flags, (u_long)htp,
(odp && (odp->d_flags&DB_F_HINT)) ? " hint":"" ));
np = nlookup(name, &htp, &fname, newdp != NULL);
if (np == NULL || fname != name)
return (NONAME);
/* don't let nonauthoritative updates write in authority zones */
- if (newdp && (flags & DB_NOTAUTH) &&
- (zn = findMyZone(np, newdp->d_class)) != DB_Z_CACHE) {
+ if (newdp && ((zn = findMyZone(np, newdp->d_class)) != DB_Z_CACHE) &&
+#ifdef STUBS
+ (zones[zn].z_type != Z_STUB) &&
+#endif
+ (flags & DB_NOTAUTH)) {
int foundRR = 0;
- /* don't generate the warning if we've done so recently or
- * if the update would have been harmless (identical data).
+ /*
+ * Don't generate the warning if the update
+ * would have been harmless (identical data).
*/
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
if (!db_cmp(dp, newdp)) {
@@ -230,31 +243,28 @@ db_update(name, odp, newdp, flags, htp)
break;
}
}
- if (!foundRR &&
- !haveComplained((char*)from_addr.sin_addr.s_addr,
- (char*)dhash((u_char*)name, strlen(name))))
- syslog(LOG_NOTICE,
- "[%s].%d attempted update to auth zone \"%s\" (%s)",
- inet_ntoa(from_addr.sin_addr),
- ntohs(from_addr.sin_port),
- zones[zn].z_origin,
- name);
+ if (!foundRR)
+ dprintf(5, (ddt,
+ "[%s].%d update? to auth zone \"%s\" (%s)",
+ inet_ntoa(from_addr.sin_addr),
+ ntohs(from_addr.sin_port),
+ zones[zn].z_origin,
+ name));
return (AUTH);
}
+ if (newdp && zn && !(flags & DB_NOTAUTH)) {
+ if (db_getclev(zones[zn].z_origin) > newdp->d_clev) {
+ dprintf(5,(ddt, "attempted update child zone %s, %s\n",
+ zones[zn].z_origin, name));
+ return(AUTH);
+ }
+ }
+
/* some special checks for root NS' A RR's */
isHintNS = isRefByNS(name, fcachetab);
+#ifdef DEPRECATED
if (newdp && isHintNS && newdp->d_type == T_A) {
- /* obviously bogus addresses die here */
- if (
-#ifdef NCACHE
- (!newdp->d_rcode) &&
-#endif
- (((struct in_addr *)newdp->d_data)->s_addr == INADDR_ANY))
- {
- syslog(LOG_INFO, "bogus (0.0.0.0) root A RR received");
- return (AUTH);
- }
/* upgrade credibility of additional data for rootsrv addrs */
if (newdp->d_cred == DB_C_ADDITIONAL) {
dprintf(3, (ddt,
@@ -267,10 +277,12 @@ db_update(name, odp, newdp, flags, htp)
newdp->d_clev = 0;
}
}
+#endif
/* Reflect certain updates in hint cache also... */
/* Don't stick data we are authoritative for in hints. */
if (!(flags & DB_NOHINTS) &&
+ (flags & DB_PRIMING) &&
(odp != NULL) &&
(htp != fcachetab) &&
(odp->d_zone <= 0) &&
@@ -296,7 +308,8 @@ db_update(name, odp, newdp, flags, htp)
(flags|DB_NOHINTS),
fcachetab)
!= OK) {
- dprintf(3, (ddt, "db_update: hint %x freed\n", dp));
+ dprintf(3, (ddt, "db_update: hint %lx freed\n",
+ (u_long)dp));
(void) free((char *)dp);
}
}
@@ -322,13 +335,9 @@ db_update(name, odp, newdp, flags, htp)
!odp->d_rcode &&
#endif /*NCACHE*/
zones[odp->d_zone].z_type != Z_CACHE) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"%s has CNAME and other data (illegal)\n",
name);
- dprintf(1, (ddt,
- "db_update: %s: CNAME and more (%d, %d)\n",
- name, odp->d_type,
- dp->d_type));
goto skip;
}
if (!newdp || newdp->d_class != dp->d_class)
@@ -362,9 +371,35 @@ db_update(name, odp, newdp, flags, htp)
* but isn't as credible, reject it.
*/
if (newdp->d_cred == DB_C_ZONE &&
- newdp->d_cred == dp->d_cred &&
- newdp->d_clev < dp->d_clev)
- return (AUTH);
+ dp->d_cred == DB_C_ZONE) {
+ /* Both records are from a zone file.
+ * If their credibility levels differ,
+ * we're dealing with a zone cut. The
+ * record with lower clev is from the
+ * upper zone's file and is therefore
+ * glue.
+ */
+ if (newdp->d_clev < dp->d_clev) {
+ if (!ISVALIDGLUE(newdp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, ignored",
+ name, p_type(newdp->d_type),
+ zones[newdp->d_zone].z_origin,
+ zones[dp->d_zone].z_origin);
+ }
+ return (AUTH);
+ }
+ if (newdp->d_clev > dp->d_clev) {
+ if (!ISVALIDGLUE(dp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, deleted",
+ name, p_type(dp->d_type),
+ zones[dp->d_zone].z_origin,
+ zones[newdp->d_zone].z_origin);
+ }
+ goto delete;
+ }
+ }
#ifdef NCACHE
/* process NXDOMAIN */
/* policy */
@@ -400,12 +435,9 @@ db_update(name, odp, newdp, flags, htp)
ntohs(from_addr.sin_port),
dp->d_cred,
dp->d_clev));
- if (newdp->d_cred > dp->d_cred ||
- (newdp->d_cred == DB_C_ZONE &&
- newdp->d_clev > dp->d_clev)) {
- /* better credibility and the old datum
- * was not from a zone file. remove
- * the old datum.
+ if (newdp->d_cred > dp->d_cred) {
+ /* better credibility.
+ * remove the old datum.
*/
goto delete;
}
@@ -414,9 +446,56 @@ db_update(name, odp, newdp, flags, htp)
return (AUTH);
}
if (newdp->d_cred == DB_C_ZONE &&
- newdp->d_cred == dp->d_cred &&
- newdp->d_clev < dp->d_clev)
- return (AUTH);
+ dp->d_cred == DB_C_ZONE ) {
+ /* Both records are from a zone file.
+ * If their credibility levels differ,
+ * we're dealing with a zone cut. The
+ * record with lower clev is from the
+ * upper zone's file and is therefore
+ * glue.
+ */
+
+ /* XXX - Tricky situation here is you
+ * have 2 zones a.b.c and sub.a.b.c
+ * being served by the same server.
+ * named will send NS records for
+ * sub.a.b.c during zone transfer of
+ * a.b.c zone. If we're secondary for
+ * both zones, and we reload zone
+ * a.b.c, we'll get the NS records
+ * (and possibly A records to go with
+ * them?) for sub.a.b.c as part of the
+ * a.b.c zone transfer. But we've
+ * already got a more credible record
+ * from the sub.a.b.c zone. So we want
+ * to ignore the new record, but we
+ * shouldn't syslog because there's
+ * nothing the user can do to prevent
+ * the situation. Perhaps we should
+ * only complain when we are primary?
+ */
+
+ if (newdp->d_clev < dp->d_clev) {
+ if (!ISVALIDGLUE(newdp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, ignored",
+ name, p_type(newdp->d_type),
+ zones[newdp->d_zone].z_origin,
+ zones[dp->d_zone].z_origin);
+ }
+ return (AUTH);
+ }
+ if (newdp->d_clev > dp->d_clev) {
+ if (!ISVALIDGLUE(dp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, deleted",
+ name, p_type(dp->d_type),
+ zones[dp->d_zone].z_origin,
+ zones[newdp->d_zone].z_origin);
+ }
+ goto delete;
+ }
+ }
/* credibility is the same.
* let it aggregate in the normal way.
@@ -439,7 +518,8 @@ db_update(name, odp, newdp, flags, htp)
if (dp->d_type == T_SOA)
goto delete;
if (dp->d_type == T_WKS &&
- !bcmp(dp->d_data, newdp->d_data, INT16SZ))
+ !bcmp(dp->d_data, newdp->d_data,
+ INT32SZ + sizeof(u_char)))
goto delete;
}
if ((flags & DB_NODATA) && !db_cmp(dp, odp)) {
@@ -458,8 +538,8 @@ db_update(name, odp, newdp, flags, htp)
if (odp->d_ttl > dp->d_ttl)
dp->d_ttl = odp->d_ttl;
dprintf(3, (ddt,
- "db_update: new ttl %d, +%d\n",
- dp->d_ttl,
+ "db_update: new ttl %ld +%d\n",
+ (u_long)dp->d_ttl,
dp->d_ttl - tt.tv_sec));
}
return (DATAEXISTS);
@@ -493,8 +573,8 @@ db_update(name, odp, newdp, flags, htp)
* response source address here if flags&NOTAUTH.
*/
fixttl(newdp);
- dprintf(3, (ddt, "db_update: adding%s %x\n",
- (newdp->d_flags&DB_F_HINT) ? " hint":"", newdp));
+ dprintf(3, (ddt, "db_update: adding%s %lx\n",
+ (newdp->d_flags&DB_F_HINT) ? " hint":"", (u_long)newdp));
#ifdef INVQ
if (!(newdp->d_flags & DB_F_HINT))
addinv(np, newdp); /* modify inverse query tables */
@@ -553,7 +633,7 @@ db_cmp(dp1, dp2)
register struct databuf *dp1, *dp2;
{
register u_char *cp1, *cp2;
- int len;
+ int len, len2;
if (dp1->d_type != dp2->d_type || dp1->d_class != dp2->d_class)
return (1);
@@ -576,6 +656,7 @@ db_cmp(dp1, dp2)
case T_WKS:
case T_NULL:
case T_NSAP:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -595,11 +676,17 @@ db_cmp(dp1, dp2)
cp1 = dp1->d_data;
cp2 = dp2->d_data;
len = *cp1;
+ len2 = *cp2;
+ if (len != len2)
+ return (1);
if (strncasecmp((char *)++cp1, (char *)++cp2, len))
return (1);
cp1 += len;
cp2 += len;
len = *cp1;
+ len2 = *cp2;
+ if (len != len2)
+ return (1);
return (strncasecmp((char *)++cp1, (char *)++cp2, len));
case T_SOA:
@@ -626,6 +713,17 @@ db_cmp(dp1, dp2)
return (1);
return (strcasecmp((char *)cp1, (char *)cp2));
+ case T_PX:
+ cp1 = dp1->d_data;
+ cp2 = dp2->d_data;
+ if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* cmp prio */
+ return (1);
+ if (strcasecmp((char *)cp1, (char *)cp2))
+ return (1);
+ cp1 += strlen((char *)cp1) + 1;
+ cp2 += strlen((char *)cp2) + 1;
+ return (strcasecmp((char *)cp1, (char *)cp2));
+
case T_TXT:
case T_X25:
if (dp1->d_size != dp2->d_size)
diff --git a/usr.sbin/named/ns_defs.h b/usr.sbin/named/ns_defs.h
index d9a208bc1ca17..e462e4454b810 100644
--- a/usr.sbin/named/ns_defs.h
+++ b/usr.sbin/named/ns_defs.h
@@ -1,6 +1,6 @@
/*
* from ns.h 4.33 (Berkeley) 8/23/90
- * $Id: ns_defs.h,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $
+ * $Id: ns_defs.h,v 1.2 1995/05/30 03:48:47 rgrimes Exp $
*/
/*
@@ -95,7 +95,8 @@
#define MAX_XFER_TIME 60*60*2 /* max seconds for an xfer */
#define XFER_TIME_FUDGE 10 /* MAX_XFER_TIME fudge */
#define MAX_XFERS_RUNNING 10 /* default max value of xfers_running */
-#define MAX_XFERS_PERNS 2 /* max # of xfers per peer nameserver */
+#define MAX_XFERS_PER_NS 2 /* max # of xfers per peer nameserver */
+#define XFER_BUFSIZE (16*1024) /* arbitrary but bigger than most MTU's */
#define ALPHA 0.7 /* How much to preserve of old response time */
#define BETA 1.2 /* How much to penalize response time on failure */
@@ -128,7 +129,20 @@ struct zoneinfo {
#ifdef SECURE_ZONES
struct netinfo *secure_nets; /* list of secure networks for zone */
#endif
+#ifdef BIND_NOTIFY
+ /* XXX - this will have to move to the name when we do !SOA notify */
+ struct notify *z_notifylist; /* list of servers we should notify */
+#endif
+};
+
+#ifdef BIND_NOTIFY
+struct notify {
+ struct in_addr addr; /* of server */
+ time_t last; /* when they asked */
+ struct notify *next;
+ /* XXX - this will need a type field when we do !SOA notify */
};
+#endif
/* zone types (z_type) */
#define Z_NIL 0 /* zone slot not in use */
@@ -205,7 +219,12 @@ struct qinfo {
struct zoneinfo *q_zquery; /* Zone query is about (Q_ZSERIAL) */
#ifdef LAME_DELEGATION
char q_domain[MAXDNAME]; /* domain for servers we are querying */
-#endif /* LAME_DELEGATION */
+#endif
+#ifdef BIND_NOTIFY
+ int q_notifyzone; /* zone which needs a sysnotify()
+ * when the reply to this comes in.
+ */
+#endif
};
/* q_flags bits (8 bits) */
@@ -291,7 +310,12 @@ enum nameserStats { nssRcvdQ, /* sent us a query */
nssSentDupQ, /* sent them a retry */
nssSentFail, /* sent them a SERVFAIL */
nssSentFErr, /* sent them a FORMERR */
- nssSendtoErr, /* error in sendto(2) */
+ nssSendtoErr, /* error in sendto */
+#ifdef XSTATS
+ nssNotNsQ, /* query received from remote port != ns_port */
+ nssSentNaAns, /* sent them a non autoritative answer */
+ nssSentNXD, /* sent them a negative response */
+#endif
nssLast };
struct nameser {
@@ -346,12 +370,11 @@ typedef struct _to_validate TO_Validate;
#ifdef DEBUG
-# define dprintf(lev, args) ((debug >= lev) && fprintf args)
+# define dprintf(lev, args) (ddt && (debug >= lev) && fprintf args)
#else
# define dprintf(lev, args)
#endif
-
#ifdef INIT
error "INIT already defined, check system include files"
#endif
diff --git a/usr.sbin/named/ns_forw.c b/usr.sbin/named/ns_forw.c
index 19a1cd57f7e06..1d4ffbb860d26 100644
--- a/usr.sbin/named/ns_forw.c
+++ b/usr.sbin/named/ns_forw.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_forw.c 4.32 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: ns_forw.c,v 1.1.1.1 1994/09/22 19:46:11 pst Exp $";
+static char rcsid[] = "$Id: ns_forw.c,v 1.2 1995/05/30 03:48:49 rgrimes Exp $";
#endif /* not lint */
/*
@@ -104,7 +104,7 @@ ns_forw(nsp, msg, msglen, fp, qsp, dfd, qpp, dname, np)
hp = (HEADER *) msg;
id = hp->id;
/* Look at them all */
- for (qp = qhead; qp!=QINFO_NULL; qp = qp->q_link) {
+ for (qp = nsqhead; qp != QINFO_NULL; qp = qp->q_link) {
if (qp->q_id == id &&
bcmp((char *)&qp->q_from, fp, sizeof(qp->q_from)) == 0 &&
((qp->q_cmsglen == 0 && qp->q_msglen == msglen &&
@@ -138,12 +138,12 @@ ns_forw(nsp, msg, msglen, fp, qsp, dfd, qpp, dname, np)
qp->q_dfd = dfd;
qp->q_id = id;
qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2;
- hp->id = qp->q_nsid = htons((u_int16_t)++nsid);
+ hp->id = qp->q_nsid = htons(nsid_next());
hp->ancount = 0;
hp->nscount = 0;
hp->arcount = 0;
if ((qp->q_msg = (u_char *)malloc((unsigned)msglen)) == NULL) {
- syslog(LOG_ERR, "forw: %m");
+ syslog(LOG_NOTICE, "forw: malloc: %m");
qfree(qp);
return (FW_SERVFAIL);
}
@@ -169,15 +169,15 @@ ns_forw(nsp, msg, msglen, fp, qsp, dfd, qpp, dname, np)
(qp->q_addr[0].nsdata != NULL)
? qp->q_addr[0].nsdata->d_nstime
: -1,
- qp->q_time - tt.tv_sec));
+ (int)(qp->q_time - tt.tv_sec)));
#ifdef DEBUG
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, msglen, ddt);
#endif
- if (sendto(ds, msg, msglen, 0, (struct sockaddr *)nsa,
+ if (sendto(ds, (char *)msg, msglen, 0, (struct sockaddr *)nsa,
sizeof(struct sockaddr_in)) < 0) {
if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
- syslog(LOG_NOTICE, "ns_forw: sendto([%s].%d): %m",
+ syslog(LOG_INFO, "ns_forw: sendto([%s].%d): %m",
inet_ntoa(nsa->sin_addr), ntohs(nsa->sin_port));
nameserIncr(nsa->sin_addr, nssSendtoErr);
}
@@ -225,10 +225,10 @@ aIsUs(addr)
*/
int
haveComplained(tag1, tag2)
- char *tag1, *tag2;
+ const char *tag1, *tag2;
{
struct complaint {
- char *tag1, *tag2;
+ const char *tag1, *tag2;
time_t expire;
struct complaint *next;
};
@@ -274,20 +274,19 @@ haveComplained(tag1, tag2)
*/
void
nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr)
- char *sysloginfo, *queryname, *complaint, *dname;
- register struct databuf *a_rr;
+ const char *sysloginfo, *queryname, *complaint, *dname;
+ const struct databuf *a_rr;
{
dprintf(2, (ddt, "NS '%s' %s\n", dname, complaint));
if (sysloginfo && queryname && !haveComplained(queryname, complaint))
{
- char buf[512];
+ char buf[999];
/* syslog only takes 5 params */
sprintf(buf, "%s: query(%s) %s (%s:%s)",
sysloginfo, queryname,
- complaint, dname, inet_ntoa(
- *(struct in_addr*)a_rr->d_data
- ));
+ complaint, dname,
+ inet_ntoa(data_inaddr(a_rr->d_data)));
syslog(LOG_INFO, buf);
}
}
@@ -306,14 +305,14 @@ nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr)
* is detected.
* side effects:
* if a dangerous situation is detected and (syslogdname && sysloginfo),
- * calls syslog.
+ * calls syslog.
*/
int
nslookup(nsp, qp, syslogdname, sysloginfo)
struct databuf *nsp[];
register struct qinfo *qp;
- char *syslogdname;
- char *sysloginfo;
+ const char *syslogdname;
+ const char *sysloginfo;
{
register struct namebuf *np;
register struct databuf *dp, *nsdp;
@@ -321,20 +320,22 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
register int n;
register unsigned int i;
struct hashbuf *tmphtp;
- char *dname, *fname;
+ char *dname;
+ const char *fname;
int oldn, naddr, class, found_arr;
time_t curtime;
- dprintf(3, (ddt, "nslookup(nsp=0x%x, qp=0x%x, \"%s\")\n",
- nsp, qp, syslogdname));
+ dprintf(3, (ddt, "nslookup(nsp=0x%lx, qp=0x%lx, \"%s\")\n",
+ (u_long)nsp, (u_long)qp, syslogdname));
naddr = n = qp->q_naddr;
curtime = (u_long) tt.tv_sec;
while ((nsdp = *nsp++) != NULL) {
class = nsdp->d_class;
dname = (char *)nsdp->d_data;
- dprintf(3, (ddt, "nslookup: NS \"%s\" c=%d t=%d (0x%x)\n",
- dname, class, nsdp->d_type, nsdp->d_flags));
+ dprintf(3, (ddt, "nslookup: NS \"%s\" c=%d t=%d (%#lx)\n",
+ dname, class, nsdp->d_type,
+ (u_long)nsdp->d_flags));
/* don't put in servers we have tried */
for (i = 0; i < qp->q_nusedns; i++) {
@@ -349,8 +350,8 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
tmphtp = ((nsdp->d_flags & DB_F_HINT) ?fcachetab :hashtab);
np = nlookup(dname, &tmphtp, &fname, 1);
if (np == NULL || fname != dname) {
- dprintf(3, (ddt, "%s: not found %s %x\n",
- dname, fname, np));
+ dprintf(3, (ddt, "%s: not found %s %lx\n",
+ dname, fname, (u_long)np));
continue;
}
found_arr = 0;
@@ -360,42 +361,56 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
struct in_addr nsa;
+#ifdef NCACHE
+ if (dp->d_rcode)
+ continue;
+#endif
if (dp->d_type == T_CNAME && dp->d_class == class)
goto skipserver;
if (dp->d_type != T_A || dp->d_class != class)
continue;
-#ifdef NCACHE
- if (dp->d_rcode)
+ if (data_inaddr(dp->d_data).s_addr == INADDR_ANY) {
+ syslog(LOG_INFO, "Bogus (0.0.0.0) A RR for %s",
+ dname);
continue;
-#endif
+ }
/*
* Don't use records that may become invalid to
* reference later when we do the rtt computation.
* Never delete our safety-belt information!
*/
if ((dp->d_zone == 0) &&
+#ifdef DATUMREFCNT
+ (dp->d_ttl < curtime) &&
+#else
(dp->d_ttl < (curtime+900)) &&
+#endif
!(dp->d_flags & DB_F_HINT) )
{
dprintf(3, (ddt,
"nslookup: stale entry '%s'\n",
np->n_dname));
/* Cache invalidate the NS RR's */
+#ifndef DATUMREFCNT
if (dp->d_ttl < curtime)
+#endif
+ {
delete_all(np, class, T_A);
- n = oldn;
- break;
+ n = oldn;
+ found_arr = 0;
+ goto need_sysquery;
+ }
}
#ifdef VALIDATE
/* anant@isi.edu validation procedure, maintains a
* table of server names-addresses used recently
*/
- store_name_addr(dname, (struct in_addr *)dp->d_data,
+ store_name_addr(dname, data_inaddr(dp->d_data),
syslogdname, sysloginfo);
#endif /*VALIDATE*/
found_arr++;
- nsa = *(struct in_addr *)dp->d_data;
+ nsa = data_inaddr(dp->d_data);
/* don't put in duplicates */
qs = qp->q_addr;
for (i = 0; i < n; i++, qs++)
@@ -440,6 +455,7 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
complaint, dname, dp);
return (-1);
}
+#ifdef BOGUSNS
/*
* Don't forward queries to bogus servers. Note
* that this is unlike the previous tests, which
@@ -454,16 +470,20 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
*/
if (addr_on_netlist(nsa, boglist))
goto skipserver;
+#endif
n++;
if (n >= NSMAX)
goto out;
- skipaddr: ;
+ skipaddr:
+ NULL;
}
dprintf(8, (ddt, "nslookup: %d ns addrs\n", n));
+ need_sysquery:
if (found_arr == 0 && !(qp->q_flags & Q_SYSTEM))
- (void) sysquery(dname, class, T_A, NULL, 0);
-skipserver: ;
+ (void) sysquery(dname, class, T_A, NULL, 0, QUERY);
+ skipserver:
+ NULL;
}
out:
dprintf(3, (ddt, "nslookup: %d ns addrs total\n", n));
@@ -585,11 +605,12 @@ schedretry(qp, t)
#ifdef DEBUG
if (debug > 3) {
- fprintf(ddt,"schedretry(0x%x, %ld sec)\n", qp, (long)t);
+ fprintf(ddt, "schedretry(0x%lx, %ld sec)\n",
+ (u_long)qp, (long)t);
if (qp->q_time)
fprintf(ddt,
- "WARNING: schedretry(%#x, %d) q_time already %d\n",
- qp, t, qp->q_time);
+ "WARNING: schedretry(%#lx, %ld) q_time already %ld\n",
+ (u_long)qp, (long)t, (long)qp->q_time);
}
#endif
t += (u_long) tt.tv_sec;
@@ -620,7 +641,7 @@ unsched(qp)
{
register struct qinfo *np;
- dprintf(3, (ddt, "unsched(%#x, %d )\n", qp, ntohs(qp->q_id)));
+ dprintf(3, (ddt, "unsched(%#lx, %d)\n", (u_long)qp, ntohs(qp->q_id)));
if (retryqp == qp) {
retryqp = qp->q_next;
} else {
@@ -646,7 +667,7 @@ retry(qp)
register HEADER *hp;
struct sockaddr_in *nsa;
- dprintf(3, (ddt, "retry(x%x) id=%d\n", qp, ntohs(qp->q_id)));
+ dprintf(3, (ddt, "retry(x%lx) id=%d\n", (u_long)qp, ntohs(qp->q_id)));
if (qp->q_msg == NULL) { /* XXX - why? */
qremove(qp);
@@ -655,9 +676,10 @@ retry(qp)
if (qp->q_expire && (qp->q_expire < tt.tv_sec)) {
dprintf(1, (ddt,
- "retry(x%x): expired @ %d (%d secs before now (%d))\n",
- qp, qp->q_expire, tt.tv_sec - qp->q_expire,
- tt.tv_sec));
+ "retry(x%lx): expired @ %lu (%d secs before now (%lu))\n",
+ (u_long)qp, (u_long)qp->q_expire,
+ (int)(tt.tv_sec - qp->q_expire),
+ (u_long)tt.tv_sec));
if (qp->q_stream) /* return failure code on stream */
goto fail;
qremove(qp);
@@ -701,16 +723,16 @@ fail:
n = ((HEADER *)qp->q_cmsg ? qp->q_cmsglen : qp->q_msglen);
hp->id = qp->q_id;
hp->qr = 1;
- hp->ra = 1;
+ hp->ra = (NoRecurse == 0);
hp->rd = 1;
hp->rcode = SERVFAIL;
#ifdef DEBUG
if (debug >= 10)
- fp_query(qp->q_msg, ddt);
+ fp_nquery(qp->q_msg, n, ddt);
#endif
if (send_msg((u_char *)hp, n, qp)) {
- dprintf(1, (ddt,"gave up retry(x%x) nsid=%d id=%d\n",
- qp, ntohs(qp->q_nsid), ntohs(qp->q_id)));
+ dprintf(1, (ddt, "gave up retry(x%lx) nsid=%d id=%d\n",
+ (u_long)qp, ntohs(qp->q_nsid), ntohs(qp->q_id)));
}
nameserIncr(qp->q_from.sin_addr, nssSentFail);
qremove(qp);
@@ -735,10 +757,10 @@ found:
: (-1)));
#ifdef DEBUG
if (debug >= 10)
- fp_query(qp->q_msg, ddt);
+ fp_nquery(qp->q_msg, qp->q_msglen, ddt);
#endif
/* NOSTRICT */
- if (sendto(ds, qp->q_msg, qp->q_msglen, 0,
+ if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
(struct sockaddr *)nsa,
sizeof(struct sockaddr_in)) < 0) {
dprintf(3, (ddt, "error resending msg errno=%d\n", errno));
@@ -783,16 +805,16 @@ retrytime(qp)
void
qflush()
{
- while (qhead)
- qremove(qhead);
- qhead = QINFO_NULL;
+ while (nsqhead)
+ qremove(nsqhead);
+ nsqhead = QINFO_NULL;
}
void
qremove(qp)
register struct qinfo *qp;
{
- dprintf(3, (ddt, "qremove(x%x)\n", qp));
+ dprintf(3, (ddt, "qremove(x%lx)\n", (u_long)qp));
if (qp->q_flags & Q_ZSERIAL)
qserial_answer(qp, 0);
@@ -812,7 +834,7 @@ qfindid(id)
register struct qinfo *qp;
dprintf(3, (ddt, "qfindid(%d)\n", ntohs(id)));
- for (qp = qhead; qp!=QINFO_NULL; qp = qp->q_link) {
+ for (qp = nsqhead; qp!=QINFO_NULL; qp = qp->q_link) {
if (qp->q_nsid == id)
return(qp);
}
@@ -831,20 +853,23 @@ qnew()
{
register struct qinfo *qp;
- if ((qp = (struct qinfo *)
+ qp = (struct qinfo *)
#ifdef DMALLOC
- dcalloc(file, line,
+ dcalloc(file, line, 1, sizeof(struct qinfo));
#else
- calloc(
+ calloc(1, sizeof(struct qinfo));
#endif
- 1, sizeof(struct qinfo))) == NULL) {
+ if (qp == NULL) {
dprintf(5, (ddt, "qnew: calloc error\n"));
syslog(LOG_ERR, "forw: %m");
exit(12);
}
- dprintf(5, (ddt, "qnew(x%x)\n", qp));
- qp->q_link = qhead;
- qhead = qp;
+ dprintf(5, (ddt, "qnew(x%lx)\n", (u_long)qp));
+#ifdef BIND_NOTIFY
+ qp->q_notifyzone = DB_Z_CACHE;
+#endif
+ qp->q_link = nsqhead;
+ nsqhead = qp;
return (qp);
}
@@ -858,12 +883,10 @@ qfree(qp)
int i;
#endif
-#ifdef DEBUG
- if(debug > 3)
- fprintf(ddt,"Qfree( x%x )\n", qp);
- if(debug && qp->q_next)
- fprintf(ddt,"WARNING: qfree of linked ptr x%x\n", qp);
-#endif
+ dprintf(3, (ddt, "Qfree(x%lx)\n", (u_long)qp));
+ if (qp->q_next)
+ dprintf(1, (ddt, "WARNING: qfree of linked ptr x%lx\n",
+ (u_long)qp));
if (qp->q_msg)
free(qp->q_msg);
if (qp->q_cmsg)
@@ -896,10 +919,10 @@ qfree(qp)
}
}
#endif
- if( qhead == qp ) {
- qhead = qp->q_link;
+ if( nsqhead == qp ) {
+ nsqhead = qp->q_link;
} else {
- for( np=qhead; np->q_link != QINFO_NULL; np = np->q_link ) {
+ for( np=nsqhead; np->q_link != QINFO_NULL; np = np->q_link ) {
if( np->q_link != qp ) continue;
np->q_link = qp->q_link; /* dequeue */
break;
diff --git a/usr.sbin/named/ns_func.h b/usr.sbin/named/ns_func.h
index eaff3bfe11fb6..ba1847c3c1538 100644
--- a/usr.sbin/named/ns_func.h
+++ b/usr.sbin/named/ns_func.h
@@ -1,16 +1,18 @@
/* ns_func.h - declarations for ns_*.c's externally visible functions
*
- * $Id: ns_func.h,v 1.12 1994/07/22 08:42:39 vixie Exp $
+ * $Id: ns_func.h,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $
*/
/* ++from ns_resp.c++ */
extern void ns_resp __P((u_char *, int)),
prime_cache __P((void)),
delete_all __P((struct namebuf *, int, int));
-extern struct qinfo *sysquery __P((char *, int, int,
- struct in_addr *, int));
-extern int
- doupdate __P((u_char *, int, u_char *, int,
+extern struct qinfo *sysquery __P((const char *, int, int,
+ struct in_addr *, int, int));
+extern struct notify *findNotifyPeer __P((const struct zoneinfo *,
+ struct in_addr));
+extern void sysnotify __P((const char *, int, int));
+extern int doupdate __P((u_char *, int, u_char *, int,
struct databuf **, int, u_int)),
send_msg __P((u_char *, int, struct qinfo *)),
findns __P((struct namebuf **, int,
@@ -27,14 +29,20 @@ extern int
extern void ns_req __P((u_char *, int, int,
struct qstream *,
struct sockaddr_in *,
- int));
+ int)),
+ free_addinfo __P((void)),
+ free_nsp __P((struct databuf **));
extern int stale __P((struct databuf *)),
- make_rr __P((char *, struct databuf *,
+ make_rr __P((const char *, struct databuf *,
u_char *, int, int)),
doaddinfo __P((HEADER *, u_char *, int)),
doaddauth __P((HEADER *, u_char *, int,
struct namebuf *,
struct databuf *));
+#ifdef BIND_NOTIFY
+extern int findZonePri __P((const struct zoneinfo *,
+ const struct sockaddr_in *));
+#endif
/* --from ns_req.c-- */
/* ++from ns_forw.c++ */
@@ -48,15 +56,16 @@ extern int ns_forw __P((struct databuf *nsp[],
struct qinfo **qpp,
char *dname,
struct namebuf *np)),
- haveComplained __P((char *, char *)),
+ haveComplained __P((const char *, const char *)),
nslookup __P((struct databuf *nsp[],
struct qinfo *qp,
- char *syslogdname,
- char *sysloginfo)),
+ const char *syslogdname,
+ const char *sysloginfo)),
qcomp __P((struct qserv *, struct qserv *));
extern struct qdatagram *aIsUs __P((struct in_addr));
-extern void nslookupComplain __P((char *, char *, char *, char *,
- struct databuf *)),
+extern void nslookupComplain __P((const char *, const char *,
+ const char *, const char *,
+ const struct databuf *)),
schedretry __P((struct qinfo *, time_t)),
unsched __P((struct qinfo *)),
retry __P((struct qinfo *)),
@@ -79,7 +88,9 @@ extern void sqrm __P((struct qstream *)),
dqflush __P((time_t gen)),
sq_done __P((struct qstream *)),
ns_setproctitle __P((char *, int)),
- getnetconf __P((void));
+ getnetconf __P((void)),
+ nsid_init __P((void));
+extern u_int16_t nsid_next __P((void));
extern struct netinfo *findnetinfo __P((struct in_addr));
/* --from ns_main.c-- */
@@ -91,9 +102,14 @@ extern void ns_maint __P((void)),
#else
remove_zone __P((struct hashbuf *, int)),
#endif
+#ifdef PURGE_ZONE
+ purge_zone __P((const char *, struct hashbuf *, int)),
+#endif
loadxfer __P((void)),
+ qserial_query __P((struct zoneinfo *)),
qserial_answer __P((struct qinfo *, u_int32_t));
-extern SIG_FN endxfer __P((void));
+extern SIG_FN endxfer __P(());
+extern const char * zoneTypeString __P((const struct zoneinfo *));
#ifdef DEBUG
extern void printzoneinfo __P((int));
#endif
@@ -107,7 +123,9 @@ extern void sort_response __P((u_char *, int,
/* --from ns_sort.c-- */
/* ++from ns_init.c++ */
-extern void ns_init __P((char *));
+extern void ns_refreshtime __P((struct zoneinfo *, time_t)),
+ ns_retrytime __P((struct zoneinfo *, time_t)),
+ ns_init __P((char *));
/* --from ns_init.c-- */
/* ++from ns_ncache.c++ */
@@ -116,6 +134,9 @@ extern void cache_n_resp __P((u_char *, int));
/* ++from ns_stats.c++ */
extern void ns_stats __P((void));
+#ifdef XSTATS
+extern void ns_logstats __P((void));
+#endif
extern void qtypeIncr __P((int qtype));
extern struct nameser *nameserFind __P((struct in_addr addr, int flags));
#define NS_F_INSERT 0x0001
@@ -135,6 +156,6 @@ extern int
dovalidate __P((u_char *, int, u_char *, int, int,
struct sockaddr_in *, int *)),
update_msg __P((u_char *, int *, int Vlist[], int));
-extern void store_name_addr __P((char *, struct in_addr *,
+extern void store_name_addr __P((char *, struct in_addr,
char *, char *));
/* --from ns_validate.c-- */
diff --git a/usr.sbin/named/ns_glob.h b/usr.sbin/named/ns_glob.h
index 4e72a48c16c0c..d229c955c1146 100644
--- a/usr.sbin/named/ns_glob.h
+++ b/usr.sbin/named/ns_glob.h
@@ -1,6 +1,6 @@
/*
* from ns.h 4.33 (Berkeley) 8/23/90
- * $Id: ns_glob.h,v 1.1.1.1 1994/09/22 19:46:14 pst Exp $
+ * $Id: ns_glob.h,v 1.2 1995/05/30 03:48:50 rgrimes Exp $
*/
/*
@@ -77,14 +77,11 @@ DECL struct qdatagram *datagramq INIT(QDATAGRAM_NULL);
DECL struct timeval tt;
/* head of allocated queries */
-DECL struct qinfo *qhead INIT(QINFO_NULL);
+DECL struct qinfo *nsqhead INIT(QINFO_NULL);
/* list of forwarding hosts */
DECL struct fwdinfo *fwdtab INIT(NULL);
- /* next forwarded query id */
-DECL int nsid INIT(0);
-
/* datagram socket */
DECL int ds INIT(-1);
@@ -101,6 +98,16 @@ DECL int needmaint INIT(0);
/* (beware: this is also the upper bound on named_xfer real time) */
DECL int maint_interval INIT(15*60);
+#ifdef CLEANCACHE
+ /* What's the minimum interval between cache cleanings? */
+DECL int cache_interval INIT(60*60);
+#endif
+
+#ifdef XSTATS
+ /* What's the minimum interval between stats output? */
+DECL int stats_interval INIT(60*60);
+#endif
+
/* need to reload secondary zone(s) */
DECL int needzoneload INIT(0);
@@ -122,6 +129,13 @@ DECL int needStatsDump INIT(0);
*/
DECL int needToExit INIT(0);
#endif /* ALLOW_UPDATES */
+#ifdef XSTATS
+ /* need to exit
+ * set by shutdown signal handler
+ * (onintr)
+ */
+DECL int needToExit INIT(0);
+#endif /* XSTATS */
#ifdef QRYLOG
/* is query logging turned on? */
@@ -231,15 +245,23 @@ DECL int slave_retry INIT(4);
#endif
#ifdef STATSFILE
-DECL char *statsfile INIT(STATSFILE);
+DECL const char *statsfile INIT(STATSFILE);
#else
-DECL char *statsfile INIT(_PATH_STATS);
+DECL const char *statsfile INIT(_PATH_STATS);
#endif
-DECL char sendtoStr[] INIT("sendto");
+DECL const char sendtoStr[] INIT("sendto");
/* defined in version.c, can't use DECL/INIT */
extern char Version[];
/* max value of xfers_running */
-DECL int max_xfers_running INIT(MAX_XFERS_RUNNING);
+DECL int max_xfers_running INIT(MAX_XFERS_RUNNING);
+
+ /* max number of transfers to any given name server */
+DECL int max_xfers_per_ns INIT(MAX_XFERS_PER_NS);
+
+#ifndef INVQ
+ /* should IQUERY be answered bogusly rather than with NOTIMPL? */
+DECL int fake_iquery INIT(0);
+#endif
diff --git a/usr.sbin/named/ns_init.c b/usr.sbin/named/ns_init.c
index af5ad93ab0eb5..e3af752105b86 100644
--- a/usr.sbin/named/ns_init.c
+++ b/usr.sbin/named/ns_init.c
@@ -70,22 +70,55 @@ static char rcsid[] = "$Id:";
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
+#include <assert.h>
#include "named.h"
#undef nsaddr
+enum limit { Datasize };
+
static void zoneinit __P((struct zoneinfo *)),
get_forwarders __P((FILE *)),
boot_read __P((char *)),
#ifdef DEBUG
content_zone __P((int)),
#endif
- free_forwarders __P((void));
+ free_forwarders __P((void)),
+ ns_limit __P((const char *name, int value)),
+ ns_rlimit __P((const char *name, enum limit limit,
+ long value)),
+ ns_option __P((const char *name));
static struct zoneinfo *find_zone __P((char *, int, int));
/*
+ * Set new refresh time for zone. Use a random number in the last half of
+ * the refresh limit; we want it to be substantially correct while still
+ * preventing slave synchronization.
+ */
+void
+ns_refreshtime(zp, timebase)
+ struct zoneinfo *zp;
+ time_t timebase;
+{
+ register time_t half = ((zp->z_refresh + 1) / 2);
+
+ zp->z_time = timebase + half + (rand() % half);
+}
+
+/*
+ * Set new retry time for zone.
+ */
+void
+ns_retrytime(zp, timebase)
+ struct zoneinfo *zp;
+ time_t timebase;
+{
+ zp->z_time = timebase + zp->z_retry;
+}
+
+/*
* Read boot file for configuration info.
*/
void
@@ -114,6 +147,7 @@ ns_init(bootfile)
fcachetab = savehash((struct hashbuf *)NULL);
/* init zone data */
zones[0].z_type = Z_CACHE;
+ zones[0].z_origin = "";
} else {
/* Mark previous zones as not yet found in boot file. */
for (zp = &zones[1]; zp < &zones[nzones]; zp++)
@@ -197,7 +231,7 @@ boot_read(bootfile)
struct stat f_time;
static int tmpnum = 0; /* unique number for tmp zone files */
#ifdef ALLOW_UPDATES
- char *cp, *flag;
+ char *flag;
#endif
int slineno; /* Saved global line number. */
int i;
@@ -208,12 +242,17 @@ boot_read(bootfile)
}
slineno = lineno;
- lineno = 0;
+ lineno = 1;
while (!feof(fp) && !ferror(fp)) {
- if (!getword(buf, sizeof(buf), fp))
- continue;
/* read named.boot keyword and process args */
+ if (!getword(buf, sizeof(buf), fp)) {
+ /*
+ * This is a blank line, a commented line, or the
+ * '\n' of the previous line.
+ */
+ continue;
+ }
if (strcasecmp(buf, "directory") == 0) {
(void) getword(buf, sizeof(buf), fp);
if (chdir(buf) < 0) {
@@ -226,14 +265,21 @@ boot_read(bootfile)
get_netlist(fp, enettab, ALLOW_NETS, buf);
continue;
} else if (strcasecmp(buf, "max-fetch") == 0) {
- max_xfers_running = getnum(fp, bootfile, 0);
+ max_xfers_running = getnum(fp, bootfile, GETNUM_NONE);
+ continue;
+ } else if (strcasecmp(buf, "limit") == 0) {
+ (void) getword(buf, sizeof(buf), fp);
+ ns_limit(buf, getnum(fp, bootfile, GETNUM_SCALED));
+ continue;
+ } else if (strcasecmp(buf, "options") == 0) {
+ while (getword(buf, sizeof(buf), fp))
+ ns_option(buf);
continue;
} else if (strcasecmp(buf, "forwarders") == 0) {
get_forwarders(fp);
continue;
} else if (strcasecmp(buf, "slave") == 0) {
forward_only++;
- endline(fp);
continue;
#ifdef BOGUSNS
} else if (strcasecmp(buf, "bogusns") == 0) {
@@ -250,20 +296,26 @@ boot_read(bootfile)
} else if (strcasecmp(buf, "domain") == 0) {
if (getword(buf, sizeof(buf), fp))
localdomain = savestr(buf);
- endline(fp);
continue;
#endif
} else if (strcasecmp(buf, "include") == 0) {
if (getword(buf, sizeof(buf), fp))
boot_read(buf);
- endline(fp);
continue;
} else if (strncasecmp(buf, "cache", 5) == 0) {
type = Z_CACHE;
class = C_IN;
#ifdef GEN_AXFR
- if (class_p = strchr(buf, '/'))
+ if (class_p = strchr(buf, '/')) {
class = get_class(class_p+1);
+
+ if (class != C_IN) {
+ syslog(LOG_NOTICE,
+ "cache directive with non-IN class is not supported (yet)");
+ endline(fp);
+ continue;
+ }
+ }
#endif
} else if (strncasecmp(buf, "primary", 7) == 0) {
type = Z_PRIMARY;
@@ -289,8 +341,9 @@ boot_read(bootfile)
#endif
#endif
} else {
- syslog(LOG_ERR, "%s: line %d: unknown field '%s'\n",
- bootfile, lineno+1, buf);
+ syslog(LOG_NOTICE,
+ "%s: line %d: unknown directive '%s'\n",
+ bootfile, lineno, buf);
endline(fp);
continue;
}
@@ -299,22 +352,23 @@ boot_read(bootfile)
* read zone origin
*/
if (!getword(obuf, sizeof(obuf), fp)) {
- syslog(LOG_ERR, "%s: line %d: missing origin\n",
+ syslog(LOG_NOTICE, "%s: line %d: missing origin\n",
bootfile, lineno);
continue;
}
i = strlen(obuf);
if ((obuf[i-1] == '.') && (i != 1))
- syslog(LOG_ERR, "%s: line %d: zone \"%s\" has trailing dot\n",
- bootfile, lineno, obuf);
+ syslog(LOG_INFO,
+ "%s: line %d: zone \"%s\" has trailing dot\n",
+ bootfile, lineno, obuf);
while ((--i >= 0) && (obuf[i] == '.'))
obuf[i] = '\0';
dprintf(1, (ddt, "zone origin %s", obuf[0]?obuf:"."));
/*
- * read source file or host address
+ * Read source file or host address.
*/
if (!getword(buf, sizeof(buf), fp)) {
- syslog(LOG_ERR, "%s: line %d: missing %s\n",
+ syslog(LOG_NOTICE, "%s: line %d: missing %s\n",
bootfile, lineno,
#ifdef STUBS
(type == Z_SECONDARY || type == Z_STUB)
@@ -326,36 +380,33 @@ boot_read(bootfile)
continue;
}
- /* check for previous instance of this zone (reload) */
+ /*
+ * Check for previous instance of this zone (reload).
+ */
if (!(zp = find_zone(obuf, type, class))) {
if (type == Z_CACHE) {
zp = &zones[0];
- zp->z_origin = "";
goto gotcache;
}
for (zp = &zones[1]; zp < &zones[nzones]; zp++)
if (zp->z_type == Z_NIL)
goto gotzone;
/*
- * this code assumes that nzones never decreases
+ * This code assumes that nzones never decreases.
*/
if (nzones % 64 == 0) {
dprintf(1, (ddt,
"Reallocating zones structure\n"));
/*
* Realloc() not used since it might damage zones
- * if an error occurs
+ * if an error occurs.
*/
zp = (struct zoneinfo *)
malloc((64 + nzones)
* sizeof(struct zoneinfo));
if (zp == (struct zoneinfo *)0) {
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"no memory for more zones");
- dprintf(1, (ddt,
- "Out of memory for new zones\n"
- )
- );
endline(fp);
continue;
}
@@ -384,16 +435,16 @@ boot_read(bootfile)
#ifdef notyet
zp->z_refresh = atoi(buf);
if (zp->z_refresh <= 0) {
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"%s: line %d: bad refresh time '%s', ignored\n",
bootfile, lineno, buf);
zp->z_refresh = 0;
} else if (cache_file == NULL)
cache_file = source;
#else
- syslog(LOG_WARNING,
- "%s: line %d: cache refresh ignored\n",
- bootfile, lineno);
+ syslog(LOG_NOTICE,
+ "%s: line %d: cache refresh ignored\n",
+ bootfile, lineno);
#endif
endline(fp);
}
@@ -424,7 +475,7 @@ boot_read(bootfile)
}
zp->z_source = source;
dprintf(1, (ddt, "reloading zone\n"));
- (void) db_load(zp->z_source, zp->z_origin, zp, 0);
+ (void) db_load(zp->z_source, zp->z_origin, zp, NULL);
break;
case Z_PRIMARY:
@@ -434,7 +485,7 @@ boot_read(bootfile)
endline(fp);
flag = buf;
while (flag) {
- cp = strchr(flag, ',');
+ char *cp = strchr(flag, ',');
if (cp)
*cp++ = 0;
if (strcasecmp(flag, "dynamic") == 0)
@@ -442,7 +493,7 @@ boot_read(bootfile)
else if (strcasecmp(flag, "addonly") == 0)
zp->z_flags |= Z_DYNADDONLY;
else {
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"%s: line %d: bad flag '%s'\n",
bootfile, lineno, flag);
}
@@ -478,8 +529,11 @@ boot_read(bootfile)
}
zp->z_source = source;
zp->z_flags &= ~Z_AUTH;
+#ifdef PURGE_ZONE
+ purge_zone(zp->z_origin, hashtab, zp->z_class);
+#endif
dprintf(1, (ddt, "reloading zone\n"));
- if (db_load(zp->z_source, zp->z_origin, zp, 0) == 0)
+ if (!db_load(zp->z_source, zp->z_origin, zp, NULL))
zp->z_flags |= Z_AUTH;
#ifdef ALLOW_UPDATES
/* Guarantee calls to ns_maint() */
@@ -517,8 +571,8 @@ boot_read(bootfile)
* We will always transfer this zone again
* after a reload.
*/
- sprintf(buf, "/%s/NsTmp%d.%d", _PATH_TMPDIR,
- getpid(), tmpnum++);
+ sprintf(buf, "/%s/NsTmp%ld.%d", _PATH_TMPDIR,
+ (long)getpid(), tmpnum++);
source = savestr(buf);
zp->z_flags |= Z_TMP_FILE;
} else
@@ -565,16 +619,21 @@ boot_read(bootfile)
break;
}
- zp->z_flags |= Z_FOUND;
+ if ((zp->z_flags & Z_FOUND) && /* already found? */
+ (zp - zones) != DB_Z_CACHE) /* cache never sets Z_FOUND */
+ syslog(LOG_NOTICE,
+ "Zone \"%s\" declared more than once",
+ zp->z_origin);
+ zp->z_flags |= Z_FOUND;
dprintf(1, (ddt, "zone[%d] type %d: '%s'",
zp-zones, type,
*(zp->z_origin) == '\0' ? "." : zp->z_origin));
if (zp->z_refresh && zp->z_time == 0)
- zp->z_time = zp->z_refresh + tt.tv_sec;
+ ns_refreshtime(zp, tt.tv_sec);
if (zp->z_time <= tt.tv_sec)
needmaint = 1;
- dprintf(1, (ddt, " z_time %d, z_refresh %d\n",
- zp->z_time, zp->z_refresh));
+ dprintf(1, (ddt, " z_time %lu, z_refresh %lu\n",
+ (u_long)zp->z_time, (u_long)zp->z_refresh));
}
(void) my_fclose(fp);
lineno = slineno;
@@ -585,6 +644,7 @@ zoneinit(zp)
register struct zoneinfo *zp;
{
struct stat sb;
+ int result;
/*
* Try to load zone from backup file,
@@ -595,8 +655,12 @@ zoneinit(zp)
*/
if (!zp->z_source)
return;
- if (stat(zp->z_source, &sb) == -1 ||
- db_load(zp->z_source, zp->z_origin, zp, 0) != 0) {
+ result = stat(zp->z_source, &sb);
+#ifdef PURGE_ZONE
+ if (result != -1)
+ purge_zone(zp->z_origin, hashtab, zp->z_class);
+#endif
+ if (result == -1 || db_load(zp->z_source, zp->z_origin, zp, NULL)) {
/*
* Set zone to be refreshed immediately.
*/
@@ -710,14 +774,13 @@ get_forwarders(fp)
ftp->fwdaddr.sin_port = ns_port;
ftp->fwdaddr.sin_family = AF_INET;
} else {
- syslog(LOG_ERR, "'%s' (ignored, NOT dotted quad)",
+ syslog(LOG_NOTICE, "'%s' (ignored, NOT dotted quad)",
buf);
- dprintf(1, (ddt, " (ignored, NOT dotted quad)"));
continue;
}
#ifdef FWD_LOOP
if (aIsUs(ftp->fwdaddr.sin_addr)) {
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"Forwarder '%s' ignored, my address",
buf);
dprintf(1, (ddt, " (ignored, my address)"));
@@ -754,10 +817,10 @@ get_forwarders(fp)
#ifdef DEBUG
if (debug > 2) {
for (ftp = fwdtab; ftp != NULL; ftp = ftp->next) {
- fprintf(ddt,"ftp x%x [%s] next x%x\n",
- ftp,
+ fprintf(ddt, "ftp x%lx [%s] next x%lx\n",
+ (u_long)ftp,
inet_ntoa(ftp->fwdaddr.sin_addr),
- ftp->next);
+ (u_long)ftp->next);
}
}
#endif
@@ -806,3 +869,79 @@ content_zone(end)
}
}
#endif
+
+static void
+ns_limit(name, value)
+ const char *name;
+ int value;
+{
+ if (!strcasecmp(name, "transfers-in")) {
+ max_xfers_running = value;
+ } else if (!strcasecmp(name, "transfers-per-ns")) {
+ max_xfers_per_ns = value;
+ } else if (!strcasecmp(name, "datasize")) {
+ ns_rlimit("datasize", Datasize, value);
+ } else {
+ syslog(LOG_ERR,
+ "error: unrecognized limit in bootfile: \"%s\"",
+ name);
+ exit(1);
+ }
+}
+
+static void
+ns_rlimit(name, limit, value)
+ const char *name;
+ enum limit limit;
+ long value;
+{
+#ifndef HAVE_GETRUSAGE
+# ifdef LINT
+ name; limit; value;
+# endif
+ syslog(LOG_WARNING, "warning: unimplemented limit in bootfile: \"%s\"",
+ name);
+#else
+ struct rlimit limits;
+ int rlimit;
+
+ switch (limit) {
+ case Datasize:
+ rlimit = RLIMIT_DATA;
+ break;
+ default:
+ abort();
+ }
+ if (getrlimit(rlimit, &limits) < 0) {
+ syslog(LOG_WARNING, "getrlimit(%s): %m", name);
+ return;
+ }
+ limits.rlim_cur = value;
+ if (setrlimit(rlimit, &limits) < 0) {
+ syslog(LOG_WARNING, "setrlimit(%s, %ld): %m", name, value);
+ return;
+ }
+#endif
+}
+
+static void
+ns_option(name)
+ const char *name;
+{
+ if (!strcasecmp(name, "no-recursion")) {
+ NoRecurse = 1;
+ } else if (!strcasecmp(name, "query-log")) {
+ qrylog = 1;
+ } else if (!strcasecmp(name, "forward-only")) {
+ forward_only = 1;
+#ifndef INVQ
+ } else if (!strcasecmp(name, "fake-iquery")) {
+ fake_iquery = 1;
+#endif
+ } else {
+ syslog(LOG_ERR,
+ "error: unrecognized option in bootfile: \"%s\"",
+ name);
+ exit(1);
+ }
+}
diff --git a/usr.sbin/named/ns_main.c b/usr.sbin/named/ns_main.c
index 10c294e4d3a48..f1b974f6985af 100644
--- a/usr.sbin/named/ns_main.c
+++ b/usr.sbin/named/ns_main.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_main.c 4.55 (Berkeley) 7/1/91";
-static char rcsid[] = "$Id: ns_main.c,v 1.1.1.1 1994/09/22 19:46:12 pst Exp $";
+static char rcsid[] = "$Id: ns_main.c,v 1.2 1995/05/30 03:48:52 rgrimes Exp $";
#endif /* not lint */
/*
@@ -76,17 +76,22 @@ char copyright[] =
#if !defined(SYSV) && defined(XXX)
#include <sys/wait.h>
#endif /* !SYSV */
-#include <sys/time.h>
-#define TIME_H_INCLUDED
-#include <sys/resource.h>
#if defined(__osf__)
-#define _SOCKADDR_LEN /* XXX - should be in portability.h but that
+# define _SOCKADDR_LEN /* XXX - should be in portability.h but that
* would need to be included before socket.h
*/
#endif
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#if defined(__osf__)
+# include <sys/mbuf.h>
+# include <net/route.h>
+#endif
+#if defined(_AIX)
+# include <sys/time.h>
+# define TIME_H_INCLUDED
+#endif
#include <net/if.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
@@ -108,10 +113,13 @@ char copyright[] =
#undef nsaddr
/* UDP receive, TCP send buffer size */
-static const int rbufsize = 8 * 1024;
+static const int rbufsize = 8 * 1024,
+ /* TCP send window size */
+ sbufsize = 16 * 1024;
static struct sockaddr_in nsaddr;
-static u_int16_t local_ns_port; /* our service port */
+static u_int16_t local_ns_port, /* our service port */
+ nsid_state;
static fd_set mask; /* open descriptors */
static char **Argv = NULL;
static char *LastArg = NULL; /* end of argv */
@@ -165,9 +173,13 @@ main(argc, argv, envp)
int rfd, size;
time_t lasttime, maxctime;
u_char buf[BUFSIZ];
+#ifdef POSIX_SIGNALS
+ struct sigaction sact;
+#else
#ifndef SYSV
struct sigvec vec;
#endif
+#endif
fd_set tmpmask;
struct timeval t, *tp;
struct qstream *candidate = QSTREAM_NULL;
@@ -184,6 +196,12 @@ main(argc, argv, envp)
local_ns_port = ns_port = htons(NAMESERVER_PORT);
+ /* BSD has a better random number generator but it's not clear
+ * that we need it here.
+ */
+ gettime(&tt);
+ srand(((unsigned)getpid()) + (unsigned)tt.tv_usec);
+
/*
** Save start and extent of argv for ns_setproctitle().
*/
@@ -298,7 +316,7 @@ main(argc, argv, envp)
if (fp != NULL) {
(void) fgets(oldpid, sizeof(oldpid), fp);
(void) rewind(fp);
- fprintf(fp, "%d\n", getpid());
+ fprintf(fp, "%ld\n", (long)getpid());
(void) my_fclose(fp);
}
#else /*PID_FIX*/
@@ -317,6 +335,7 @@ main(argc, argv, envp)
nsaddr.sin_family = AF_INET;
nsaddr.sin_addr.s_addr = INADDR_ANY;
nsaddr.sin_port = local_ns_port;
+ nsid_init();
/*
** Open stream port.
@@ -329,7 +348,7 @@ main(argc, argv, envp)
if (setsockopt(vs, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
sizeof(on)) != 0)
{
- syslog(LOG_ERR, "setsockopt(vs, reuseaddr): %m");
+ syslog(LOG_NOTICE, "setsockopt(vs, reuseaddr): %m");
(void) my_close(vs);
continue;
}
@@ -338,7 +357,7 @@ main(argc, argv, envp)
if (errno != EADDRINUSE || n > 4) {
if (errno == EADDRINUSE) {
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"There may be a name server already running");
syslog(LOG_ERR, "exiting");
} else {
@@ -409,8 +428,20 @@ main(argc, argv, envp)
#if defined(SIGXFSZ)
(void) signal(SIGXFSZ, onhup); /* wierd DEC Hesiodism, harmless */
#endif
+#if defined(POSIX_SIGNALS)
+ bzero((char *)&sact, sizeof(sact));
+ sact.sa_handler = maint_alarm;
+ sigemptyset(&sact.sa_mask);
+ sigaddset(&sact.sa_mask, SIGCHLD);
+ (void) sigaction(SIGALRM, &sact, (struct sigaction *)NULL);
+
+ sact.sa_handler = endxfer;
+ sigemptyset(&sact.sa_mask);
+ sigaddset(&sact.sa_mask, SIGALRM);
+ (void) sigaction(SIGCHLD, &sact, (struct sigaction *)NULL);
+#else
#if defined(SYSV)
- (void) signal(SIGCLD, endxfer);
+ (void) signal(SIGCLD, (SIG_FN (*)()) endxfer);
(void) signal(SIGALRM, maint_alarm);
#else
bzero((char *)&vec, sizeof(vec));
@@ -422,6 +453,7 @@ main(argc, argv, envp)
vec.sv_mask = sigmask(SIGALRM);
(void) sigvec(SIGCHLD, &vec, (struct sigvec *)NULL);
#endif /* SYSV */
+#endif /* POSIX_SIGNALS */
(void) signal(SIGPIPE, SIG_IGN);
#ifdef SIGSYS
(void) signal(SIGSYS, sigprof);
@@ -433,6 +465,11 @@ main(argc, argv, envp)
(void) signal(SIGTERM, onintr);
#endif
+#ifdef XSTATS
+ /* Catch SIGTERM so we can write stats before exiting. */
+ (void) signal(SIGTERM, onintr);
+#endif
+
dprintf(1, (ddt, "database initialized\n"));
t.tv_usec = 0;
@@ -488,7 +525,7 @@ main(argc, argv, envp)
(void) dup2(n, 2);
if (n > 2)
(void) my_close(n);
-#ifdef SYSV
+#if defined(SYSV) || defined(hpux)
setpgrp();
#else
{
@@ -523,7 +560,7 @@ main(argc, argv, envp)
/* tuck my process id away again */
fp = fopen(PidFile, "w");
if (fp != NULL) {
- fprintf(fp, "%d\n", getpid());
+ fprintf(fp, "%ld\n", (long)getpid());
(void) my_fclose(fp);
}
#endif
@@ -533,7 +570,7 @@ main(argc, argv, envp)
nfds = getdtablesize(); /* get the number of file descriptors */
if (nfds > FD_SETSIZE) {
nfds = FD_SETSIZE; /* Bulletproofing */
- syslog(LOG_ERR, "Return from getdtablesize() > FD_SETSIZE");
+ syslog(LOG_NOTICE, "Return from getdtablesize() > FD_SETSIZE");
}
FD_ZERO(&mask);
FD_SET(vs, &mask);
@@ -563,6 +600,12 @@ main(argc, argv, envp)
exit(0);
}
#endif /* ALLOW_UPDATES */
+#ifdef XSTATS
+ if (needToExit) {
+ ns_logstats();
+ exit(0);
+ }
+#endif /* XSTATS */
if (needreload) {
needreload = 0;
db_reload();
@@ -606,11 +649,9 @@ main(argc, argv, envp)
tp = NULL;
tmpmask = mask;
n = select(nfds, &tmpmask, (fd_set *)NULL, (fd_set *)NULL, tp);
- if (n < 0) {
- if (errno != EINTR) {
- syslog(LOG_ERR, "select: %m");
- sleep(60);
- }
+ if (n < 0 && errno != EINTR) {
+ syslog(LOG_ERR, "select: %m");
+ sleep(60);
}
if (n <= 0)
continue;
@@ -619,28 +660,32 @@ main(argc, argv, envp)
dqp != QDATAGRAM_NULL;
dqp = dqp->dq_next) {
if (FD_ISSET(dqp->dq_dfd, &tmpmask))
- for (udpcnt = 0; udpcnt < 25; udpcnt++) { /*XXX*/
+ for (udpcnt = 0; udpcnt < 42; udpcnt++) { /*XXX*/
from_len = sizeof(from_addr);
- if ((n = recvfrom(dqp->dq_dfd, buf, sizeof(buf), 0,
+ if ((n = recvfrom(dqp->dq_dfd, (char *)buf, sizeof(buf), 0,
(struct sockaddr *)&from_addr, &from_len)) < 0)
{
+#if defined(SPURIOUS_ECONNREFUSED)
+ if ((n < 0) && (errno == ECONNREFUSED))
+ break;
+#endif
if ((n < 0) && (errno == PORT_WOULDBLK))
break;
- syslog(LOG_WARNING, "recvfrom: %m");
+ syslog(LOG_INFO, "recvfrom: %m");
break;
}
if (n == 0)
break;
gettime(&tt);
dprintf(1, (ddt,
- "\ndatagram from [%s].%d, fd %d, len %d; now %s",
+ "\ndatagram from [%s].%d, fd %d, len %d; now %s",
inet_ntoa(from_addr.sin_addr),
ntohs(from_addr.sin_port),
dqp->dq_dfd, n,
- ctime(&tt.tv_sec)));
+ ctimel(tt.tv_sec)));
#ifdef DEBUG
if (debug >= 10)
- fp_query(buf, ddt);
+ fp_nquery(buf, n, ddt);
#endif
/*
* Consult database to get the answer.
@@ -684,16 +729,16 @@ main(argc, argv, envp)
continue;
}
if (rfd < 0) {
- syslog(LOG_WARNING, "accept: %m");
+ syslog(LOG_INFO, "accept: %m");
continue;
}
if ((n = fcntl(rfd, F_GETFL, 0)) < 0) {
- syslog(LOG_ERR, "fcntl(rfd, F_GETFL): %m");
+ syslog(LOG_INFO, "fcntl(rfd, F_GETFL): %m");
(void) my_close(rfd);
continue;
}
if (fcntl(rfd, F_SETFL, n|PORT_NONBLOCK) != 0) {
- syslog(LOG_ERR, "fcntl(rfd, NONBLOCK): %m");
+ syslog(LOG_INFO, "fcntl(rfd, NONBLOCK): %m");
(void) my_close(rfd);
continue;
}
@@ -701,7 +746,7 @@ main(argc, argv, envp)
len = sizeof ip_opts;
if (getsockopt(rfd, IPPROTO_IP, IP_OPTIONS,
(char *)ip_opts, &len) < 0) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"getsockopt(rfd, IP_OPTIONS): %m");
(void) my_close(rfd);
continue;
@@ -711,23 +756,31 @@ main(argc, argv, envp)
if (!haveComplained((char*)
from_addr.sin_addr.s_addr,
"rcvd ip options")) {
- syslog(LOG_NOTICE,
+ syslog(LOG_INFO,
"rcvd IP_OPTIONS from [%s].%d (ignored)",
inet_ntoa(from_addr.sin_addr),
ntohs(from_addr.sin_port));
}
if (setsockopt(rfd, IPPROTO_IP, IP_OPTIONS,
NULL, 0) < 0) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"setsockopt(!IP_OPTIONS): %m");
(void) my_close(rfd);
continue;
}
}
#endif
+ if (setsockopt(rfd, SOL_SOCKET, SO_SNDBUF,
+ (char*)&sbufsize, sizeof(sbufsize)) < 0){
+ syslog(LOG_INFO,
+ "setsockopt(rfd, SO_SNDBUF, %d): %m",
+ sbufsize);
+ (void) my_close(rfd);
+ continue;
+ }
if (setsockopt(rfd, SOL_SOCKET, SO_KEEPALIVE,
(char *)&on, sizeof(on)) < 0) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"setsockopt(rfd, KEEPALIVE): %m");
(void) my_close(rfd);
continue;
@@ -749,20 +802,21 @@ main(argc, argv, envp)
inet_ntoa(sp->s_from.sin_addr),
ntohs(sp->s_from.sin_port), rfd));
}
- if (streamq) {
- dprintf(3, (ddt, "streamq = 0x%x\n",streamq));
- }
+ if (streamq)
+ dprintf(3, (ddt, "streamq = 0x%lx\n",
+ (u_long)streamq));
for (sp = streamq; sp != QSTREAM_NULL; sp = nextsp) {
nextsp = sp->s_next;
if (!FD_ISSET(sp->s_rfd, &tmpmask))
continue;
dprintf(5, (ddt,
- "sp x%x rfd %d size %d time %d next x%x\n",
- sp, sp->s_rfd, sp->s_size,
- sp->s_time, sp->s_next));
+ "sp x%lx rfd %d size %d time %d next x%lx\n",
+ (u_long)sp, sp->s_rfd, sp->s_size,
+ sp->s_time, (u_long)sp->s_next));
dprintf(5, (ddt,
- "\tbufsize %d buf x%x bufp x%x\n",
- sp->s_bufsize, sp->s_buf, sp->s_bufp));
+ "\tbufsize %d buf x%lx bufp x%lx\n",
+ sp->s_bufsize,
+ (u_long)sp->s_buf, (u_long)sp->s_bufp));
if (sp->s_size < 0) {
size = INT16SZ
- (sp->s_bufp - (u_char *)&sp->s_tempsize);
@@ -830,7 +884,7 @@ main(argc, argv, envp)
hp = (HEADER *)sp->s_buf;
hp->qr = 1;
- hp->ra = 1;
+ hp->ra = (NoRecurse == 0);
hp->ancount = 0;
hp->qdcount = 0;
hp->nscount = 0;
@@ -877,11 +931,11 @@ getnetconf()
struct ifreq ifreq, *ifr;
struct qdatagram *dqp;
static int first = 1;
- char buf[BUFSIZ], *cp, *cplim;
+ char buf[32768], *cp, *cplim;
u_int32_t nm;
time_t my_generation = time(NULL);
- ifc.ifc_len = sizeof(buf);
+ ifc.ifc_len = sizeof buf;
ifc.ifc_buf = buf;
if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) {
syslog(LOG_ERR, "get interface configuration: %m - exiting");
@@ -894,7 +948,7 @@ getnetconf()
#else
#define my_size(p) (sizeof (p))
#endif
- cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
+ cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */
for (cp = buf;
cp < cplim;
cp += sizeof (ifr->ifr_name) + my_size(ifr->ifr_addr)) {
@@ -912,7 +966,7 @@ getnetconf()
*/
#if !defined(BSD) || (BSD < 199103)
if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "get interface addr: %m");
+ syslog(LOG_NOTICE, "get interface addr: %m");
continue;
}
#endif
@@ -975,7 +1029,7 @@ getnetconf()
&ifreq.ifr_addr)->sin_addr;
#ifdef SIOCGIFNETMASK
if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "get netmask: %m");
+ syslog(LOG_NOTICE, "get netmask: %m");
ntp->mask = net_mask(ntp->my_addr);
} else
ntp->mask = ((struct sockaddr_in *)
@@ -985,7 +1039,7 @@ getnetconf()
ntp->mask = net_mask(ntp->my_addr);
#endif
if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "get interface flags: %m");
+ syslog(LOG_NOTICE, "get interface flags: %m");
continue;
}
#ifdef IFF_LOOPBACK
@@ -1005,7 +1059,7 @@ getnetconf()
continue;
} else if ((ifreq.ifr_flags & IFF_POINTOPOINT)) {
if (ioctl(vs, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
- syslog(LOG_ERR, "get dst addr: %m");
+ syslog(LOG_NOTICE, "get dst addr: %m");
continue;
}
ntp->mask = 0xffffffff;
@@ -1037,7 +1091,7 @@ getnetconf()
*
* XXX - need to update enettab/elocal as well.
*/
- dqflush(my_generation);
+ dqflush(my_generation); /* With apologies to The Who. */
/*
* Create separate qdatagram structure for socket
@@ -1107,9 +1161,10 @@ printnetinfo(ntp)
register struct netinfo *ntp;
{
for ( ; ntp != NULL; ntp = ntp->next) {
- fprintf(ddt,"addr x%lx mask x%lx", ntp->addr, ntp->mask);
- fprintf(ddt," my_addr x%lx", ntp->my_addr.s_addr);
- fprintf(ddt," %s\n", inet_ntoa(ntp->my_addr));
+ fprintf(ddt, "addr x%lx mask x%lx",
+ (u_long)ntp->addr, (u_long)ntp->mask);
+ fprintf(ddt, " my_addr x%lx", ntp->my_addr.s_addr);
+ fprintf(ddt, " %s\n", inet_ntoa(ntp->my_addr));
}
}
#endif
@@ -1133,12 +1188,12 @@ opensocket(dqp)
if (setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_REUSEADDR,
(char *)&on, sizeof(on)) != 0)
{
- syslog(LOG_ERR, "setsockopt(dqp->dq_dfd, reuseaddr): %m");
+ syslog(LOG_NOTICE, "setsockopt(dqp->dq_dfd, reuseaddr): %m");
/* XXX press on regardless, this is not too serious. */
}
#ifdef SO_RCVBUF
m = sizeof(n);
- if ((getsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF, &n, &m) >= 0)
+ if ((getsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF, (char*)&n, &m) >= 0)
&& (m == sizeof(n))
&& (n < rbufsize)) {
(void) setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF,
@@ -1146,10 +1201,10 @@ opensocket(dqp)
}
#endif /* SO_RCVBUF */
if ((n = fcntl(dqp->dq_dfd, F_GETFL, 0)) < 0) {
- syslog(LOG_ERR, "fcntl(dfd, F_GETFL): %m");
+ syslog(LOG_NOTICE, "fcntl(dfd, F_GETFL): %m");
/* XXX press on regardless, but this really is a problem. */
} else if (fcntl(dqp->dq_dfd, F_SETFL, n|PORT_NONBLOCK) != 0) {
- syslog(LOG_ERR, "fcntl(dqp->dq_dfd, non-blocking): %m");
+ syslog(LOG_NOTICE, "fcntl(dqp->dq_dfd, non-blocking): %m");
/* XXX press on regardless, but this really is a problem. */
}
/*
@@ -1160,10 +1215,11 @@ opensocket(dqp)
*/
nsaddr.sin_addr = dqp->dq_addr;
if (bind(dqp->dq_dfd, (struct sockaddr *)&nsaddr, sizeof(nsaddr))) {
- syslog(LOG_ERR, "bind(dfd=%d, [%s].%d): %m - exiting",
+ syslog(LOG_NOTICE, "bind(dfd=%d, [%s].%d): %m",
dqp->dq_dfd, inet_ntoa(nsaddr.sin_addr),
ntohs(nsaddr.sin_port));
#if !defined(sun)
+ syslog(LOG_ERR, "exiting");
exit(1);
#endif
}
@@ -1180,7 +1236,7 @@ onhup()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGHUP, onhup);
+ (void)signal(SIGHUP, (SIG_FN (*)())onhup);
#endif /* SYSV */
needreload = 1;
errno = save_errno;
@@ -1197,7 +1253,7 @@ maint_alarm()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGALRM, maint_alarm);
+ (void)signal(SIGALRM, (SIG_FN (*)())maint_alarm);
#endif /* SYSV */
needmaint = 1;
errno = save_errno;
@@ -1216,6 +1272,17 @@ onintr()
}
#endif /* ALLOW_UPDATES */
+#ifdef XSTATS
+/*
+ * Signal handler to write log information
+ */
+static SIG_FN
+onintr()
+{
+ needToExit = 1;
+}
+#endif /* XSTATS */
+
/*
* Signal handler to schedule a data base dump. Do this instead of dumping the
* data base immediately, to avoid seeing it in a possibly inconsistent state
@@ -1227,7 +1294,7 @@ setdumpflg()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGINT, setdumpflg);
+ (void)signal(SIGINT, (SIG_FN (*)())setdumpflg);
#endif /* SYSV */
needToDoadump = 1;
errno = save_errno;
@@ -1251,17 +1318,17 @@ setdebug(code)
ddt = freopen(debugfile, "w+", stderr);
if ( ddt == NULL) {
- syslog(LOG_WARNING, "can't open debug file %s: %m",
- debugfile);
+ syslog(LOG_NOTICE, "can't open debug file %s: %m",
+ debugfile);
debug = 0;
} else {
-#if defined(SYSV)
+#if defined(HAVE_SETVBUF)
setvbuf(ddt, NULL, _IOLBF, BUFSIZ);
#else
setlinebuf(ddt);
#endif
if ((n = fcntl(fileno(ddt), F_GETFL, 0)) < 0) {
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"fcntl(ddt, F_GETFL): %m");
} else {
(void) fcntl(fileno(ddt), F_SETFL, n|O_APPEND);
@@ -1286,7 +1353,7 @@ setIncrDbgFlg()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGUSR1, setIncrDbgFlg);
+ (void)signal(SIGUSR1, (SIG_FN (*)())setIncrDbgFlg);
#endif /* SYSV */
#ifdef DEBUG
if (debug == 0) {
@@ -1310,7 +1377,7 @@ setNoDbgFlg()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGUSR2, setNoDbgFlg);
+ (void)signal(SIGUSR2, (SIG_FN (*)())setNoDbgFlg);
#endif /* SYSV */
setdebug(0);
errno = save_errno;
@@ -1325,7 +1392,7 @@ setQrylogFlg()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGWINCH, setQrylogFlg);
+ (void)signal(SIGWINCH, (SIG_FN (*)())setQrylogFlg);
#endif /* SYSV */
qrylog = !qrylog;
syslog(LOG_NOTICE, "query log %s\n", qrylog ?"on" :"off");
@@ -1341,7 +1408,7 @@ setstatsflg()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGIOT, setstatsflg);
+ (void)signal(SIGIOT, (SIG_FN (*)())setstatsflg);
#endif /* SYSV */
needStatsDump = 1;
errno = save_errno;
@@ -1352,7 +1419,7 @@ setchkptflg()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGQUIT, setchkptflg);
+ (void)signal(SIGQUIT, (SIG_FN (*)())setchkptflg);
#endif /* SYSV */
needToChkpt = 1;
errno = save_errno;
@@ -1371,7 +1438,7 @@ sigprof()
{
int save_errno = errno;
#if defined(SYSV)
- (void)signal(SIGSYS, sigprof);
+ (void)signal(SIGSYS, (SIG_FN (*)())sigprof);
#endif /* SYSV */
dprintf(1, (ddt, "sigprof()\n"));
if (fork() == 0)
@@ -1396,7 +1463,7 @@ sqadd()
syslog(LOG_ERR, "sqadd: calloc: %m");
return (QSTREAM_NULL);
}
- dprintf(3, (ddt, "sqadd(x%x)\n", sqp));
+ dprintf(3, (ddt, "sqadd(x%lx)\n", (u_long)sqp));
sqp->s_next = streamq;
streamq = sqp;
@@ -1415,8 +1482,8 @@ sqrm(qp)
{
register struct qstream *qsp;
- dprintf(2, (ddt, "sqrm(%#x, %d ) rfcnt=%d\n",
- qp, qp->s_rfd, qp->s_refcnt));
+ dprintf(2, (ddt, "sqrm(%#lx, %d) rfcnt=%d\n",
+ (u_long)qp, qp->s_rfd, qp->s_refcnt));
if (qp->s_bufsize != 0)
free(qp->s_buf);
@@ -1480,7 +1547,7 @@ dqflush(gen)
if (dqp->dq_addr.s_addr == INADDR_ANY ||
dqp->dq_gen == gen)
continue;
- syslog(LOG_CRIT, "interface [%s] missing; deleting",
+ syslog(LOG_NOTICE, "interface [%s] missing; deleting",
inet_ntoa(dqp->dq_addr));
}
if (pqp != NULL)
@@ -1573,6 +1640,30 @@ net_mask(in)
return (htonl(IN_CLASSC_NET));
}
+/*
+ * These are here in case we ever want to get more clever, like perhaps
+ * using a bitmap to keep track of outstanding queries and a random
+ * allocation scheme to make it a little harder to predict them. Note
+ * that the resolver will need the same protection so the cleverness
+ * should be put there rather than here; this is just an interface layer.
+ */
+
+void
+nsid_init()
+{
+ nsid_state = res_randomid();
+}
+
+u_int16_t
+nsid_next()
+{
+ if (nsid_state == 65535)
+ nsid_state = 0;
+ else
+ nsid_state++;
+ return (nsid_state);
+}
+
#if defined(BSD43_BSD43_NFS)
/* junk needed for old Sun NFS licensees */
#undef dn_skipname
diff --git a/usr.sbin/named/ns_maint.c b/usr.sbin/named/ns_maint.c
index 12904e3f1017e..03cbf99aaa01a 100644
--- a/usr.sbin/named/ns_maint.c
+++ b/usr.sbin/named/ns_maint.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_maint.c 4.39 (Berkeley) 3/2/91";
-static char rcsid[] = "$Id: ns_maint.c,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $";
+static char rcsid[] = "$Id: ns_maint.c,v 1.2 1995/05/30 03:48:53 rgrimes Exp $";
#endif /* not lint */
/*
@@ -86,7 +86,6 @@ static int xfers_running, /* # of xfers running */
static void startxfer __P((struct zoneinfo *)),
abortxfer __P((struct zoneinfo *)),
addxfer __P((struct zoneinfo *)),
- qserial_query __P((struct zoneinfo *)),
tryxfer __P((void));
#define qserial_qfull() (qserials_running == MAXQSERIAL)
@@ -94,6 +93,9 @@ static void startxfer __P((struct zoneinfo *)),
#ifdef CLEANCACHE
static time_t cache_time;
#endif
+#ifdef XSTATS
+static time_t stats_time;
+#endif
/*
* Invoked at regular intervals by signal interrupt; refresh all secondary
* zones from primary name server and remove old cache entries. Also,
@@ -108,7 +110,7 @@ ns_maint()
gettime(&tt);
- dprintf(1, (ddt, "\nns_maint(); now %s", ctime(&tt.tv_sec)));
+ dprintf(1, (ddt, "\nns_maint(); now %s", ctimel(tt.tv_sec)));
alarm_pending = 0;
for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) {
@@ -121,21 +123,27 @@ ns_maint()
case Z_CACHE:
doachkpt();
- zp->z_time = tt.tv_sec + zp->z_refresh;
+ ns_refreshtime(zp, tt.tv_sec);
break;
case Z_SECONDARY:
#ifdef STUBS
case Z_STUB:
#endif
+ if (zp->z_serial != 0 &&
+ ((zp->z_lastupdate + zp->z_expire) <
+ tt.tv_sec)
+ ) {
+ zp->z_serial = 0;
+ }
if (zp->z_flags &
(Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL)) {
- zp->z_time = tt.tv_sec + zp->z_refresh;
+ ns_refreshtime(zp, tt.tv_sec);
break;
}
if (zp->z_flags & Z_XFER_RUNNING) {
abortxfer(zp);
- zp->z_time = tt.tv_sec + zp->z_retry;
+ ns_retrytime(zp, tt.tv_sec);
break;
}
qserial_query(zp);
@@ -148,7 +156,7 @@ ns_maint()
*/
if (zp->z_flags & Z_CHANGED) {
zonedump(zp);
- zp->z_time = tt.tv_sec + zp->z_refresh;
+ ns_refreshtime(zp, tt.tv_sec);
}
break;
#endif /* ALLOW_UPDATES */
@@ -156,8 +164,19 @@ ns_maint()
gettime(&tt);
}
}
-#ifdef CLEANCACHE
- remove_zone(hashtab, 0, 0);
+#ifdef CLEANCACHE
+ if ((cache_time + cache_interval) <= tt.tv_sec) {
+ if (cache_time)
+ remove_zone(hashtab, 0, 0);
+ cache_time = tt.tv_sec;
+ }
+#endif
+#ifdef XSTATS
+ if (stats_time + stats_interval <= tt.tv_sec) {
+ if (stats_time)
+ ns_logstats();
+ stats_time = tt.tv_sec;
+ }
#endif
if (!needmaint)
sched_maint();
@@ -174,7 +193,7 @@ sched_maint()
register struct zoneinfo *zp;
struct itimerval ival;
#ifdef CLEANCACHE
- time_t next_refresh = cache_time + 3600;
+ time_t next_refresh = cache_time + cache_interval;
#else
time_t next_refresh = 0;
#endif
@@ -207,8 +226,8 @@ sched_maint()
alarm_pending = 1;
}
(void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);
- dprintf(1, (ddt, "sched_maint: Next interrupt in %d sec\n",
- ival.it_value.tv_sec));
+ dprintf(1, (ddt, "sched_maint: Next interrupt in %lu sec\n",
+ (u_long)ival.it_value.tv_sec));
}
/*
@@ -223,7 +242,7 @@ markUpToDate(zp)
zp->z_flags &= ~Z_SYSLOGGED;
zp->z_lastupdate = tt.tv_sec;
- zp->z_time = tt.tv_sec + zp->z_refresh;
+ ns_refreshtime(zp, tt.tv_sec);
/*
* Restore Z_AUTH in case expired,
* but only if there were no errors
@@ -258,7 +277,7 @@ markUpToDate(zp)
* Query for the serial number of a zone, so that
* we can check to see if we need to transfer it.
*/
-static void
+void
qserial_query(zp)
struct zoneinfo *zp;
{
@@ -270,15 +289,16 @@ qserial_query(zp)
return;
qp = sysquery(zp->z_origin, zp->z_class, T_SOA,
- zp->z_addr, zp->z_addrcnt);
+ zp->z_addr, zp->z_addrcnt, QUERY);
if (!qp) {
- dprintf(1, (ddt, "qserial_query(%s) FAILED\n", zp->z_origin));
+ syslog(LOG_INFO, "qserial_query(%s): sysquery FAILED",
+ zp->z_origin);
return; /* XXX - this is bad, we should do something */
}
qp->q_flags |= Q_ZSERIAL;
qp->q_zquery = zp;
zp->z_flags |= Z_QSERIAL;
- zp->z_time = tt.tv_sec + zp->z_refresh;
+ ns_refreshtime(zp, tt.tv_sec);
qserials_running++;
dprintf(1, (ddt, "qserial_query(%s) QUEUED\n", zp->z_origin));
}
@@ -291,7 +311,8 @@ qserial_answer(qp, serial)
struct zoneinfo *zp = qp->q_zquery;
int was_qfull = qserial_qfull();
- dprintf(1, (ddt, "qserial_answer(%s, %lu)\n", zp->z_origin, serial));
+ dprintf(1, (ddt, "qserial_answer(%s, %lu)\n",
+ zp->z_origin, (u_long)serial));
zp->z_flags &= ~Z_QSERIAL;
qp->q_flags &= ~Q_ZSERIAL; /* keeps us from being called twice */
qserials_running--;
@@ -319,7 +340,6 @@ qserial_answer(qp, serial)
dprintf(1, (ddt, "qserial_answer: zone serial is still OK\n"));
markUpToDate(zp);
}
- done:
if (was_qfull)
needmaint = 1;
}
@@ -351,7 +371,7 @@ startxfer(zp)
argv[argc++] = "-f";
argv[argc++] = zp->z_source;
argv[argc++] = "-s";
- sprintf(serial_str, "%lu", zp->z_serial);
+ sprintf(serial_str, "%lu", (u_long)zp->z_serial);
argv[argc++] = serial_str;
#ifdef GEN_AXFR
argv[argc++] = "-C";
@@ -397,7 +417,7 @@ startxfer(zp)
if (aIsUs(a)
&& !haveComplained(zp->z_origin,
(char*)startxfer)) {
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"attempted to fetch zone %s from self (%s)",
zp->z_origin, inet_ntoa(a));
continue;
@@ -419,10 +439,8 @@ startxfer(zp)
#endif /* ECHOARGS */
#endif /* DEBUG */
-#ifdef SYSV
-#define vfork fork
-#else
gettime(&tt);
+#ifndef SYSV
omask = sigblock(sigmask(SIGCHLD));
#endif
if ((pid = vfork()) == -1) {
@@ -452,6 +470,25 @@ startxfer(zp)
#endif
}
+const char *
+zoneTypeString(zp)
+ const struct zoneinfo *zp;
+{
+ static char ret[sizeof "(4294967296?)"]; /* 2^32 */
+
+ switch (zp->z_type) {
+ case Z_PRIMARY: return ("primary");
+ case Z_SECONDARY: return ("secondary");
+#ifdef STUBS
+ case Z_STUB: return ("stub");
+#endif
+ case Z_CACHE: return ("cache");
+ default:
+ sprintf(ret, "(%lu?)", (u_long)zp->z_type);
+ return (ret);
+ }
+}
+
#ifdef DEBUG
void
printzoneinfo(zonenum)
@@ -459,7 +496,6 @@ int zonenum;
{
struct timeval tt;
struct zoneinfo *zp = &zones[zonenum];
- char *ZoneType;
if (!debug)
return;
@@ -467,25 +503,6 @@ int zonenum;
fprintf(ddt, "printzoneinfo(%d):\n", zonenum);
gettime(&tt);
- switch (zp->z_type) {
- case Z_PRIMARY:
- ZoneType = "Primary";
- break;
- case Z_SECONDARY:
- ZoneType = "Secondary";
- break;
-#ifdef STUBS
- case Z_STUB:
- ZoneType = "Stub";
- break;
-#endif
- case Z_CACHE:
- ZoneType = "Cache";
- break;
- default:
- ZoneType = "Unknown";
- break;
- }
if (zp->z_origin != NULL && (zp->z_origin[0] == '\0'))
fprintf(ddt, "origin ='.'");
else
@@ -493,20 +510,21 @@ int zonenum;
#ifdef GEN_AXFR
fprintf(ddt, ", class = %d", zp->z_class);
#endif
- fprintf(ddt, ", type = %s", ZoneType);
+ fprintf(ddt, ", type = %s", zoneTypeString(zp));
if (zp->z_source)
fprintf(ddt,", source = %s\n", zp->z_source);
- fprintf(ddt, "z_refresh = %ld", zp->z_refresh);
- fprintf(ddt, ", retry = %ld", zp->z_retry);
- fprintf(ddt, ", expire = %ld", zp->z_expire);
- fprintf(ddt, ", minimum = %ld", zp->z_minimum);
- fprintf(ddt, ", serial = %lu\n", zp->z_serial);
- fprintf(ddt, "z_time = %d", zp->z_time);
+ fprintf(ddt, "z_refresh = %lu", (u_long)zp->z_refresh);
+ fprintf(ddt, ", retry = %lu", (u_long)zp->z_retry);
+ fprintf(ddt, ", expire = %lu", (u_long)zp->z_expire);
+ fprintf(ddt, ", minimum = %lu", (u_long)zp->z_minimum);
+ fprintf(ddt, ", serial = %lu\n", (u_long)zp->z_serial);
+ fprintf(ddt, "z_time = %lu", (u_long)zp->z_time);
if (zp->z_time) {
- fprintf(ddt, ", now time : %d sec", tt.tv_sec);
- fprintf(ddt, ", time left: %d sec", zp->z_time - tt.tv_sec);
+ fprintf(ddt, ", now time : %lu sec", (u_long)tt.tv_sec);
+ fprintf(ddt, ", time left: %lu sec",
+ (int)(zp->z_time - tt.tv_sec));
}
- fprintf(ddt, "; flags %x\n", zp->z_flags);
+ fprintf(ddt, "; flags %lx\n", (u_long)zp->z_flags);
}
#endif /* DEBUG */
@@ -571,6 +589,146 @@ remove_zone(htp, zone)
}
}
+#ifdef PURGE_ZONE
+static void purge_z_2();
+static bottom_of_zone();
+
+void
+purge_zone(dname, htp, class)
+ const char *dname;
+ register struct hashbuf *htp;
+ int class;
+{
+ const char *fname;
+ struct databuf *dp, *pdp;
+ struct namebuf *np;
+ struct hashbuf *phtp = htp;
+
+ dprintf(1, (ddt, "purge_zone(%s,%d)\n", dname, class));
+ if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname) {
+ for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
+ if (dp->d_class == class)
+ dp = rm_datum(dp, np, pdp);
+ else {
+ pdp = dp;
+ dp = dp->d_next;
+ }
+ }
+
+ if (np->n_hash) {
+
+ purge_z_2(np->n_hash, class);
+
+ if (np->n_hash->h_cnt == 0) {
+ free((char*)np->n_hash);
+ np->n_hash = NULL;
+ }
+ }
+
+ /* remove entry from cache, if required */
+ if ((np->n_hash == NULL) && (np->n_data == NULL)) {
+ struct namebuf **npp, **nppend;
+ struct namebuf *npn, *pnp, *nnp;
+
+ dprintf(3,(ddt, "purge_zone: cleaning cache\n"));
+
+ /* walk parent hashtable looking for ourself */
+ if (np->n_parent)
+ phtp = np->n_parent->n_hash;
+ else
+ phtp = htp; /* top / root zone */
+
+ if (phtp) {
+ nppend = phtp->h_tab + phtp->h_size;
+
+ for (npp = phtp->h_tab; npp < nppend; npp++) {
+ for (pnp = NULL, nnp = *npp;
+ nnp != NULL;
+ nnp = npn
+ ) {
+ if (nnp == np) {
+ dprintf(3,(ddt, "purge_zone: found our selves\n"));
+ npn = rm_name(nnp, npp, pnp);
+ phtp->h_cnt--;
+ } else {
+ npn = nnp->n_next;
+ pnp = nnp;
+ }
+ }
+ }
+ }
+
+ }
+ }
+}
+
+static void
+purge_z_2(htp, class)
+ register struct hashbuf *htp;
+ register int class;
+{
+ register struct databuf *dp, *pdp;
+ register struct namebuf *np, *pnp, *npn;
+ struct namebuf **npp, **nppend;
+
+ nppend = htp->h_tab + htp->h_size;
+ for (npp = htp->h_tab; npp < nppend; npp++)
+ for (pnp = NULL, np = *npp; np != NULL; np = npn) {
+ if (!bottom_of_zone(np->n_data, class)) {
+ for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
+ if (dp->d_class == class)
+ dp = rm_datum(dp, np, pdp);
+ else {
+ pdp = dp;
+ dp = dp->d_next;
+ }
+ }
+
+ if (np->n_hash) {
+ /* call recursively to remove subdomains. */
+ purge_z_2(np->n_hash, class);
+
+ /* if now empty, free it */
+ if (np->n_hash->h_cnt == 0) {
+ free((char*)np->n_hash);
+ np->n_hash = NULL;
+ }
+ }
+
+ }
+
+ if ((np->n_hash == NULL) && (np->n_data == NULL)) {
+ npn = rm_name(np, npp, pnp);
+ htp->h_cnt--;
+ } else {
+ npn = np->n_next;
+ pnp = np;
+ }
+ }
+}
+
+static int
+bottom_of_zone(dp, class)
+ struct databuf *dp;
+ int class;
+{
+ for ( ; dp ; dp = dp->d_next) {
+ if (dp->d_class != class)
+ continue;
+ if (dp->d_zone == 0)
+ continue;
+#ifdef NCACHE
+ if (dp->d_rcode) /* this should not occur */
+ continue;
+#endif
+ if (dp->d_type == T_SOA)
+ return (1);
+ }
+ dprintf(3, (ddt, "bottom_of_zone() == 0\n"));
+ return (0);
+}
+#endif
+
/*
* Handle XFER limit for a nameserver.
*/
@@ -611,7 +769,7 @@ abortxfer(zp)
kill(zp->z_xferpid, SIGKILL);
syslog(LOG_NOTICE, "zone transfer timeout for \"%s\"; pid %lu killed",
zp->z_origin, (u_long)zp->z_xferpid);
- zp->z_time = tt.tv_sec + zp->z_retry;
+ ns_retrytime(zp, tt.tv_sec);
(void) nxfers(zp, -1);
xfers_running--;
}
@@ -662,7 +820,7 @@ endxfer()
"named-xfer exited with signal %d\n",
WTERMSIG(status));
}
- zp->z_time = tt.tv_sec + zp->z_retry;
+ ns_retrytime(zp, tt.tv_sec);
} else {
switch (exitstatus) {
case XFER_UPTODATE:
@@ -676,29 +834,26 @@ endxfer()
break;
case XFER_TIMEOUT:
- dprintf(1, (ddt,
- "zoneref: Masters for secondary zone %s unreachable\n",
- zp->z_origin));
if (!(zp->z_flags & Z_SYSLOGGED)) {
zp->z_flags |= Z_SYSLOGGED;
syslog(LOG_NOTICE,
- "zoneref: Masters for secondary zone %s unreachable",
+ "zoneref: Masters for secondary zone \"%s\" unreachable",
zp->z_origin);
}
- zp->z_time = tt.tv_sec + zp->z_retry;
+ ns_retrytime(zp, tt.tv_sec);
break;
default:
if (!(zp->z_flags & Z_SYSLOGGED)) {
zp->z_flags |= Z_SYSLOGGED;
syslog(LOG_NOTICE,
- "named-xfer for %s exited %d",
+ "named-xfer for \"%s\" exited %d",
zp->z_origin, exitstatus);
}
/* FALLTHROUGH */
case XFER_FAIL:
zp->z_flags |= Z_SYSLOGGED;
- zp->z_time = tt.tv_sec + zp->z_retry;
+ ns_retrytime(zp, tt.tv_sec);
break;
} /*switch*/
break;
@@ -707,32 +862,73 @@ endxfer()
} /*while*/
tryxfer();
#if defined(SYSV)
- (void)signal(SIGCLD, endxfer);
+ (void)signal(SIGCLD, (SIG_FN (*)()) endxfer);
#endif
errno = save_errno;
}
/*
- * Try to start some xfers
+ * Try to start some xfers - new "fair scheduler" by Bob Heiney @DEC (1995)
*/
static void
tryxfer() {
- struct zoneinfo *zp;
+ static struct zoneinfo *zp = NULL;
+ static struct zoneinfo *lastzones = NULL;
+ static int lastnzones = 0;
+ struct zoneinfo *startzp, *stopzp;
- for (zp = zones; zp < &zones[nzones]; zp++) {
+ /* initialize, and watch out for changes in zones! */
+ if (lastzones != zones) {
+ if (lastzones != NULL)
+ syslog(LOG_INFO, "zones changed: %p != %p",
+ lastzones, zones);
+ lastzones = zones;
+ zp = zones;
+ }
+
+ /* did zones shrink? */
+ if (lastnzones > nzones) {
+ syslog(LOG_INFO, "zones shrunk");
+ zp = zones;
+ }
+ lastnzones = nzones;
+
+ if (zp == zones)
+ stopzp = &zones[nzones-1];
+ else
+ stopzp = zp - 1;
+
+ dprintf(3, (ddt, "tryxfer start zp=%p stopzp=%p def=%d running=%d\n",
+ zp, stopzp, xfers_deferred, xfers_running));
+
+ startzp = zp;
+ for (;;) {
int xfers;
if (!xfers_deferred || xfers_running >= max_xfers_running)
break;
if ((xfers = nxfers(zp, 0)) != -1 &&
- xfers < MAX_XFERS_PERNS &&
+ xfers < max_xfers_per_ns &&
(zp->z_flags & Z_NEED_XFER)) {
nxfers(zp, 1);
xfers_deferred--;
startxfer(zp);
}
+
+ if (zp == stopzp) {
+ dprintf(3, (ddt, "tryxfer stop mark\n"));
+ zp = startzp;
+ break;
+ }
+
+ zp++;
+ /* wrap around? */
+ if (zp == &zones[nzones])
+ zp = zones;
}
+ dprintf(3, (ddt, "tryxfer stop zp=%p\n", zp));
+
if (!needmaint)
sched_maint();
}
@@ -756,13 +952,13 @@ loadxfer()
#else
remove_zone(hashtab, zp - zones);
#endif
- if (db_load(zp->z_source, zp->z_origin, zp, 0) == 0)
+#ifdef PURGE_ZONE
+ purge_zone(zp->z_origin, hashtab, zp->z_class);
+#endif
+ if (!db_load(zp->z_source, zp->z_origin, zp, NULL))
zp->z_flags |= Z_AUTH;
if (zp->z_flags & Z_TMP_FILE)
(void) unlink(zp->z_source);
- syslog(LOG_INFO,
- "Zone \"%s\" (class %d) xfer'd and loaded (serial %lu)",
- zp->z_origin, zp->z_class, zp->z_serial);
}
}
if (!needmaint)
diff --git a/usr.sbin/named/ns_ncache.c b/usr.sbin/named/ns_ncache.c
index f6d1ea3d247c4..367ff8730d58c 100644
--- a/usr.sbin/named/ns_ncache.c
+++ b/usr.sbin/named/ns_ncache.c
@@ -144,8 +144,9 @@ cache_n_resp(msg, msglen)
return;
}
dprintf(4, (ddt,
- "ncache succeeded: d:%s, t:%d, c:%d rcode:%d ttl:%d\n",
- dname,type,class,dp->d_rcode, dp->d_ttl-tt.tv_sec));
+ "ncache succeeded: [%s %s %s] rcode:%d ttl:%l\n",
+ dname, p_type(type), p_class(class),
+ dp->d_rcode, (long)(dp->d_ttl-tt.tv_sec)));
return;
}
diff --git a/usr.sbin/named/ns_req.c b/usr.sbin/named/ns_req.c
index 81b2e7f7e7fee..94d765ba83c2e 100644
--- a/usr.sbin/named/ns_req.c
+++ b/usr.sbin/named/ns_req.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_req.c 4.47 (Berkeley) 7/1/91";
-static char rcsid[] = "$Id: ns_req.c,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $";
+static char rcsid[] = "$Id: ns_req.c,v 1.2 1995/05/30 03:48:55 rgrimes Exp $";
#endif /* not lint */
/*
@@ -74,8 +74,10 @@ static char rcsid[] = "$Id: ns_req.c,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $";
#include "named.h"
struct addinfo {
- char *a_dname; /* domain name */
- u_int a_class; /* class for address */
+ char *a_dname; /* domain name */
+ char *a_rname; /* referred by */
+ u_int16_t a_rtype; /* referred by */
+ u_int16_t a_class; /* class for address */
};
enum req_action { Finish, Refuse, Return };
@@ -86,18 +88,23 @@ static enum req_action req_query __P((HEADER *hp, u_char **cpp, u_char *eom,
u_char *msg, int dfd,
struct sockaddr_in *from));
-#ifdef INVQ
static enum req_action req_iquery __P((HEADER *hp, u_char **cpp, u_char *eom,
int *buflenp, u_char *msg,
struct sockaddr_in *from));
+
+#ifdef BIND_NOTIFY
+static enum req_action req_notify __P((HEADER *hp, u_char **cpp, u_char *eom,
+ u_char *msg,struct sockaddr_in *from));
#endif
static void fwritemsg __P((FILE *, u_char *, int)),
+#ifdef DEBUG
+ printSOAdata __P((struct databuf)),
+#endif
doaxfr __P((struct namebuf *, FILE *,
struct namebuf *, int)),
startxfr __P((struct qstream *, struct namebuf *,
- u_char *, int, int, const char *)),
- printSOAdata __P((struct databuf));
+ u_char *, int, int, const char *));
#ifdef ALLOW_UPDATES
static int InitDynUpdate __P((register HEADER *hp,
@@ -110,7 +117,8 @@ static int InitDynUpdate __P((register HEADER *hp,
#endif
static struct addinfo addinfo[NADDRECS];
-static void addname __P((char *, u_int16_t));
+static void addname __P((const char *, const char *,
+ u_int16_t, u_int16_t));
/*
* Process request using database; assemble and send response.
@@ -126,12 +134,12 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
register HEADER *hp = (HEADER *) msg;
u_char *cp, *eom;
enum req_action action;
+ int n;
#ifdef DEBUG
if (debug > 3) {
- fprintf(ddt, "ns_req(from=[%s].%d)\n",
- inet_ntoa(from->sin_addr), ntohs(from->sin_port));
- fp_query(msg, ddt);
+ fprintf(ddt, "ns_req(from=%s)\n", sin_ntoa(from));
+ fp_nquery(msg, msglen, ddt);
}
#endif
@@ -148,19 +156,17 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
return;
}
- /* its a query and these bits have no business
+ /* it's not a response so these bits have no business
* being set. will later simplify work if we can
* safely assume these are always 0 when a query
- * comes in
+ * comes in.
*/
hp->aa = hp->ra = 0;
hp->rcode = NOERROR;
cp = msg + HFIXEDSZ;
eom = msg + msglen;
-
- dnptrs[0] = msg;
- dnptrs[1] = NULL;
+ buflen -= HFIXEDSZ;
free_addinfo(); /* sets addcount to zero */
dnptrs[0] = NULL;
@@ -172,10 +178,14 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
msg, dfd, from);
break;
-#ifdef INVQ
case IQUERY:
action = req_iquery(hp, &cp, eom, &buflen, msg, from);
break;
+
+#ifdef BIND_NOTIFY
+ case NS_NOTIFY_OP:
+ action = req_notify(hp, &cp, eom, msg, from);
+ break;
#endif
#ifdef ALLOW_UPDATES
@@ -188,14 +198,14 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
* here is that none of the other return codes equals this one (a good
* assumption, since they only occupy 4 bits over-the-wire)
*/
- /* Call InitDynUpdate for all dynamic update requests */
- case UPDATEM:
- case UPDATEMA:
- case UPDATED:
- case UPDATEDA:
- case UPDATEA:
- n = InitDynUpdate(hp, msg, msglen, cp, from, qsp, dfd);
- if (n == FORWARDED) {
+ /* Call InitDynUpdate for all dynamic update requests */
+ case UPDATEM:
+ case UPDATEMA:
+ case UPDATED:
+ case UPDATEDA:
+ case UPDATEA:
+ n = InitDynUpdate(hp, msg, msglen, cp, from, qsp, dfd);
+ if (n == FORWARDED) {
/* Return directly because InitDynUpdate
* forwarded the query to the primary, so we
* will send response later
@@ -207,11 +217,11 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
*/
action = Finish;
}
-#endif /* ALLOW_UPDATES */
case ZONEREF:
dprintf(1, (ddt, "Refresh Zone\n"));
/*FALLTHROUGH*/
+#endif /* ALLOW_UPDATES */
default:
dprintf(1, (ddt, "ns_req: Opcode %d not implemented\n",
@@ -238,48 +248,47 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
/* rest of the function handles this case */
break;
default:
- syslog(LOG_CRIT, "bad action variable in ns_req() -- %d",
- (int) action);
- return; /* XXX - should really exit here */
+ panic(-1, "ns_req: bad action variable");
+ /*NOTREACHED*/
}
/*
* apply final polish
*/
hp->qr = 1; /* set Response flag */
- if (NoRecurse)
- hp->ra = 0; /* No recursion; maybe we're a root server */
- else
- hp->ra = 1; /* Recursion is Available */
+ hp->ra = (NoRecurse == 0);
hp->ancount = htons(hp->ancount);
- if (addcount) {
- int n = doaddinfo(hp, cp, buflen);
- cp += n;
- buflen -= n;
- }
- dprintf(1, (ddt, "ns_req: answer -> [%s].%d fd=%d id=%d %s\n",
- inet_ntoa(from->sin_addr),
- ntohs(from->sin_port),
+ n = doaddinfo(hp, cp, buflen);
+ cp += n;
+ buflen -= n;
+
+ dprintf(1, (ddt, "ns_req: answer -> %s fd=%d id=%d size=%d %s\n",
+ sin_ntoa(from),
(qsp == QSTREAM_NULL) ?dfd :qsp->s_rfd,
- ntohs(hp->id), local(from) == NULL ? "Remote" : "Local"));
+ ntohs(hp->id), cp - msg, local(from) == NULL ? "Remote" : "Local"));
#ifdef DEBUG
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, cp - msg, ddt);
#endif
if (qsp == QSTREAM_NULL) {
- if (sendto(dfd, msg, cp - msg, 0,
+ if (sendto(dfd, (char*)msg, cp - msg, 0,
(struct sockaddr *)from,
sizeof(*from)) < 0) {
if (!haveComplained((char*)from->sin_addr.s_addr,
sendtoStr))
- syslog(LOG_NOTICE,
- "ns_req: sendto([%s].%d): %m",
- inet_ntoa(from->sin_addr),
- ntohs(from->sin_port));
+ syslog(LOG_INFO,
+ "ns_req: sendto(%s): %m",
+ sin_ntoa(from));
nameserIncr(from->sin_addr, nssSendtoErr);
}
nameserIncr(from->sin_addr, nssSentAns);
+#ifdef XSTATS
+ if (hp->rcode == NXDOMAIN)
+ nameserIncr(from->sin_addr, nssSentNXD);
+ if (!hp->aa)
+ nameserIncr(from->sin_addr, nssSentNaAns);
+#endif
} else {
(void) writemsg(qsp->s_rfd, msg, cp - msg);
sq_done(qsp);
@@ -290,6 +299,124 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
}
}
+#ifdef BIND_NOTIFY
+int
+findZonePri(zp, from)
+ register const struct zoneinfo *zp;
+ const struct sockaddr_in *from;
+{
+ register u_int32_t from_addr = from->sin_addr.s_addr;
+ register int i;
+
+ for (i = 0; (u_int)i < zp->z_addrcnt; i++)
+ if (zp->z_addr[i].s_addr == from_addr)
+ return (i);
+ return (-1);
+}
+
+static enum req_action
+req_notify(hp, cpp, eom, msg, from)
+ HEADER *hp;
+ u_char **cpp, *eom, *msg;
+ struct sockaddr_in *from;
+{
+ int n, type, class, zn;
+ char dnbuf[MAXDNAME];
+ struct namebuf *np;
+ const char *fname;
+ struct hashbuf *htp = hashtab; /* lookup relative to root */
+
+ /* valid notify's have one question and zero answers */
+ if ((ntohs(hp->qdcount) != 1)
+ || hp->ancount
+ || hp->nscount
+ || hp->arcount) {
+ dprintf(1, (ddt, "FORMERR Notify header counts wrong\n"));
+ hp->qdcount = 0;
+ hp->ancount = 0;
+ hp->nscount = 0;
+ hp->arcount = 0;
+ hp->rcode = FORMERR;
+ return (Finish);
+ }
+
+ n = dn_expand(msg, eom, *cpp, dnbuf, sizeof dnbuf);
+ if (n < 0) {
+ dprintf(1, (ddt, "FORMERR Query expand name failed\n"));
+ hp->rcode = FORMERR;
+ return (Finish);
+ }
+ *cpp += n;
+ GETSHORT(type, *cpp);
+ GETSHORT(class, *cpp);
+ syslog(LOG_INFO, "rcvd NOTIFY(%s %s %s)",
+ dnbuf, p_class(class), p_type(type));
+ /* XXX - when answers are allowed, we'll need to do compression
+ * correctly here, and we will need to check for packet underflow.
+ */
+ np = nlookup(dnbuf, &htp, &fname, 0);
+ if (!np) {
+ syslog(LOG_INFO, "rcvd NOTIFY for \"%s\", name not in cache",
+ dnbuf);
+ hp->rcode = SERVFAIL;
+ return (Finish);
+ }
+ zn = findMyZone(np, class);
+ if (zn == DB_Z_CACHE || zones[zn].z_type != Z_SECONDARY) {
+ /* this can come if a user did an AXFR of some zone somewhere
+ * and that zone's server now wants to tell us that the SOA
+ * has changed. AXFR's always come from nonpriv ports so it
+ * isn't possible to know whether it was the server or just
+ * "dig". this condition can be avoided by using secure zones
+ * since that way only real secondaries can AXFR from you.
+ */
+ syslog(LOG_INFO,
+ "NOTIFY for non-secondary name (%s), from %s",
+ dnbuf, sin_ntoa(from));
+ goto refuse;
+ }
+ if (findZonePri(&zones[zn], from) == -1) {
+ syslog(LOG_INFO,
+ "NOTIFY from non-master server (zone %s), from %s",
+ zones[zn].z_origin, sin_ntoa(from));
+ goto refuse;
+ }
+ switch (type) {
+ case T_SOA:
+ if (strcasecmp(dnbuf, zones[zn].z_origin) != 0) {
+ syslog(LOG_INFO,
+ "NOTIFY(SOA) for non-origin (%s), from %s",
+ dnbuf, sin_ntoa(from));
+ goto refuse;
+ }
+ if (zones[zn].z_flags &
+ (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL|Z_XFER_RUNNING)) {
+ syslog(LOG_INFO,
+ "NOTIFY(SOA) for zone already xferring (%s)",
+ dnbuf);
+ goto noerror;
+ }
+ zones[zn].z_time = tt.tv_sec;
+ qserial_query(&zones[zn]);
+ /* XXX: qserial_query() can fail due to queue full condition;
+ * we should detect that case here and do something.
+ */
+ break;
+ default:
+ /* unimplemented, but it's not a protocol error, just
+ * something to be ignored.
+ */
+ break;
+ }
+ noerror:
+ hp->rcode = NOERROR;
+ return (Finish);
+ refuse:
+ hp->rcode = REFUSED;
+ return (Finish);
+}
+#endif /*BIND_NOTIFY*/
+
static enum req_action
req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
HEADER *hp;
@@ -303,14 +430,26 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
int n, class, type, count, foundname, founddata, omsglen, cname;
u_int16_t id;
u_char **dpp, *omsg, *answers;
- char dnbuf[MAXDNAME], *dname, *fname;
+ char dnbuf[MAXDNAME], *dname;
+ const char *fname;
struct hashbuf *htp;
struct databuf *nsp[NSMAX];
- struct namebuf *np;
+ struct namebuf *np, *anp;
struct qinfo *qp;
struct netinfo *lp;
+#ifdef SECURE_ZONES
+ struct zoneinfo *zp;
+#endif
+ struct databuf *dp;
nameserIncr(from->sin_addr, nssRcvdQ);
+
+#ifdef XSTATS
+ /* Statistics for queries coming from port <> 53, suspect some kind of forwarder */
+ if (from->sin_port != ns_port)
+ nameserIncr(from->sin_addr, nssNotNsQ);
+#endif
+
#ifdef DATUMREFCNT
nsp[0] = NULL;
#endif
@@ -368,10 +507,8 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
/* refuse request if not a TCP connection */
if (qsp == QSTREAM_NULL) {
syslog(LOG_INFO,
- "rejected UDP AXFR from [%s].%u for \"%s\"",
- inet_ntoa(from->sin_addr),
- ntohs(from->sin_port),
- *dnbuf ? dnbuf : ".");
+ "rejected UDP AXFR from %s for \"%s\"",
+ sin_ntoa(from), *dnbuf ? dnbuf : ".");
return (Refuse);
}
/* the position of this is subtle. */
@@ -384,20 +521,16 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
*/
if (!addr_on_netlist(from->sin_addr, xfrnets)) {
syslog(LOG_INFO,
- "unapproved AXFR from [%s].%u for %s",
- inet_ntoa(from->sin_addr),
- ntohs(from->sin_port),
- *dnbuf ? dnbuf : ".");
+ "unapproved AXFR from %s for %s",
+ sin_ntoa(from), *dnbuf ? dnbuf : ".");
return (Refuse);
}
}
#endif /*XFRNETS*/
dnptrs[0] = NULL; /* don't compress names */
hp->rd = 0; /* recursion not possible */
- syslog(LOG_INFO, "approved AXFR from [%s].%d for \"%s\"",
- inet_ntoa(from->sin_addr),
- ntohs(from->sin_port),
- *dnbuf ? dnbuf : ".");
+ syslog(LOG_INFO, "approved AXFR from %s for \"%s\"",
+ sin_ntoa(from), *dnbuf ? dnbuf : ".");
}
*buflenp -= *msglenp;
count = 0;
@@ -416,10 +549,10 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
#endif /*QRYLOG*/
try_again:
- dprintf(1, (ddt, "req: nlookup(%s) id %d type=%d\n",
- dname, hp->id, type));
+ dprintf(1, (ddt, "req: nlookup(%s) id %d type=%d class=%d\n",
+ dname, hp->id, type, class));
htp = hashtab; /* lookup relative to root */
- if ((np = nlookup(dname, &htp, &fname, 0)) == NULL)
+ if ((anp = np = nlookup(dname, &htp, &fname, 0)) == NULL)
fname = "";
dprintf(1, (ddt, "req: %s '%s' as '%s' (cname=%d)\n",
np == NULL ? "missed" : "found",
@@ -438,7 +571,7 @@ try_again:
dprintf(1, (ddt,"req: nlookup(%s) type=%d\n", dname, type));
htp = hashtab;
np = nlookup(dname, &htp, &fname, 0);
- }
+ }
#endif /*LOCALDOM*/
#ifdef YPKLUDGE
@@ -470,17 +603,26 @@ try_again:
goto fetchns;
#ifdef SECURE_ZONES
- if (np->n_data) {
- struct zoneinfo *zp;
-
- zp = &zones[np->n_data->d_zone];
+ /* (gdmr) Make sure the class is correct. If we have the same name
+ * with more than one class then we can't refuse a request for one
+ * class just because another class is blocked. We *really* ought
+ * to look for the correct type too, but since everything in a
+ * particular class of zone has the same secure_zone attribute it
+ * doesn't really matter which type we use! Alternatively, this lot
+ * could all be moved to after the finddata(), by which time only
+ * the correct class/type combinations will be left.
+ */
+ dp = np->n_data;
+ while (dp && (dp->d_class != class))
+ dp = dp->d_next;
+ if (dp) {
+ zp = &zones[dp->d_zone];
if (zp->secure_nets
&& !addr_on_netlist(from->sin_addr, zp->secure_nets)) {
- dprintf(1, (ddt,
- "REFUSED Unauthorized request from %s\n",
- inet_ntoa(from->sin_addr)));
- syslog(LOG_INFO, "Unauthorized request %s from %s",
- dname, inet_ntoa(from->sin_addr));
+ syslog(LOG_NOTICE, "Unauthorized request %s from %s",
+ dname, sin_ntoa(from));
+ dprintf(1, (ddt, "req: refuse %s from %s class %d (%d)\n",
+ dname, sin_ntoa(from), class, zp->z_class));
return (Refuse);
}
}
@@ -490,36 +632,30 @@ try_again:
count = *cpp - msg;
#ifdef NCACHE
- /* if this is a NXDOMAIN, will have only one databuf
- * whose d_rcode field will be NXDOMAIN. So we can go home
- * right here. -ve $ing: anant@isi.edu
+ /* Look for NXDOMAIN record with appropriate class
+ * if found return immediately
*/
- if (np->n_data != NULL && !stale(np->n_data)) {
- if (np->n_data->d_rcode == NXDOMAIN) {
+ for (dp = np->n_data; dp ; dp = dp->d_next) {
+ if (!stale(dp) && (dp->d_rcode == NXDOMAIN) &&
+ (dp->d_class == class)) {
#ifdef RETURNSOA
- n = finddata(np, class, T_SOA, hp, &dname,
- buflenp, &count);
- if (n != 0 ) {
- if (hp->rcode == NOERROR_NODATA) {
+ n = finddata(np, class, T_SOA, hp, &dname,
+ buflenp, &count);
+ if (n != 0 ) {
+ if (hp->rcode == NOERROR_NODATA) {
/* this should not occur */
hp->rcode = NOERROR;
return (Finish);
+ }
+ *cpp += n;
+ *buflenp -= n;
+ *msglenp += n;
+ hp->nscount = htons((u_int16_t)count);
}
- *cpp += n;
- *buflenp -= n;
- *msglenp += n;
- hp->rcode = NXDOMAIN;
- hp->nscount = htons((u_int16_t)count);
- hp->aa = 1;
- return (Finish);
- }
- else
- goto fetchns;
-#else
+#endif
hp->rcode = NXDOMAIN;
hp->aa = 1;
return (Finish);
-#endif
}
}
@@ -569,6 +705,29 @@ try_again:
if ((lp = local(from)) != NULL)
sort_response(answers, count, lp, *cpp);
+#ifdef BIND_NOTIFY
+ if (type == T_SOA &&
+ from->sin_port == ns_port &&
+ np->n_data) {
+ int zn = np->n_data->d_zone;
+
+ if (zn != DB_Z_CACHE) {
+ struct notify *ap;
+
+ /* Old? */
+ ap = findNotifyPeer(&zones[zn], from->sin_addr);
+ /* New? */
+ if (!ap && (ap = (struct notify *)malloc(sizeof *ap))) {
+ ap->addr = from->sin_addr;
+ ap->next = zones[zn].z_notifylist;
+ zones[zn].z_notifylist = ap;
+ }
+ /* Old or New? */
+ if (ap)
+ ap->last = tt.tv_sec;
+ }
+ }
+#endif /*BIND_NOTIFY*/
if (type == T_AXFR) {
hp->ancount = htons(hp->ancount);
startxfr(qsp, np, msg, *cpp - msg, class, dname);
@@ -598,6 +757,7 @@ fetchns:
count = 0;
switch (findns(&np, class, nsp, &count, 0)) {
case NXDOMAIN:
+ /* We are authoritative for this np. */
if (!foundname) {
hp->rcode = NXDOMAIN;
}
@@ -616,7 +776,7 @@ fetchns:
#ifdef ADDAUTH
} else if (hp->ancount) {
/* don't add NS records for NOERROR NODATA
- as some severs can get confused */
+ as some servers can get confused */
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
@@ -625,7 +785,9 @@ fetchns:
case SERVFAIL:
break;
default:
- if (np) {
+ if (np &&
+ (type != T_NS || np != anp)
+ ) {
n = add_data(np, nsp, *cpp,
*buflenp);
if (n < 0) {
@@ -648,6 +810,7 @@ fetchns:
return (Finish);
case SERVFAIL:
+ /* We're authoritative but the zone isn't loaded. */
if (!founddata && !(forward_only && fwdtab)) {
hp->rcode = SERVFAIL;
#ifdef DATUMREFCNT
@@ -664,17 +827,25 @@ fetchns:
* ("authority section") here and we're done.
*/
if (founddata || (!hp->rd) || NoRecurse) {
- n = add_data(np, nsp, *cpp, *buflenp);
- if (n < 0) {
- hp->tc = 1;
- n = (-n);
+ /* If the qtype was NS, and the np of the authority is
+ * the same as the np of the data, we don't need to add
+ * another copy of the answer here in the authority
+ * section.
+ */
+ if (!founddata || type != T_NS || anp != np) {
+ n = add_data(np, nsp, *cpp, *buflenp);
+ if (n < 0) {
+ hp->tc = 1;
+ n = (-n);
+ }
+ *cpp += n;
+ *buflenp -= n;
+ hp->nscount = htons((u_int16_t)count);
}
- *cpp += n;
- *buflenp -= n;
- hp->nscount = htons((u_int16_t)count);
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
+ /* Our caller will handle the Additional section. */
return (Finish);
}
@@ -688,8 +859,7 @@ fetchns:
if (cname) {
omsg = (u_char *)malloc((unsigned) *msglenp);
if (omsg == (u_char *)NULL) {
- dprintf(1, (ddt, "ns_req: malloc fail\n"));
- syslog(LOG_ERR, "ns_req: Out Of Memory");
+ syslog(LOG_INFO, "ns_req: Out Of Memory");
hp->rcode = SERVFAIL;
#ifdef DATUMREFCNT
free_nsp(nsp);
@@ -700,9 +870,18 @@ fetchns:
hp->ancount = htons(hp->ancount);
omsglen = *msglenp;
bcopy(msg, omsg, omsglen);
- *msglenp = res_mkquery(QUERY, dname, class, type,
- NULL, 0, NULL, msg,
- *msglenp + *buflenp);
+ n = res_mkquery(QUERY, dname, class, type,
+ NULL, 0, NULL, msg,
+ *msglenp + *buflenp);
+ if (n < 0) {
+ syslog(LOG_INFO, "res_mkquery(%s) failed", dname);
+ hp->rcode = SERVFAIL;
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return (Finish);
+ }
+ *msglenp = n;
}
n = ns_forw(nsp, msg, *msglenp, from, qsp, dfd, &qp, dname, np);
if (n != FW_OK && cname)
@@ -727,10 +906,7 @@ fetchns:
*/
if (np) {
if (np->n_dname[0] == '\0') {
- dprintf(1, (ddt,
- "ns_req: no address for root NS\n"
- ));
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"ns_req: no address for root server");
hp->rcode = SERVFAIL;
#ifdef DATUMREFCNT
@@ -762,7 +938,6 @@ fetchns:
return (Return);
}
-#ifdef INVQ
static enum req_action
req_iquery(hp, cpp, eom, buflenp, msg, from)
HEADER *hp;
@@ -771,12 +946,8 @@ req_iquery(hp, cpp, eom, buflenp, msg, from)
u_char *msg;
struct sockaddr_in *from;
{
- register struct invbuf *ip;
- int dlen, alen, i, n, type, class, count;
+ int dlen, alen, n, type, class, count;
char dnbuf[MAXDNAME], anbuf[PACKETSZ], *data, *fname;
- struct namebuf *np;
- struct qinfo *qp;
- struct databuf *dp;
nameserIncr(from->sin_addr, nssRcvdIQ);
@@ -819,8 +990,14 @@ req_iquery(hp, cpp, eom, buflenp, msg, from)
*/
switch (type) {
case T_A:
+#ifndef INVQ
+ if (!fake_iquery)
+ return (Refuse);
+#endif
+#ifdef INVQ
case T_UID:
case T_GID:
+#endif
break;
default:
return (Refuse);
@@ -833,10 +1010,29 @@ req_iquery(hp, cpp, eom, buflenp, msg, from)
*cpp = (u_char *)fname;
*buflenp -= HFIXEDSZ;
count = 0;
+
+#ifdef QRYLOG
+ if (qrylog) {
+ syslog(LOG_INFO, "XX /%s/%s/-%s",
+ inet_ntoa(from->sin_addr),
+ inet_ntoa(data_inaddr((u_char *)data)),
+ p_type(type));
+ }
+#endif /*QRYLOG*/
+
+#ifdef INVQ
+ {
+ register struct invbuf *ip;
+
for (ip = invtab[dhash((u_char *)data, dlen)];
ip != NULL;
ip = ip->i_next) {
+ int i;
+
for (i = 0; i < INVBLKSZ; i++) {
+ struct namebuf *np;
+ struct databuf *dp;
+
if ((np = ip->i_dname[i]) == NULL)
break;
dprintf(5, (ddt, "dname = %d\n", np->n_dname));
@@ -863,6 +1059,30 @@ req_iquery(hp, cpp, eom, buflenp, msg, from)
}
}
}
+ }
+#else /*INVQ*/
+ /*
+ * We can only get here if we are compiled without INVQ (the default)
+ * and the type is T_A and the option "fake-iquery" is on in the boot
+ * file.
+ *
+ * What we do here is send back a bogus response of "[dottedquad]".
+ * A better strategy would be to turn this into a PTR query, but that
+ * would legitimize inverse queries in a way they do not deserve.
+ */
+ sprintf(dnbuf, "[%s]", inet_ntoa(data_inaddr((u_char *)data)));
+ *buflenp -= QFIXEDSZ;
+ n = dn_comp(dnbuf, *cpp, *buflenp, NULL, NULL);
+ if (n < 0) {
+ hp->tc = 1;
+ return (Finish);
+ }
+ *cpp += n;
+ PUTSHORT((u_int16_t)type, *cpp);
+ PUTSHORT((u_int16_t)class, *cpp);
+ *buflenp -= n;
+ count++;
+#endif /*INVQ*/
dprintf(1, (ddt, "req: IQuery %d records\n", count));
hp->qdcount = htons((u_int16_t)count);
if (alen > *buflenp) {
@@ -873,7 +1093,6 @@ req_iquery(hp, cpp, eom, buflenp, msg, from)
*cpp += alen;
return (Finish);
}
-#endif
static void
fwritemsg(rfp, msg, msglen)
@@ -886,7 +1105,8 @@ fwritemsg(rfp, msg, msglen)
__putshort(msglen, len);
if (fwrite((char *)len, INT16SZ, 1, rfp) != 1 ||
fwrite((char *)msg, msglen, 1, rfp) != 1) {
- dprintf(1, (ddt, "fwrite failed %d\n", errno));
+ syslog(LOG_ERR, "fwritemsg: %m");
+ _exit(1);
}
}
@@ -904,10 +1124,14 @@ stale(dp)
case Z_PRIMARY:
return (0);
- case Z_SECONDARY:
#ifdef STUBS
case Z_STUB:
+ /* root stub zones have DB_F_HINT set */
+ if (dp->d_flags & DB_F_HINT)
+ return (0);
+ /* FALLTROUGH */
#endif
+ case Z_SECONDARY:
/*
* Check to see whether a secondary zone
* has expired; if so clear authority flag
@@ -920,27 +1144,37 @@ stale(dp)
"stale: secondary zone %s expired\n",
zp->z_origin));
if (!haveComplained(zp->z_origin, (char*)stale)) {
- syslog(LOG_ERR,
+ syslog(LOG_NOTICE,
"secondary zone \"%s\" expired",
zp->z_origin);
}
zp->z_flags &= ~Z_AUTH;
return (1);
}
+ if (zp->z_lastupdate > tt.tv_sec) {
+ if (!haveComplained(zp->z_origin, (char*)stale)) {
+ syslog(LOG_NOTICE,
+ "secondary zone \"%s\" time warp",
+ zp->z_origin);
+ }
+ zp->z_flags &= ~Z_AUTH;
+ return (1);
+ }
return (0);
case Z_CACHE:
if (dp->d_flags & DB_F_HINT || dp->d_ttl >= tt.tv_sec)
return (0);
- dprintf(3, (ddt, "stale: ttl %d %d (x%x)\n",
- dp->d_ttl, dp->d_ttl - tt.tv_sec, dp->d_flags));
+ dprintf(3, (ddt, "stale: ttl %d %d (x%lx)\n",
+ dp->d_ttl, dp->d_ttl - tt.tv_sec,
+ (u_long)dp->d_flags));
return (1);
default:
/* FALLTHROUGH */ ;
}
- abort();
+ panic(-1, "stale: impossible condition");
/* NOTREACHED */
}
@@ -950,7 +1184,7 @@ stale(dp)
*/
int
make_rr(name, dp, buf, buflen, doadd)
- char *name;
+ const char *name;
register struct databuf *dp;
u_char *buf;
int buflen, doadd;
@@ -962,31 +1196,27 @@ make_rr(name, dp, buf, buflen, doadd)
register int32_t ttl;
u_char **edp = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
- dprintf(5, (ddt, "make_rr(%s, %x, %x, %d, %d) %d zone %d ttl %d\n",
- name, dp, buf,
+ dprintf(5, (ddt, "make_rr(%s, %lx, %lx, %d, %d) %d zone %d ttl %d\n",
+ name, (u_long)dp, (u_long)buf,
buflen, doadd, dp->d_size, dp->d_zone, dp->d_ttl));
#ifdef NCACHE
if (dp->d_rcode
#ifdef RETURNSOA
- && dp->d_rcode != NXDOMAIN
+ && dp->d_rcode != NXDOMAIN
#endif
) {
- syslog(LOG_CRIT, "make_rr d_rcode %d", dp->d_rcode);
-#ifdef DEBUG
- if (debug) abort();
-#endif
- return (-1); /* XXX We should exit here */
+ panic(-1, "make_rr: impossible d_rcode value");
}
#endif
zp = &zones[dp->d_zone];
- /* check for outdated RR before updating dnptrs by dn_comp() (???) */
+ /* check for outdated RR before updating dnptrs by dn_comp() (?) */
if (zp->z_type == Z_CACHE) {
ttl = dp->d_ttl - (u_int32_t) tt.tv_sec;
if ((dp->d_flags & DB_F_HINT) || (ttl < 0)) {
dprintf(3, (ddt,
- "make_rr: %d=>0, x%x\n",
- ttl, dp->d_flags)); /* XXX */
+ "make_rr: %d=>0, %#lx\n",
+ ttl, (u_long)dp->d_flags));
ttl = 0;
}
} else {
@@ -1047,7 +1277,8 @@ make_rr(name, dp, buf, buflen, doadd)
PUTSHORT((u_int16_t)n, sp);
cp += n;
if (doadd)
- addname((char*)dp->d_data, dp->d_class);
+ addname((char*)dp->d_data, name,
+ dp->d_type, dp->d_class);
break;
case T_SOA:
@@ -1079,22 +1310,51 @@ make_rr(name, dp, buf, buflen, doadd)
/* cp1 == our data/ cp == data of RR */
cp1 = dp->d_data;
+ if ((buflen -= INT16SZ) < 0)
+ return (-1);
+
/* copy preference */
bcopy(cp1, cp, INT16SZ);
cp += INT16SZ;
cp1 += INT16SZ;
- buflen -= INT16SZ;
n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp);
- if (n < 0)
- return (-1);
- cp += n;
+ if (n < 0)
+ return (-1);
+ cp += n;
- /* save data length */
+ /* save data length */
n = (u_int16_t)((cp - sp) - INT16SZ);
- PUTSHORT((u_int16_t)n, sp);
+ PUTSHORT((u_int16_t)n, sp);
if (doadd)
- addname((char*)cp1, dp->d_class);
+ addname((char*)cp1, name, dp->d_type, dp->d_class);
+ break;
+
+ case T_PX:
+ cp1 = dp->d_data;
+
+ if ((buflen -= INT16SZ) < 0)
+ return (-1);
+
+ /* copy preference */
+ bcopy(cp1, cp, INT16SZ);
+ cp += INT16SZ;
+ cp1 += INT16SZ;
+
+ n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ cp1 += strlen((char *)cp1) + 1;
+ n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp);
+ if (n < 0)
+ return (-1);
+ cp += n;
+
+ /* save data length */
+ n = (u_int16_t)((cp - sp) - INT16SZ);
+ PUTSHORT((u_int16_t)n, sp);
break;
default:
@@ -1109,28 +1369,33 @@ make_rr(name, dp, buf, buflen, doadd)
#if defined(__STDC__) || defined(__GNUC__)
static void
-addname(register char *name,
+addname(register const char *dname,
+ register const char *rname,
+ u_int16_t rtype,
u_int16_t class)
#else
static void
-addname(name, class)
- register char *name;
- u_int16_t class;
+addname(dname, rname, rtype, class)
+ register const char *dname;
+ register const char *rname;
+ u_int16_t rtype;
+ u_int16_t class;
#endif
{
register struct addinfo *ap;
register int n;
for (ap = addinfo, n = addcount; --n >= 0; ap++)
- if (strcasecmp(ap->a_dname, name) == 0)
+ if (strcasecmp(ap->a_dname, dname) == 0)
return;
/* add domain name to additional section */
if (addcount < NADDRECS) {
addcount++;
- ap->a_dname = (char *)malloc(strlen(name)+1);
- strcpy(ap->a_dname,name);
+ ap->a_dname = savestr(dname);
+ ap->a_rname = savestr(rname);
+ ap->a_rtype = rtype;
ap->a_class = class;
}
}
@@ -1150,9 +1415,12 @@ doaddinfo(hp, msg, msglen)
register struct addinfo *ap;
register u_char *cp;
struct hashbuf *htp;
- char *fname;
+ const char *fname;
int n, count;
+ if (!addcount)
+ return (0);
+
dprintf(3, (ddt, "doaddinfo() addcount = %d\n", addcount));
if (hp->tc) {
@@ -1165,11 +1433,13 @@ doaddinfo(hp, msg, msglen)
for (ap = addinfo; --addcount >= 0; ap++) {
int foundstale = 0,
foundany = 0,
+ foundcname = 0,
save_count = count,
save_msglen = msglen;
u_char *save_cp = cp;
- dprintf(3, (ddt, "do additional '%s'\n", ap->a_dname));
+ dprintf(3, (ddt, "do additional \"%s\" (from \"%s\")\n",
+ ap->a_dname, ap->a_rname));
htp = hashtab; /* because "nlookup" stomps on arg. */
np = nlookup(ap->a_dname, &htp, &fname, 0);
if (np == NULL || fname != ap->a_dname)
@@ -1177,9 +1447,17 @@ doaddinfo(hp, msg, msglen)
dprintf(3, (ddt, "found it\n"));
/* look for the data */
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
- if ( (!match(dp, (int)ap->a_class, T_A))
- && (!match(dp, C_IN, T_A))
- ) {
+#ifdef NCACHE
+ if (dp->d_rcode)
+ continue;
+#endif
+ if (match(dp, (int)ap->a_class, T_CNAME) ||
+ match(dp, C_IN, T_CNAME)) {
+ foundcname++;
+ break;
+ }
+ if (!match(dp, (int)ap->a_class, T_A) &&
+ !match(dp, C_IN, T_A)) {
continue;
}
foundany++;
@@ -1194,10 +1472,6 @@ doaddinfo(hp, msg, msglen)
));
continue;
}
-#ifdef NCACHE
- if (dp->d_rcode)
- continue;
-#endif
/*
* Should be smart and eliminate duplicate
* data here. XXX
@@ -1213,6 +1487,9 @@ doaddinfo(hp, msg, msglen)
* since we only do A RR's here, the name is
* the key). vixie, 23apr93
*/
+ dprintf(5, (ddt,
+ "addinfo: not enough room, remaining msglen = %d\n",
+ save_msglen));
cp = save_cp;
msglen = save_msglen;
count = save_count;
@@ -1225,16 +1502,31 @@ doaddinfo(hp, msg, msglen)
msglen -= n;
count++;
}
-next_rr: if (foundstale) {
+ next_rr:
+ if (foundstale) {
/* Cache invalidate the address RR's */
delete_all(np, (int)ap->a_class, T_A);
}
- if (foundstale || !foundany) {
+ if (
+#if 0 /*XXX*/
+ !NoRecurse &&
+#endif
+ !foundcname && (foundstale || !foundany)) {
/* ask a real server for this info */
(void) sysquery(ap->a_dname, (int)ap->a_class, T_A,
- NULL, 0);
+ NULL, 0, QUERY);
+ }
+ if (foundcname) {
+ if (!haveComplained((char*)nhash(ap->a_dname),
+ (char*)nhash(ap->a_rname))) {
+ syslog(LOG_INFO,
+ "\"%s %s %s\" points to a CNAME (%s)",
+ ap->a_rname, p_class(ap->a_class),
+ p_type(ap->a_rtype), ap->a_dname);
+ }
}
free(ap->a_dname);
+ free(ap->a_rname);
}
hp->arcount = htons((u_int16_t)count);
return (cp - msg);
@@ -1299,25 +1591,22 @@ doaxfr(np, rfp, top, class)
struct namebuf **npp, **nppend;
u_char msg[PACKETSZ];
u_char *cp;
- char *fname;
+ const char *fname;
char dname[MAXDNAME];
- HEADER *hp = (HEADER *) msg;
+ HEADER *hp;
int fndns;
if (np == top)
dprintf(1, (ddt, "doaxfr()\n"));
fndns = 0;
- hp->id = 0;
+ bzero((char*)msg, sizeof msg);
+ hp = (HEADER *) msg;
hp->opcode = QUERY;
- hp->aa = hp->tc = hp->ra = hp->pr = hp->rd = 0;
hp->qr = 1;
hp->rcode = NOERROR;
- hp->qdcount = 0;
hp->ancount = htons(1);
- hp->nscount = 0;
- hp->arcount = 0;
- cp = (u_char *) (msg + HFIXEDSZ);
- getname(np, dname, sizeof(dname));
+ cp = msg + HFIXEDSZ;
+ getname(np, dname, sizeof dname);
/* first do the NS records (del@harris) */
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
@@ -1357,7 +1646,9 @@ doaxfr(np, rfp, top, class)
break;
if ( (tnp == NULL) && (top->n_dname[0] != '\0') )
continue; /* name server is not below top domain */
- for (tnp = gnp; tnp != top; tnp = tnp->n_parent) {
+ for (tnp = gnp;
+ tnp != NULL && tnp != top;
+ tnp = tnp->n_parent) {
for (tdp = tnp->n_data;
tdp != NULL;
tdp = tdp->d_next) {
@@ -1371,7 +1662,8 @@ doaxfr(np, rfp, top, class)
if (tdp != NULL)
break; /* found a zone cut */
}
- if (tnp == top)
+ if ((tnp == top) ||
+ ((tnp == NULL) && (top->n_dname[0] == '\0')))
continue; /* name server is not in a delegated zone */
/* now we know glue records are needed. send them. */
#endif /*NO_GLUE*/
@@ -1562,8 +1854,6 @@ InitDynUpdate(hp, msg, msglen, startcp, from, qsp, dfd)
*znp = NULL;
np = nlookup(ZoneName, &htp, &fname, 0);
if ((np == NULL) || (fname != ZoneName)) {
- dprintf(1, (ddt, "InitDynUpdate: lookup failed on zone (%s)\n",
- ZoneName));
syslog(LOG_ERR, "InitDynUpdate: lookup failed on zone (%s)\n",
ZoneName);
hp->rcode = NXDOMAIN;
@@ -1618,13 +1908,9 @@ InitDynUpdate(hp, msg, msglen, startcp, from, qsp, dfd)
if (match(olddp, class, T_SOA))
break;
if (olddp == NULL) {
- dprintf(1, (ddt,
- "InitDynUpdate: Couldn't find SOA record for '%s'\n",
- ZoneName));
- syslog(LOG_ERR,
- "InitDynUpdate: Couldn't find SOA record for '%s'\n"
-,
- ZoneName);
+ syslog(LOG_NOTICE,
+ "InitDynUpdate: Couldn't find SOA RR for '%s'\n",
+ ZoneName);
hp->rcode = NXDOMAIN;
#ifdef DATUMREFCNT
free_nsp(nsp);
@@ -1690,11 +1976,14 @@ printSOAdata(dp)
if (!debug)
return; /* Otherwise fprintf to ddt will bomb */
cp = (u_char *)dp->d_data;
- fprintf(ddt, "printSOAdata(%x): origin(%x)='%s'\n", dp, cp, cp);
+ fprintf(ddt, "printSOAdata(%#lx): origin(%#lx)='%s'\n",
+ (u_long)dp, (u_long)cp, cp);
cp += strlen(cp) + 1; /* skip origin string */
- fprintf(ddt, "printSOAdata: in-charge(%x)='%s'\n", cp, cp);
+ fprintf(ddt, "printSOAdata: in-charge(%#lx)='%s'\n",
+ (u_long)cp, cp);
cp += strlen(cp) + 1; /* skip in-charge string */
- fprintf(ddt, "printSOAdata: serial(%x)=%d\n", cp, _getlong(cp));
+ fprintf(ddt, "printSOAdata: serial(%lx)=%d\n",
+ cp, (u_long)_getlong(cp));
}
#endif
#endif
@@ -1711,6 +2000,15 @@ startxfr(qsp, np, soa, soalen, class, dname)
FILE *rfp;
int fdstat;
pid_t pid;
+#ifdef HAVE_SETVBUF
+ char *buf;
+#endif
+#ifdef SO_SNDBUF
+ static const int sndbuf = XFER_BUFSIZE * 2;
+#endif
+#ifdef SO_LINGER
+ static const struct linger ll = { 1, 120 };
+#endif
dprintf(5, (ddt, "startxfr()\n"));
@@ -1720,16 +2018,16 @@ startxfr(qsp, np, soa, soalen, class, dname)
*/
switch (pid = fork()) {
case -1:
- syslog(LOG_ERR, "startxfr(%s -> [%s]) failing; fork: %m",
- dname, inet_ntoa(qsp->s_from.sin_addr));
+ syslog(LOG_NOTICE, "startxfr(%s -> %s) failing; fork: %m",
+ dname, sin_ntoa(&qsp->s_from));
return;
case 0:
/* child */
break;
default:
/* parent */
- syslog(LOG_DEBUG, "zone transfer of \"%s\" to [%s] (pid %lu)",
- dname, inet_ntoa(qsp->s_from.sin_addr), pid);
+ syslog(LOG_DEBUG, "zone transfer of \"%s\" to %s (pid %lu)",
+ dname, sin_ntoa(&qsp->s_from), pid);
return;
}
@@ -1758,25 +2056,58 @@ startxfr(qsp, np, soa, soalen, class, dname)
_exit(1);
}
(void) fcntl(qsp->s_rfd, F_SETFL, fdstat & ~PORT_NONBLOCK);
+#ifdef HAVE_SETVBUF
+ /* some systems (DEC OSF/1, SunOS) don't initialize the stdio buffer
+ * if all you do between fdopen() and fclose() are fwrite()'s. even
+ * on systems where the buffer is correctly set, it is too small.
+ */
+ if ((buf = malloc(XFER_BUFSIZE)) != NULL)
+ (void) setvbuf(rfp, buf, _IOFBF, XFER_BUFSIZE);
+#endif
+#ifdef SO_SNDBUF
+ /* the default seems to be 4K, and we'd like it to have enough room
+ * to parallelize sending the pushed data with accumulating more
+ * write() data from us.
+ */
+ (void) setsockopt(qsp->s_rfd, SOL_SOCKET, SO_SNDBUF,
+ (char *)&sndbuf, sizeof sndbuf);
+#endif
+ /* XXX: some day we would like to only send the size and header out
+ * when we fill a 64K DNS/AXFR "message" rather than on each RR.
+ * (PVM@ISI gets credit for this idea.)
+ */
fwritemsg(rfp, soa, soalen);
doaxfr(np, rfp, np, class);
fwritemsg(rfp, soa, soalen);
(void) fflush(rfp);
+#ifdef SO_LINGER
+ /* kernels that map pages for IO end up failing if the pipe is full
+ * at exit and we take away the final buffer. this is really a kernel
+ * bug but it's harmless on systems that are not broken, so...
+ */
+ setsockopt(qsp->s_rfd, SOL_SOCKET, SO_LINGER,
+ (char *)&ll, sizeof ll);
+ close(qsp->s_rfd);
+#endif
_exit(0);
+ /* NOTREACHED */
}
+void
free_addinfo() {
struct addinfo *ap;
for (ap = addinfo; --addcount >= 0; ap++) {
free(ap->a_dname);
+ free(ap->a_rname);
}
addcount = 0;
}
#ifdef DATUMREFCNT
+void
free_nsp(nsp)
-struct databuf **nsp;
+ struct databuf **nsp;
{
while (*nsp) {
if (--((*nsp)->d_rcnt)) {
diff --git a/usr.sbin/named/ns_resp.c b/usr.sbin/named/ns_resp.c
index 004721b57b57e..fde341cf23eb2 100644
--- a/usr.sbin/named/ns_resp.c
+++ b/usr.sbin/named/ns_resp.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_resp.c 4.65 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: ns_resp.c,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $";
+static char rcsid[] = "$Id: ns_resp.c,v 1.2 1995/05/30 03:48:56 rgrimes Exp $";
#endif /* not lint */
/*
@@ -76,19 +76,94 @@ static void check_root __P((void)),
static u_int8_t norootlogged[MAXCLASS]; /* XXX- should be a bitmap */
-static char skipnameFailedAnswer[] = "skipname failed in answer",
+static const char skipnameFailedAnswer[] = "skipname failed in answer",
skipnameFailedQuery[] = "skipname failed in query",
outofDataQuery[] = "ran out of data in query",
outofDataAnswer[] = "ran out of data in answer",
-#ifdef LAME_DELEGATION
+ notSingleQuery[] = "not exactly one query",
expandFailedQuery[] = "dn_expand failed in query",
+ expandFailedAnswer[] = "dn_expand failed in answer",
expandFailedAuth[] = "dn_expand failed in authority",
outofDataAuth[] = "ran out of data in authority",
-#endif /* LAME_DELEGATION */
dlenOverrunAnswer[] = "dlen overrun in answer",
dlenUnderrunAnswer[] = "dlen underrun in answer",
outofDataFinal[] = "out of data in final pass",
- outofDataAFinal[] = "out of data after final pass";
+ outofDataAFinal[] = "out of data after final pass",
+ editFailed[] = "edit of response failed";
+
+static char *
+learntFrom(qp, server)
+ struct qinfo *qp;
+ struct sockaddr_in *server;
+{
+ static char *buf = NULL;
+ char *a, *ns, *na;
+ struct databuf *db;
+ char nsbuf[20];
+ char abuf[20];
+ int i;
+
+ if (buf) {
+ free(buf);
+ buf = NULL;
+ }
+
+ a = ns = na = "<Not Available>";
+
+ for (i = 0; i < (int)qp->q_naddr; i++) {
+ if (qp->q_addr[i].ns_addr.sin_addr.s_addr ==
+ server->sin_addr.s_addr) {
+ db = qp->q_addr[i].ns;
+ if (db) {
+#ifdef STATS
+ if (db->d_ns) {
+ strcpy(nsbuf,
+ inet_ntoa(db->d_ns->addr));
+ ns = nsbuf;
+ } else {
+ ns = zones[db->d_zone].z_origin;
+ }
+#endif
+
+#ifdef NCACHE
+ if (!db->d_rcode)
+#endif
+ na = (char*)qp->q_addr[i].ns->d_data;
+ }
+
+#ifdef STATS
+ db = qp->q_addr[i].nsdata;
+ if (db) {
+ if (db->d_ns) {
+ strcpy(abuf,
+ inet_ntoa(db->d_ns->addr));
+ a = abuf;
+ } else {
+ a = zones[db->d_zone].z_origin;
+ }
+ }
+#endif
+ break;
+ }
+ }
+
+ if ((a == ns) && (ns == na)) /* all "UNKNOWN" */
+ return ("");
+
+#ifdef STATS
+# define LEARNTFROM " '%s': learnt (A=%s,NS=%s)"
+#else
+# define LEARNTFROM " '%s'"
+#endif
+ if (buf = malloc(strlen(a = (*a ? a : "\".\"")) +
+ strlen(ns = (*ns ? ns : "\".\"")) +
+ strlen(na = (*na ? na : "\".\"")) +
+ sizeof(LEARNTFROM))) {
+ sprintf(buf, LEARNTFROM, na, a, ns);
+ return (buf);
+ }
+ return("");
+}
void
ns_resp(msg, msglen)
@@ -100,24 +175,25 @@ ns_resp(msg, msglen)
register struct qserv *qs;
register struct databuf *ns, *ns2;
register u_char *cp;
+ u_char *eom = msg + msglen;
#ifdef VALIDATE
register u_char *tempcp;
struct sockaddr_in *server = &from_addr;
int *validatelist;
- int lesscount;
+ int lesscount, old_ancount;
#endif
struct sockaddr_in *nsa;
struct databuf *nsp[NSMAX], **nspp;
- int i, c, n, ancount, aucount, nscount, arcount;
- int old_ancount;
- int type, class, dbflags;
+ int i, c, n, qdcount, ancount, aucount, nscount, arcount;
+ int qtype, qclass, dbflags;
int cname = 0; /* flag for processing cname response */
int count, founddata, foundname;
int buflen;
int newmsglen;
- char name[MAXDNAME], *dname;
- char *fname;
- char *formerrmsg = "brain damage";
+ char name[MAXDNAME], qname[MAXDNAME];
+ char *dname;
+ const char *fname;
+ const char *formerrmsg = "brain damage";
u_char newmsg[BUFSIZ];
u_char **dpp, *tp;
time_t rtrip;
@@ -144,6 +220,53 @@ ns_resp(msg, msglen)
ntohs(qp->q_nsid), ntohs(qp->q_id)));
/*
+ * Here we handle high level formatting problems by parsing the header.
+ */
+ qdcount = ntohs(hp->qdcount);
+ ancount = ntohs(hp->ancount);
+ aucount = ntohs(hp->nscount); /* !!! */
+ arcount = ntohs(hp->arcount);
+ free_addinfo(); /* sets addcount to zero */
+ cp = msg + HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = msg;
+ if ((*cp & INDIR_MASK) == 0)
+ *dpp++ = cp;
+ *dpp = NULL;
+ if (qdcount == 1) {
+ n = dn_expand(msg, eom, cp, qname, sizeof(qname));
+ if (n <= 0) {
+ formerrmsg = expandFailedQuery;
+ goto formerr;
+ }
+ cp += n;
+ GETSHORT(qtype, cp);
+ GETSHORT(qclass, cp);
+ if (cp > eom) {
+ formerrmsg = outofDataQuery;
+ goto formerr;
+ }
+ if (qp->q_msg && qp->q_msglen &&
+ !res_nameinquery(qname, qtype, qclass,
+ qp->q_msg, qp->q_msg + qp->q_msglen)) {
+ char msgbuf[MAXDNAME*2];
+
+ sprintf(msgbuf,
+ "query section mismatch (%s %s %s)",
+ qname, p_class(qclass), p_type(qtype));
+ formerrmsg = msgbuf;
+ goto formerr;
+ }
+ } else {
+ /* Pedantic. */
+ qname[0] = '\0';
+ qtype = 0;
+ qclass = 0;
+ }
+
+ /* cp now points after the query section (if there was one). */
+
+ /*
* Here we handle bad responses from servers.
* Several possibilities come to mind:
* The server is sick and returns SERVFAIL
@@ -157,8 +280,12 @@ ns_resp(msg, msglen)
|| (hp->rcode == NXDOMAIN && !hp->aa) /* must accept this one if
* we allow negative caching
*/
-#endif /*NCACHE*/
- || hp->opcode != QUERY) {
+#endif
+ || (hp->opcode != QUERY
+#ifdef BIND_NOTIFY
+ && hp->opcode != NS_NOTIFY_OP
+#endif
+ )) {
dprintf(2, (ddt, "resp: error (ret %d, op %d), dropped\n",
hp->rcode, hp->opcode));
switch (hp->rcode) {
@@ -174,63 +301,47 @@ ns_resp(msg, msglen)
}
return;
}
+
+ if (qdcount != 1) {
+ /* We don't generate or forward these (yet). */
+ formerrmsg = notSingleQuery;
+ goto formerr;
+ }
+
#ifdef LAME_DELEGATION
/*
* Non-authoritative, no answer, no error
*/
- if (hp->rcode == NOERROR && !hp->aa && ntohs(hp->ancount) == 0 &&
- ntohs(hp->nscount) > 0) {
-
-#ifdef LAME_LOGGING
- char qname[MAXDNAME];
-#endif /* LAME_LOGGING */
-
+ if (qdcount == 1 && hp->rcode == NOERROR && !hp->aa && ancount == 0
+ && aucount > 0
+#ifdef BIND_NOTIFY
+ && hp->opcode != NS_NOTIFY_OP
+#endif
+ ) {
+ u_char *tp;
+ int type, class;
#ifdef DEBUG
if (debug > 0)
- fp_query(msg, ddt);
+ fp_nquery(msg, msglen, ddt);
#endif
-
- cp = msg + HFIXEDSZ;
- dpp = dnptrs;
- *dpp++ = msg;
- if ((*cp & INDIR_MASK) == 0)
- *dpp++ = cp;
- *dpp = NULL;
- if (hp->qdcount) {
-#ifdef LAME_LOGGING
- n = dn_expand(msg, msg + msglen, cp, qname,
- sizeof(qname));
- if (n <= 0) {
- formerrmsg = expandFailedQuery;
- goto formerr;
- }
-#else /* LAME_LOGGING */
- n = dn_skipname(cp, msg + msglen);
- if (n <= 0) {
- formerrmsg = skipnameFailedQuery;
- goto formerr;
- }
-#endif /* LAME_LOGGING */
- cp += n;
- GETSHORT(type, cp);
- GETSHORT(class, cp);
- if (cp - msg > msglen) {
- formerrmsg = outofDataQuery;
- goto formerr;
- }
-#ifdef LAME_LOGGING
- } else {
- strcpy(qname, "[No query name!]");
-#endif /* LAME_LOGGING */
- }
- n = dn_expand(msg, msg + msglen, cp, name, sizeof name);
+ /*
+ * Since there is no answer section (ancount == 0),
+ * we must be pointing at the authority section (aucount > 0).
+ */
+ tp = cp;
+ n = dn_expand(msg, eom, tp, name, sizeof name);
if (n < 0) {
formerrmsg = expandFailedAuth;
goto formerr;
}
- cp += n;
- GETSHORT(type, cp);
- if (cp - msg > msglen) {
+ tp += n;
+ GETSHORT(type, tp);
+ if (tp >= eom) {
+ formerrmsg = outofDataAuth;
+ goto formerr;
+ }
+ GETSHORT(class, tp);
+ if (tp >= eom) {
formerrmsg = outofDataAuth;
goto formerr;
}
@@ -238,31 +349,31 @@ ns_resp(msg, msglen)
/*
* If the answer delegates us either to the same level in
* the hierarchy or closer to the root, we consider this
- * server lame.
+ * server lame. Note that for now we only log the message
+ * if the T_NS was C_IN, which is technically wrong (NS is
+ * visible in all classes) but necessary anyway (non-IN
+ * classes tend to not have good strong delegation graphs).
*/
if (type == T_NS && samedomain(qp->q_domain, name)) {
nameserIncr(from_addr.sin_addr, nssRcvdLDel);
#ifdef LAME_LOGGING
- if (!haveComplained((char*)dhash((u_char*)name,
- strlen(name)),
- (char*)dhash((u_char*)qp->q_domain,
- strlen(qp->q_domain)
- )
- )
- ) {
+ if (class == C_IN &&
+ !haveComplained((char*)nhash(name),
+ (char*)nhash(qp->q_domain)))
syslog(LAME_LOGGING,
-"Lame delegation to '%s' from [%s] (server for '%s'?) on query on name '%s'\n",
- name, inet_ntoa(from_addr.sin_addr),
- qp->q_domain, qname);
- }
+ "Lame server on '%s' (in '%s'?): %s%s\n",
+ qname, qp->q_domain,
+ inet_etoa(&from_addr),
+ learntFrom(qp, &from_addr)
+ );
+
#endif /* LAME_LOGGING */
return;
}
}
#endif /* LAME_DELEGATION */
-
#ifdef ALLOW_UPDATES
if ( (hp->rcode == NOERROR) &&
(hp->opcode == UPDATEA || hp->opcode == UPDATED ||
@@ -297,25 +408,26 @@ ns_resp(msg, msglen)
/* XXX: note bad ambiguity here. if one of our forwarders is also
* a delegated server for some domain, then we will not update
* the RTT information on any replies we get from those servers.
+ * Workaround: disable recursion on authoritative servers so that
+ * the ambiguity does not arise.
*/
/*
- * If we were using nameservers, find the qinfo pointer and update
+ * If we weren't using a forwarder, find the qinfo pointer and update
* the rtt and fact that we have called on this server before.
*/
if (fwd == (struct fwdinfo *)NULL) {
struct timeval *stp;
- for (n = 0, qs = qp->q_addr; n < qp->q_naddr; n++, qs++)
+ for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; n++, qs++)
if (qs->ns_addr.sin_addr.s_addr ==
from_addr.sin_addr.s_addr)
break;
- if (n >= qp->q_naddr) {
+ if ((u_int)n >= qp->q_naddr) {
if (!haveComplained((char*)from_addr.sin_addr.s_addr,
"unexpected source")) {
- syslog(LOG_NOTICE,
- "Response from unexpected source [%s].%d",
- inet_ntoa(from_addr.sin_addr),
- ntohs(from_addr.sin_port));
+ syslog(LOG_INFO,
+ "Response from unexpected source (%s)",
+ inet_etoa(&from_addr));
}
/*
* We don't know who this response came from so it
@@ -338,8 +450,8 @@ ns_resp(msg, msglen)
*/
dprintf(1, (ddt,
"Response from unused address %s, assuming %s\n",
- inet_ntoa(from_addr.sin_addr),
- inet_ntoa(qs->ns_addr.sin_addr)));
+ inet_etoa(&from_addr),
+ inet_etoa(&qs->ns_addr)));
/* XXX - catch aliases here */
}
@@ -356,9 +468,10 @@ ns_resp(msg, msglen)
(tt.tv_usec - stp->tv_usec) / 1000);
}
- dprintf(3, (ddt, "stime %d/%d now %d/%d rtt %d\n",
- stp->tv_sec, stp->tv_usec,
- tt.tv_sec, tt.tv_usec, rtrip));
+ dprintf(3, (ddt, "stime %lu/%lu now %lu/%lu rtt %ld\n",
+ (u_long)stp->tv_sec, (u_long)stp->tv_usec,
+ (u_long)tt.tv_sec, (u_long)tt.tv_usec,
+ (long)rtrip));
/* prevent floating point overflow, limit to 1000 sec */
if (rtrip > 1000000) {
@@ -389,8 +502,8 @@ ns_resp(msg, msglen)
*/
if (ns && qs->ns && (qp->q_nusedns < NSMAX)) {
qp->q_usedns[qp->q_nusedns++] = qs->ns;
- dprintf(2, (ddt, "NS #%d addr [%s] used, rtt %d\n",
- n, inet_ntoa(qs->ns_addr.sin_addr),
+ dprintf(2, (ddt, "NS #%d addr %s used, rtt %d\n",
+ n, inet_etoa(&qs->ns_addr),
ns->d_nstime));
}
@@ -405,7 +518,7 @@ ns_resp(msg, msglen)
* and are no longer the correct type. XXX
*/
- for (n = 0, qs = qp->q_addr; n < qp->q_naddr; n++, qs++) {
+ for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; n++, qs++) {
ns2 = qs->nsdata;
if ((!ns2) || (ns2 == ns))
continue;
@@ -423,46 +536,28 @@ ns_resp(msg, msglen)
ns2->d_nstime = 1000000;
} else
ns2->d_nstime = (u_int32_t)(ns2->d_nstime * GAMMA);
- dprintf(2, (ddt, "NS #%d [%s] rtt now %d\n", n,
- inet_ntoa(qs->ns_addr.sin_addr),
+ dprintf(2, (ddt, "NS #%d %s rtt now %d\n", n,
+ inet_etoa(&qs->ns_addr),
ns2->d_nstime));
}
}
- /*************************************************************/
-
- /*
- * Skip query section
+#ifdef BIND_NOTIFY
+ /* for now, NOTIFY isn't defined for ANCOUNT!=0, AUCOUNT!=0,
+ * or ADCOUNT!=0. therefore the only real work to be done for
+ * a NOTIFY-QR is to remove it from the query queue.
*/
- free_addinfo(); /* sets addcount to zero */
- cp = msg + HFIXEDSZ;
- dpp = dnptrs;
- *dpp++ = msg;
- if ((*cp & INDIR_MASK) == 0)
- *dpp++ = cp;
- *dpp = NULL;
- type = class = 0;
- if (hp->qdcount) {
- n = dn_skipname(cp, msg + msglen);
- if (n <= 0) {
- formerrmsg = skipnameFailedQuery;
- goto formerr;
- }
- cp += n;
- GETSHORT(type, cp);
- GETSHORT(class, cp);
- if (cp - msg > msglen) {
- formerrmsg = outofDataQuery;
- goto formerr;
- }
+ if (hp->opcode == NS_NOTIFY_OP) {
+ qremove(qp);
+ return;
}
+#endif
+
+ /*************************************************************/
/*
* Save answers, authority, and additional records for future use.
*/
- ancount = ntohs(hp->ancount);
- aucount = ntohs(hp->nscount);
- arcount = ntohs(hp->arcount);
nscount = 0;
tp = cp;
dprintf(3, (ddt, "resp: ancount %d, aucount %d, arcount %d\n",
@@ -479,21 +574,21 @@ ns_resp(msg, msglen)
if (ancount == 1 || (ancount == 0 && aucount > 0)) {
c = aucount;
do {
- if (tp - msg >= msglen) {
+ if (tp >= eom) {
formerrmsg = outofDataAnswer;
goto formerr;
}
- n = dn_skipname(tp, msg + msglen);
+ n = dn_skipname(tp, eom);
if (n <= 0) {
formerrmsg = skipnameFailedAnswer;
goto formerr;
}
tp += n; /* name */
GETSHORT(i, tp); /* type */
- tp += INT16SZ; /* class */
- tp += INT32SZ; /* ttl */
+ tp += INT16SZ; /* class */
+ tp += INT32SZ; /* ttl */
GETSHORT(count, tp); /* dlen */
- if (tp - msg > msglen - count) {
+ if (tp + count > eom) {
formerrmsg = dlenOverrunAnswer;
goto formerr;
}
@@ -522,38 +617,49 @@ ns_resp(msg, msglen)
}
if (qp->q_flags & Q_ZSERIAL) {
- if ((hp->aa)
- && (ancount != 0)
- && (hp->rcode == NOERROR)
- && (type == T_SOA)
- && ((class == C_IN) || (class == C_HS))
- ) { /* XXX - should check name, too */
+ if (hp->aa && ancount > 0 && hp->rcode == NOERROR &&
+ qtype == T_SOA && ((qclass == C_IN) || (qclass == C_HS))) {
int n;
- u_int16_t dlen;
+ u_int16_t type, class, dlen;
u_int32_t serial;
u_char *tp = cp;
- if (0 >= (n = dn_skipname(tp, msg + msglen))) {
- formerrmsg = skipnameFailedAnswer;
+ n = dn_expand(msg, eom, tp, name, sizeof name);
+ if (n < 0) {
+ formerrmsg = expandFailedAnswer;
goto formerr;
}
- tp += n /* name */
- + INT16SZ /* type */
- + INT16SZ /* class */
- + INT32SZ; /* ttl */
+ tp += n; /* name */
+ GETSHORT(type, tp); /* type */
+ GETSHORT(class, tp); /* class */
+ tp += INT32SZ; /* ttl */
GETSHORT(dlen, tp); /* dlen */
+ if (tp >= eom) {
+ formerrmsg = outofDataAnswer;
+ goto formerr;
+ }
+ if (strcasecmp(qname, name) ||
+ qtype != type ||
+ qclass != class) {
+ char msgbuf[MAXDNAME*2];
- if (dlen < (5 * INT32SZ)) {
+ sprintf(msgbuf,
+ "qserial answer mismatch (%s %s %s)",
+ name, p_class(class), p_type(type));
+ formerrmsg = msgbuf;
+ goto formerr;
+ }
+ if ((u_int)dlen < (5 * INT32SZ)) {
formerrmsg = dlenUnderrunAnswer;
goto formerr;
}
- if (0 >= (n = dn_skipname(tp, msg + msglen))) {
+ if (0 >= (n = dn_skipname(tp, eom))) {
formerrmsg = skipnameFailedAnswer;
goto formerr;
}
tp += n; /* mname */
- if (0 >= (n = dn_skipname(tp, msg + msglen))) {
+ if (0 >= (n = dn_skipname(tp, eom))) {
formerrmsg = skipnameFailedAnswer;
goto formerr;
}
@@ -585,7 +691,7 @@ ns_resp(msg, msglen)
* DON'T do this now, as it will requery if data are already
* in the cache (maybe later with negative caching).
*/
- if (hp->qdcount && type == T_CNAME && c == 0 && hp->rcode == NOERROR
+ if (type == T_CNAME && c == 0 && hp->rcode == NOERROR
&& !(qp->q_flags & Q_SYSTEM)) {
dprintf(4, (ddt, "resp: leaving, no CNAME\n"));
@@ -603,6 +709,8 @@ ns_resp(msg, msglen)
else
dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS;
count = c;
+ if (qp->q_flags & Q_PRIMING)
+ dbflags |= DB_PRIMING;
if (hp->tc) {
count -= arcount; /* truncation had to affect this */
if (!arcount) {
@@ -620,7 +728,7 @@ ns_resp(msg, msglen)
old_ancount = ancount;
for (i = 0; i < count; i++) {
int VCode;
- if (tempcp >= msg + msglen) {
+ if (tempcp >= eom) {
free((char *)validatelist);
formerrmsg = outofDataFinal;
goto formerr;
@@ -644,31 +752,34 @@ ns_resp(msg, msglen)
*/
n = update_msg(msg, &msglen, validatelist, count);
free((char *)validatelist);
- if (n < 0)
+ if (n < 0) {
+ formerrmsg = editFailed;
goto formerr;
+ }
count -= lesscount;
- if (old_ancount && !hp->ancount) {
+ ancount = ntohs(hp->ancount);
+ if (old_ancount && !ancount) {
/* We lost all the answers */
dprintf(1, (ddt, "validate count -> 0"));
return;
}
- ancount = ntohs(hp->ancount);
#endif
for (i = 0; i < count; i++) {
struct databuf *ns3;
u_char cred;
- if (cp >= msg + msglen) {
+ if (cp >= eom) {
formerrmsg = outofDataFinal;
goto formerr;
}
- if (i < ancount) {
+ if (i < ancount)
cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER;
- } else {
- cred = DB_C_ADDITIONAL;
- }
+ else
+ cred = (qp->q_flags & Q_PRIMING)
+ ? DB_C_ANSWER
+ : DB_C_ADDITIONAL;
ns3 = 0;
n = doupdate(msg, msglen, cp, 0, &ns3, dbflags, cred);
if (n < 0) {
@@ -698,14 +809,25 @@ ns_resp(msg, msglen)
check_root();
dprintf(3, (ddt, "resp: leaving, SYSQUERY ancount %d\n",
ancount));
+#ifdef BIND_NOTIFY
+ if (qp->q_notifyzone != DB_Z_CACHE) {
+ struct zoneinfo *zp = &zones[qp->q_notifyzone];
+
+ /*
+ * Clear this first since sysnotify() might set it.
+ */
+ qp->q_notifyzone = DB_Z_CACHE;
+ sysnotify(zp->z_origin, zp->z_class, T_SOA);
+ }
+#endif
qremove(qp);
-#ifdef DATUMREFCNT
+#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
return;
}
- if (cp > msg + msglen) {
+ if (cp > eom) {
formerrmsg = outofDataAFinal;
goto formerr;
}
@@ -715,13 +837,13 @@ ns_resp(msg, msglen)
* sort them appropriately for the local context.
*/
if (ancount > 1 && (lp = local(&qp->q_from)) != NULL)
- sort_response(tp, ancount, lp, msg + msglen);
+ sort_response(tp, ancount, lp, eom);
/*
* An answer to a T_ANY query or a successful answer to a
* regular query with no indirection, then just return answer.
*/
- if ((hp->qdcount && type == T_ANY && ancount) ||
+ if ((qtype == T_ANY && ancount) ||
(!cname && !qp->q_cmsglen && ancount)) {
dprintf(3, (ddt, "resp: got as much answer as there is\n"));
goto return_msg;
@@ -732,7 +854,7 @@ ns_resp(msg, msglen)
*/
if (!ancount &&
(!nscount || hp->rcode == NXDOMAIN) &&
- (hp->aa || fwd || class == C_ANY)) {
+ (hp->aa || fwd || qclass == C_ANY)) {
/* we have an authoritative NO */
dprintf(3, (ddt, "resp: leaving auth NO\n"));
if (qp->q_cmsglen) {
@@ -784,8 +906,8 @@ ns_resp(msg, msglen)
cp += n + QFIXEDSZ;
buflen = sizeof(newmsg) - (cp - newmsg);
-try_again:
- dprintf(1, (ddt, "resp: nlookup(%s) type=%d\n", dname, type));
+ try_again:
+ dprintf(1, (ddt, "resp: nlookup(%s) qtype=%d\n", dname, qtype));
fname = "";
htp = hashtab; /* lookup relative to root */
np = nlookup(dname, &htp, &fname, 0);
@@ -796,13 +918,13 @@ try_again:
foundname++;
count = cp - newmsg;
- n = finddata(np, class, type, hp, &dname, &buflen, &count);
+ n = finddata(np, qclass, qtype, hp, &dname, &buflen, &count);
if (n == 0)
goto fetch_ns; /* NO data available */
cp += n;
buflen -= n;
hp->ancount += count;
- if (fname != dname && type != T_CNAME && type != T_ANY) {
+ if (fname != dname && qtype != T_CNAME && qtype != T_ANY) {
cname++;
goto try_again;
}
@@ -812,7 +934,7 @@ try_again:
"resp: foundname=%d, count=%d, founddata=%d, cname=%d\n",
foundname, count, founddata, cname));
-fetch_ns:
+ fetch_ns:
hp->ancount = htons(hp->ancount);
/*
* Look for name servers to refer to and fill in the authority
@@ -822,13 +944,13 @@ fetch_ns:
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- switch (findns(&np, class, nsp, &count, 0)) {
+ switch (findns(&np, qclass, nsp, &count, 0)) {
case NXDOMAIN: /* shouldn't happen */
dprintf(3, (ddt, "req: leaving (%s, rcode %d)\n",
dname, hp->rcode));
if (!foundname)
hp->rcode = NXDOMAIN;
- if (class != C_ANY) {
+ if (qclass != C_ANY) {
hp->aa = 1;
/* XXX: should return SOA if founddata == 0,
* but old named's are confused by an SOA
@@ -864,40 +986,45 @@ fetch_ns:
* to iterate to try and get it. First, infinite loop avoidance.
*/
if (qp->q_nqueries++ > MAXQUERIES) {
- dprintf(1,
- (ddt,
- "resp: MAXQUERIES exceeded (%s, class %d, type %d)\n",
- dname, class, type
- )
- );
- syslog(LOG_NOTICE,
- "MAXQUERIES exceeded, possible data loop in resolving (%s)",
- dname);
+ dprintf(1, (ddt, "resp: MAXQUERIES exceeded (%s %s %s)\n",
+ dname, p_class(qclass), p_type(qtype)));
+ syslog(LOG_INFO,
+ "MAXQUERIES exceeded, possible data loop in resolving (%s)",
+ dname);
goto servfail;
}
/* Reset the query control structure */
#ifdef DATUMREFCNT
- for (i = 0 ; i < qp->q_naddr ; i++) {
- if ((--(qp->q_addr[i].ns->d_rcnt))) {
- dprintf(1 ,(ddt, "ns_resp: ns %s rcnt %d\n",
- qp->q_addr[i].ns->d_data,
- qp->q_addr[i].ns->d_rcnt));
- } else {
- dprintf(1 ,(ddt, "ns_resp: ns %s rcnt %d delayed\n",
- qp->q_addr[i].ns->d_data,
- qp->q_addr[i].ns->d_rcnt));
- free((char*)qp->q_addr[i].ns);
+ /* XXX - this code should be shared with qfree()'s similar logic. */
+ for (i = 0; (u_int)i < qp->q_naddr; i++) {
+ static const char freed[] = "freed", busy[] = "busy";
+ const char *result;
+
+ if (qp->q_addr[i].ns != NULL) {
+ if ((--(qp->q_addr[i].ns->d_rcnt)))
+ result = busy;
+ else {
+ free((char*)qp->q_addr[i].ns);
+ result = freed;
+ }
+ dprintf(1, (ddt, "ns_resp: ns %s rcnt %d (%s)\n",
+ qp->q_addr[i].ns->d_data,
+ qp->q_addr[i].ns->d_rcnt,
+ result));
}
- if ((--(qp->q_addr[i].nsdata->d_rcnt))) {
- dprintf(1 ,(ddt, "ns_resp: nsdata %08.8X rcnt %d\n",
- *(int32_t *)(qp->q_addr[i].nsdata->d_data),
- qp->q_addr[i].nsdata->d_rcnt));
- } else {
- dprintf(1 ,(ddt, "ns_resp: nsdata %08.8X rcnt %d delayed\n",
- *(int32_t *)(qp->q_addr[i].nsdata->d_data),
- qp->q_addr[i].nsdata->d_rcnt));
- free((char*)qp->q_addr[i].nsdata);
+ if (qp->q_addr[i].nsdata != NULL) {
+ if ((--(qp->q_addr[i].nsdata->d_rcnt)))
+ result = busy;
+ else {
+ free((char*)qp->q_addr[i].nsdata);
+ result = freed;
+ }
+ dprintf(1, (ddt,
+ "ns_resp: nsdata %08.8X rcnt %d (%s)\n",
+ *(int32_t *)(qp->q_addr[i].nsdata->d_data),
+ qp->q_addr[i].nsdata->d_rcnt,
+ result));
}
}
#endif
@@ -917,7 +1044,7 @@ fetch_ns:
goto return_newmsg;
goto servfail;
}
- for (n = 0; n < qp->q_naddr; n++)
+ for (n = 0; (u_int)n < qp->q_naddr; n++)
qp->q_addr[n].stime.tv_sec = 0;
if (!qp->q_fwd)
qp->q_addr[0].stime = tt;
@@ -933,39 +1060,43 @@ fetch_ns:
if (qp->q_msg)
(void) free(qp->q_msg);
if ((qp->q_msg = (u_char *)malloc(BUFSIZ)) == NULL) {
- dprintf(1, (ddt, "resp: malloc error\n"));
+ syslog(LOG_NOTICE, "resp: malloc error\n");
+ goto servfail;
+ }
+ n = res_mkquery(QUERY, dname, qclass, qtype,
+ NULL, 0, NULL, qp->q_msg, BUFSIZ);
+ if (n < 0) {
+ syslog(LOG_INFO, "resp: res_mkquery(%s) failed",
+ dname);
goto servfail;
}
- qp->q_msglen = res_mkquery(QUERY, dname, class,
- type, NULL, 0, NULL,
- qp->q_msg, BUFSIZ);
+ qp->q_msglen = n;
hp = (HEADER *) qp->q_msg;
hp->rd = 0;
} else
- hp = (HEADER *)qp->q_msg;
- hp->id = qp->q_nsid = htons((u_int16_t)++nsid);
+ hp = (HEADER *) qp->q_msg;
+ hp->id = qp->q_nsid = htons(nsid_next());
if (qp->q_fwd)
hp->rd = 1;
unsched(qp);
schedretry(qp, retrytime(qp));
nsa = Q_NEXTADDR(qp, 0);
- dprintf(1, (ddt, "resp: forw -> [%s].%d ds=%d nsid=%d id=%d %dms\n",
- inet_ntoa(nsa->sin_addr),
- ntohs(nsa->sin_port), ds,
+ dprintf(1, (ddt, "resp: forw -> %s ds=%d nsid=%d id=%d %dms\n",
+ inet_etoa(nsa), ds,
ntohs(qp->q_nsid), ntohs(qp->q_id),
(qp->q_addr[0].nsdata != NULL)
? qp->q_addr[0].nsdata->d_nstime
: (-1)));
#ifdef DEBUG
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(qp->q_msg, qp->q_msglen, ddt);
#endif
- if (sendto(ds, qp->q_msg, qp->q_msglen, 0,
+ if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
(struct sockaddr *)nsa,
sizeof(struct sockaddr_in)) < 0) {
if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
- syslog(LOG_NOTICE, "ns_resp: sendto([%s].%d): %m",
- inet_ntoa(nsa->sin_addr), ntohs(nsa->sin_port));
+ syslog(LOG_INFO, "ns_resp: sendto(%s): %m",
+ inet_etoa(nsa));
nameserIncr(nsa->sin_addr, nssSendtoErr);
}
hp->rd = 0; /* leave set to 0 for dup detection */
@@ -977,37 +1108,25 @@ fetch_ns:
#endif
return;
-formerr:
- dprintf(3, (ddt,
- "FORMERR resp() from [%s].%d size err %d, msglen %d\n",
- inet_ntoa(from_addr.sin_addr),
- ntohs(from_addr.sin_port),
- cp - msg, msglen));
+ formerr:
if (!haveComplained((char*)from_addr.sin_addr.s_addr,
- (char*)dhash((u_char *)formerrmsg,
- strlen(formerrmsg)
- )
- )
- ) {
- syslog(LOG_INFO, "Malformed response from [%s].%d (%s)\n",
- inet_ntoa(from_addr.sin_addr),
- ntohs(from_addr.sin_port),
- formerrmsg);
- }
+ (char*)nhash(formerrmsg)))
+ syslog(LOG_INFO, "Malformed response from %s (%s)\n",
+ inet_etoa(&from_addr), formerrmsg);
nameserIncr(from_addr.sin_addr, nssSentFErr);
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
return;
-return_msg:
+ return_msg:
nameserIncr(from_addr.sin_addr, nssRcvdFwdR);
nameserIncr(qp->q_from.sin_addr, nssSentFwdR);
/* The "standard" return code */
hp->qr = 1;
hp->id = qp->q_id;
hp->rd = 1;
- hp->ra = 1;
+ hp->ra = (NoRecurse == 0);
(void) send_msg(msg, msglen, qp);
qremove(qp);
#ifdef DATUMREFCNT
@@ -1015,17 +1134,22 @@ return_msg:
#endif
return;
-return_newmsg:
+ return_newmsg:
nameserIncr(qp->q_from.sin_addr, nssSentAns);
- if (addcount) {
- n = doaddinfo(hp, cp, buflen);
- cp += n;
- buflen -= n;
- }
+
+#ifdef XSTATS
+ if (!hp->aa)
+ nameserIncr(qp->q_from.sin_addr, nssSentNaAns);
+ if (hp->rcode == NXDOMAIN)
+ nameserIncr(qp->q_from.sin_addr, nssSentNXD);
+#endif
+ n = doaddinfo(hp, cp, buflen);
+ cp += n;
+ buflen -= n;
hp->qr = 1;
hp->id = qp->q_id;
hp->rd = 1;
- hp->ra = 1;
+ hp->ra = (NoRecurse == 0);
(void) send_msg(newmsg, cp - newmsg, qp);
qremove(qp);
#ifdef DATUMREFCNT
@@ -1033,14 +1157,14 @@ return_newmsg:
#endif
return;
-servfail:
+ servfail:
nameserIncr(qp->q_from.sin_addr, nssSentFail);
hp = (HEADER *)(cname ? qp->q_cmsg : qp->q_msg);
hp->rcode = SERVFAIL;
+ hp->qr = 1;
hp->id = qp->q_id;
hp->rd = 1;
- hp->ra = 1;
- hp->qr = 1;
+ hp->ra = (NoRecurse == 0);
(void) send_msg((u_char *)hp, (cname ? qp->q_cmsglen : qp->q_msglen),
qp);
qremove(qp);
@@ -1074,8 +1198,8 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
int zonenum;
#endif
- dprintf(3, (ddt, "doupdate(zone %d, savens %x, flags %x)\n",
- zone, savens, flags));
+ dprintf(3, (ddt, "doupdate(zone %d, savens %#lx, flags %#lx)\n",
+ zone, (u_long)savens, (u_long)flags));
cp = rrp;
if ((n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname)) < 0) {
@@ -1109,6 +1233,7 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
case T_X25:
case T_ISDN:
case T_NSAP:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -1188,6 +1313,33 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
cp1 = data;
break;
+ case T_PX:
+ /* grab preference */
+ bcopy(cp, data, INT16SZ);
+ cp1 = data + INT16SZ;
+ cp += INT16SZ;
+
+ /* get MAP822 name */
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1,
+ sizeof data - INT16SZ);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += (n = strlen((char *)cp1) + 1);
+ n1 = sizeof(data) - n;
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += strlen((char *)cp1) + 1;
+ n = cp1 - data;
+ cp1 = data;
+ break;
+
default:
dprintf(3, (ddt, "unknown type %d\n", type));
return ((cp - rrp) + dlen);
@@ -1196,7 +1348,7 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
dprintf(1, (ddt,
"update type %d: %d bytes is too much data\n",
type, n));
- hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */
+ hp->rcode = FORMERR;
return (-1);
}
@@ -1379,19 +1531,17 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
if (!haveComplained((char*)from_addr.sin_addr.s_addr,
"bogus root NS"))
syslog(LOG_NOTICE,
- "bogus root NS %s rcvd from [%s] on query for \"%s\"",
- data, inet_ntoa(from_addr.sin_addr),
- qname);
+ "bogus root NS %s rcvd from %s on query for \"%s\"",
+ data, inet_etoa(&from_addr), qname);
return (cp - rrp);
}
#ifdef BOGUSNS
if (bogusns) {
if (!haveComplained((char*)from_addr.sin_addr.s_addr,
"bogus nonroot NS"))
- syslog(LOG_NOTICE,
- "bogus nonroot NS %s rcvd from [%s] on query for \"%s\"",
- data, inet_ntoa(from_addr.sin_addr),
- qname);
+ syslog(LOG_INFO,
+ "bogus nonroot NS %s rcvd from %s on query for \"%s\"",
+ data, inet_etoa(&from_addr), qname);
return (cp - rrp);
}
#endif
@@ -1405,9 +1555,9 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
if ((n = db_update(dname, dp, dp, flags, hashtab)) != OK) {
#ifdef DEBUG
if (debug && (n != DATAEXISTS))
- fprintf(ddt,"update failed (%d)\n", n);
+ fprintf(ddt, "update failed (%d)\n", n);
else if (debug >= 3)
- fprintf(ddt,"update failed (DATAEXISTS)\n");
+ fprintf(ddt, "update failed (DATAEXISTS)\n");
#endif
free((char *)dp);
} else if (type == T_NS && savens != NULL)
@@ -1425,39 +1575,43 @@ send_msg(msg, msglen, qp)
return (1);
#ifdef DEBUG
if (debug) {
- fprintf(ddt,"send_msg -> [%s] (%s %d %d) id=%d\n",
- inet_ntoa(qp->q_from.sin_addr),
+ fprintf(ddt,"send_msg -> %s (%s %d) id=%d\n",
+ inet_etoa(&qp->q_from),
qp->q_stream == QSTREAM_NULL ? "UDP" : "TCP",
qp->q_stream == QSTREAM_NULL ? qp->q_dfd
: qp->q_stream->s_rfd,
- ntohs(qp->q_from.sin_port),
ntohs(qp->q_id));
}
if (debug>4) {
struct qinfo *tqp;
- for (tqp = qhead; tqp!=QINFO_NULL; tqp = tqp->q_link) {
- fprintf(ddt, "qp %x q_id: %d q_nsid: %d q_msglen: %d ",
- tqp, tqp->q_id,tqp->q_nsid,tqp->q_msglen);
- fprintf(ddt,"q_naddr: %d q_curaddr: %d\n", tqp->q_naddr,
- tqp->q_curaddr);
- fprintf(ddt,"q_next: %x q_link: %x\n", qp->q_next,
- qp->q_link);
+ for (tqp = nsqhead; tqp!=QINFO_NULL; tqp = tqp->q_link) {
+ fprintf(ddt,
+ "qp %#lx q_id: %d q_nsid: %d q_msglen: %d ",
+ (u_long)tqp, tqp->q_id,
+ tqp->q_nsid, tqp->q_msglen);
+ fprintf(ddt,
+ "q_naddr: %d q_curaddr: %d\n",
+ tqp->q_naddr, tqp->q_curaddr);
+ fprintf(ddt, "q_next: %#lx q_link: %#lx\n",
+ (u_long)qp->q_next, (u_long)qp->q_link);
}
}
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, msglen, ddt);
#endif /* DEBUG */
if (qp->q_stream == QSTREAM_NULL) {
- if (sendto(qp->q_dfd, msg, msglen, 0,
+ if (sendto(qp->q_dfd, (char*)msg, msglen, 0,
(struct sockaddr *)&qp->q_from,
sizeof(qp->q_from)) < 0) {
if (!haveComplained((char*)qp->q_from.sin_addr.s_addr,
sendtoStr))
- syslog(LOG_NOTICE,
- "send_msg: sendto([%s].%d): %m",
- inet_ntoa(qp->q_from.sin_addr),
- ntohs(qp->q_from.sin_port));
+#if defined(SPURIOUS_ECONNREFUSED)
+ if (errno != ECONNREFUSED)
+#endif
+ syslog(LOG_INFO,
+ "send_msg: sendto(%s): %m",
+ inet_etoa(&qp->q_from));
nameserIncr(qp->q_from.sin_addr, nssSendtoErr);
return (1);
}
@@ -1484,7 +1638,7 @@ prime(class, type, oqp)
sizeof(dname)) < 0)
return;
dprintf(2, (ddt, "prime: %s\n", dname));
- (void) sysquery(dname, class, type, NULL, 0);
+ (void) sysquery(dname, class, type, NULL, 0, QUERY);
}
#endif
@@ -1496,7 +1650,7 @@ prime_cache()
dprintf(1, (ddt, "prime_cache: priming = %d\n", priming));
if (!priming && fcachetab->h_tab[0] != NULL && !forward_only) {
priming++;
- if ((qp = sysquery("", C_IN, T_NS, NULL, 0)) == NULL)
+ if (!(qp = sysquery("", C_IN, T_NS, NULL, 0, QUERY)))
priming = 0;
else
qp->q_flags |= (Q_SYSTEM | Q_PRIMING);
@@ -1505,12 +1659,156 @@ prime_cache()
return;
}
+#ifdef BIND_NOTIFY
+struct notify *
+findNotifyPeer(zp, ina)
+ const struct zoneinfo *zp;
+ struct in_addr ina;
+{
+ register struct notify *ap;
+
+ for (ap = zp->z_notifylist; ap; ap = ap->next)
+ if (ap->addr.s_addr == ina.s_addr)
+ break;
+ return (ap);
+}
+
+/* sysnotify(dname, class, type)
+ * cause a NOTIFY request to be sysquery()'d to each secondary server
+ * of the zone that "dname" is within.
+ */
+void
+sysnotify(dname, class, type)
+ const char *dname;
+ int class, type;
+{
+ char *soaname, *zname;
+ const char *fname;
+ register struct databuf *dp;
+ struct in_addr nss[NSMAX];
+ int nns, na, zn, nsc;
+ struct hashbuf *htp;
+ struct zoneinfo *zp;
+ struct notify *ap;
+ struct namebuf *np;
+
+ htp = hashtab;
+ np = nlookup(dname, &htp, &fname, 0);
+ if (!np)
+ panic(-1, "sysnotify: can't find name");
+ zn = findMyZone(np, class);
+ if (zn == DB_Z_CACHE)
+ panic(-1, "sysnotify: not auth zone");
+ zp = &zones[zn];
+ if (zp->z_type != Z_PRIMARY && zp->z_type != Z_SECONDARY)
+ panic(-1, "sysnotify: not pri/sec");
+ zname = zp->z_origin;
+/*
+**DBG** syslog(LOG_INFO, "sysnotify: found \"%s\" in \"%s\" (%s)",
+**DBG** dname, zname, zoneTypeString(zp));
+*/
+ nns = na = 0;
+ /*
+ * Send to recent AXFR peers.
+ */
+ for (ap = zp->z_notifylist; ap; ap = ap->next) {
+ if (tt.tv_sec - ap->last >= zp->z_refresh) {
+ /* XXX - probably should do GC here. */
+ continue;
+ }
+ nss[0] = ap->addr;
+ nsc = 1;
+ nns++;
+ na++;
+ sysquery(dname, class, T_SOA, nss, nsc, NS_NOTIFY_OP);
+ }
+ if (zp->z_type != Z_PRIMARY)
+ goto done;
+ /*
+ * Master.
+ */
+ htp = hashtab;
+ np = nlookup(zname, &htp, &fname, 0);
+ if (!np)
+ panic(-1, "sysnotify: found name but not zone");
+ soaname = NULL;
+ for (dp = np->n_data; dp; dp = dp->d_next) {
+ if (!dp->d_zone || !match(dp, class, T_SOA))
+ continue;
+ if (soaname) {
+ syslog(LOG_NOTICE, "multiple SOA's for zone \"%s\"?",
+ zname);
+ return;
+ }
+ soaname = (char *) dp->d_data;
+ }
+ if (!soaname) {
+ syslog(LOG_NOTICE, "no SOA found for zone \"%s\"", zname);
+ return;
+ }
+
+ for (dp = np->n_data; dp; dp = dp->d_next) {
+ register struct databuf *adp;
+ struct namebuf *anp;
+
+ if (!dp->d_zone || !match(dp, class, T_NS))
+ continue;
+ /* NS RDATA is server name. */
+ if (strcasecmp((char*)dp->d_data, soaname) == 0)
+ continue;
+ htp = hashtab;
+ anp = nlookup((char*)dp->d_data, &htp, &fname, 0);
+ if (!anp) {
+ syslog(LOG_INFO, "sysnotify: can't nlookup(%s)?",
+ (char*)dp->d_data);
+ continue;
+ }
+ nsc = 0;
+ for (adp = anp->n_data; adp; adp = adp->d_next) {
+ struct in_addr ina;
+ if (!match(adp, class, T_A))
+ continue;
+ ina = data_inaddr(adp->d_data);
+ /* Don't send to things we handled above. */
+ ap = findNotifyPeer(zp, ina);
+ if (ap && tt.tv_sec - ap->last < zp->z_refresh)
+ goto nextns;
+ if (nsc < NSMAX)
+ nss[nsc++] = ina;
+ } /*next A*/
+ if (nsc == 0) {
+ struct qinfo *qp;
+
+ qp = sysquery((char*)dp->d_data, /*NS name*/
+ class, /*XXX: C_IN?*/
+ T_A, 0, 0, QUERY);
+ if (qp)
+ qp->q_notifyzone = zn;
+ continue;
+ }
+ (void) sysquery(dname, class, T_SOA, nss, nsc, NS_NOTIFY_OP);
+ nns++;
+ na += nsc;
+ nextns:;
+ } /*next NS*/
+ done:
+ if (nns || na) {
+ char tmp[MAXDNAME*2];
+
+ /* Many syslog()'s only take 5 args. */
+ sprintf(tmp, "%s %s %s", dname, p_class(class), p_type(type));
+ syslog(LOG_INFO, "Sent NOTIFY for \"%s\" (%s); %d NS, %d A",
+ tmp, zname, nns, na);
+ }
+}
+#endif /*BIND_NOTIFY*/
+
struct qinfo *
-sysquery(dname, class, type, nss, nsc)
- char *dname;
+sysquery(dname, class, type, nss, nsc, opcode)
+ const char *dname;
int class, type;
struct in_addr *nss;
- int nsc;
+ int nsc, opcode;
{
register struct qinfo *qp, *oqp;
register HEADER *hp;
@@ -1518,14 +1816,14 @@ sysquery(dname, class, type, nss, nsc)
struct databuf *nsp[NSMAX];
struct hashbuf *htp;
struct sockaddr_in *nsa;
- char *fname;
- int count;
+ const char *fname;
+ int n, count;
#ifdef DATUMREFCNT
nsp[0] = NULL;
#endif
- dprintf(3, (ddt, "sysquery(%s, %d, %d, 0x%x, %d)\n",
- dname, class, type, nss, nsc));
+ dprintf(3, (ddt, "sysquery(%s, %d, %d, %#lx, %d)\n",
+ dname, class, type, (u_long)nss, nsc));
qp = qnew();
if (nss && nsc) {
@@ -1535,23 +1833,24 @@ sysquery(dname, class, type, nss, nsc)
if (priming && dname[0] == '\0') {
np = NULL;
} else if ((np = nlookup(dname, &htp, &fname, 1)) == NULL) {
- dprintf(1, (ddt,
- "sysquery: nlookup error on %s?\n",
- dname));
+ syslog(LOG_INFO, "sysquery: nlookup error on %s?",
+ dname);
+ err1:
qfree(qp);
- return (0);
+ return (NULL);
}
- switch (findns(&np, class, nsp, &count, 0)) {
+ n = findns(&np, class, nsp, &count, 0);
+ switch (n) {
case NXDOMAIN:
case SERVFAIL:
- dprintf(1, (ddt,
- "sysquery: findns error on %s?\n", dname));
- qfree(qp);
+ syslog(LOG_DEBUG, "sysquery: findns error (%d) on %s?",
+ n, dname);
+ err2:
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return (0);
+ goto err1;
}
}
@@ -1569,33 +1868,39 @@ sysquery(dname, class, type, nss, nsc)
#endif /* LAME_DELEGATION */
if ((qp->q_msg = (u_char *)malloc(BUFSIZ)) == NULL) {
- qfree(qp);
-#ifdef DATUMREFCNT
- free_nsp(nsp);
-#endif
- return (0);
+ syslog(LOG_NOTICE, "sysquery: malloc failed");
+ goto err2;
+ }
+ n = res_mkquery(opcode, dname, class,
+ type, NULL, 0, NULL,
+ qp->q_msg, BUFSIZ);
+ if (n < 0) {
+ syslog(LOG_INFO, "sysquery: res_mkquery(%s) failed", dname);
+ goto err2;
}
- qp->q_msglen = res_mkquery(QUERY, dname, class,
- type, NULL, 0, NULL,
- qp->q_msg, BUFSIZ);
+ qp->q_msglen = n;
hp = (HEADER *) qp->q_msg;
- hp->id = qp->q_nsid = htons((u_int16_t)++nsid);
+ hp->id = qp->q_nsid = htons(nsid_next());
hp->rd = (qp->q_fwd ? 1 : 0);
/* First check for an already pending query for this data */
- for (oqp = qhead; oqp != QINFO_NULL; oqp = oqp->q_link) {
+ for (oqp = nsqhead; oqp != QINFO_NULL; oqp = oqp->q_link) {
if ((oqp != qp)
&& (oqp->q_msglen == qp->q_msglen)
&& bcmp((char *)oqp->q_msg+2,
qp->q_msg+2,
qp->q_msglen-2) == 0
) {
- dprintf(3, (ddt, "sysquery: duplicate\n"));
- qfree(qp);
-#ifdef DATUMREFCNT
- free_nsp(nsp);
-#endif
- return (0);
+#ifdef BIND_NOTIFY
+ /* XXX - need fancier test to suppress duplicate
+ * NOTIFYs to the same server (compare nss?)
+ */
+ if (opcode != NS_NOTIFY_OP)
+#endif /*BIND_NOTIFY*/
+ {
+ dprintf(3, (ddt, "sysquery: duplicate\n"));
+ goto err2;
+ }
}
}
@@ -1616,20 +1921,19 @@ sysquery(dname, class, type, nss, nsc)
}
qp->q_naddr = nsc;
} else {
- if ((count = nslookup(nsp, qp, dname, "sysquery")) <= 0) {
- if (count < 0) {
- dprintf(1, (ddt,
- "sysquery: nslookup reports danger\n"));
- } else {
- dprintf(1, (ddt,
- "sysquery: no addrs found for NS's\n"));
+ count = nslookup(nsp, qp, dname, "sysquery");
+ if (count <= 0) {
+ if (count < 0)
+ syslog(LOG_INFO,
+ "sysquery: nslookup reports danger (%s)",
+ dname);
+ else
+ /* "." domain gets LOG_WARNING here. */
+ syslog(dname[0] ? LOG_INFO : LOG_WARNING,
+ "sysquery: no addrs found for NS (%s)",
+ dname);
+ goto err2;
}
- qfree(qp);
-#ifdef DATUMREFCNT
- free_nsp(nsp);
-#endif
- return (0);
- }
}
schedretry(qp, retrytime(qp));
@@ -1638,21 +1942,20 @@ sysquery(dname, class, type, nss, nsc)
nsa = Q_NEXTADDR(qp, 0);
dprintf(1, (ddt,
- "sysquery: send -> [%s].%d dfd=%d nsid=%d id=%d retry=%ld\n",
- inet_ntoa(nsa->sin_addr),
- ntohs(nsa->sin_port), qp->q_dfd,
+ "sysquery: send -> %s dfd=%d nsid=%d id=%d retry=%ld\n",
+ inet_etoa(nsa), qp->q_dfd,
ntohs(qp->q_nsid), ntohs(qp->q_id),
qp->q_time));
#ifdef DEBUG
if (debug >= 10)
- fp_query(qp->q_msg, ddt);
+ fp_nquery(qp->q_msg, qp->q_msglen, ddt);
#endif
- if (sendto(qp->q_dfd, qp->q_msg, qp->q_msglen, 0,
+ if (sendto(qp->q_dfd, (char*)qp->q_msg, qp->q_msglen, 0,
(struct sockaddr *)nsa,
sizeof(struct sockaddr_in)) < 0) {
if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
- syslog(LOG_NOTICE, "sysquery: sendto([%s].%d): %m",
- inet_ntoa(nsa->sin_addr), ntohs(nsa->sin_port));
+ syslog(LOG_INFO, "sysquery: sendto(%s): %m",
+ inet_etoa(nsa));
nameserIncr(nsa->sin_addr, nssSendtoErr);
}
nameserIncr(nsa->sin_addr, nssSentSysQ);
@@ -1678,7 +1981,7 @@ check_root()
if (np->n_dname[0] == '\0')
break;
if (np == NULL) {
- syslog(LOG_ERR, "check_root: Can't find root!\n");
+ syslog(LOG_NOTICE, "check_root: Can't find root!\n");
return;
}
for (dp = np->n_data; dp != NULL; dp = dp->d_next)
@@ -1686,9 +1989,9 @@ check_root()
count++;
dprintf(1, (ddt, "%d root servers\n", count));
if (count < MINROOTS) {
- syslog(LOG_WARNING,
+ syslog(LOG_NOTICE,
"check_root: %d root servers after query to root server < min",
- count);
+ count);
return;
}
pdp = NULL;
@@ -1719,7 +2022,7 @@ check_ns()
struct hashbuf *htp;
char *dname;
int found_arr;
- char *fname;
+ const char *fname;
time_t curtime;
dprintf(2, (ddt, "check_ns()\n"));
@@ -1738,9 +2041,9 @@ check_ns()
tnp = nlookup(dname, &htp, &fname, 0);
if (tnp == NULL || fname != dname) {
dprintf(3, (ddt,
- "check_ns: %s: not found %s %x\n",
- dname, fname, tnp));
- sysquery(dname, dp->d_class, T_A, NULL, 0);
+ "check_ns: %s: not found %s %#lx\n",
+ dname, fname, (u_long)tnp));
+ sysquery(dname, dp->d_class, T_A, NULL, 0, QUERY);
continue;
}
/* look for name server addresses */
@@ -1762,7 +2065,7 @@ check_ns()
found_arr++;
}
if (!found_arr)
- (void) sysquery(dname, dp->d_class, T_A, NULL, 0);
+ sysquery(dname, dp->d_class, T_A, NULL, 0, QUERY);
}
}
}
@@ -1770,7 +2073,7 @@ check_ns()
/* int findns(npp, class, nsp, countp, flag)
* Find NS' or an SOA
* npp, class:
- * dname whose least-superior NS is wanted
+ * dname whose most enclosing NS is wanted
* nsp, countp:
* result array and count; array will also be NULL terminated
* flag:
@@ -1802,7 +2105,7 @@ findns(npp, class, nsp, countp, flag)
else
htp = hashtab;
-try_again:
+ try_again:
if (htp == fcachetab)
needs_prime_cache = 1;
while (np == NULL && htp != NULL) {
@@ -1814,13 +2117,19 @@ try_again:
htp = (htp == hashtab ? fcachetab : NULL); /* Fallback */
}
while (np != NULL) {
- dprintf(5, (ddt, "findns: np 0x%x '%s'\n", np, np->n_dname));
+ dprintf(5, (ddt, "findns: np %#lx '%s'\n",
+ (u_long)np, np->n_dname));
/* Look first for SOA records. */
#ifdef ADDAUTH
if (!flag)
#endif
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
- if (dp->d_zone != 0 && match(dp, class, T_SOA)) {
+ if (dp->d_zone != 0 &&
+#ifdef PURGE_ZONE
+ ((zones[dp->d_zone].z_type == Z_PRIMARY) ||
+ (zones[dp->d_zone].z_type == Z_SECONDARY)) &&
+#endif
+ match(dp, class, T_SOA)) {
dprintf(3, (ddt, "findns: SOA found\n"));
if (zones[dp->d_zone].z_flags & Z_AUTH) {
*npp = np;
@@ -1846,6 +2155,10 @@ try_again:
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
if (!match(dp, class, T_NS))
continue;
+#ifdef NCACHE
+ if (dp->d_rcode)
+ continue;
+#endif
/*
* Don't use records that may become invalid to
* reference later when we do the rtt computation.
@@ -1854,12 +2167,18 @@ try_again:
* XXX: this is horribly bogus.
*/
if ((dp->d_zone == 0) &&
+#ifdef DATUMREFCNT
+ (dp->d_ttl < tt.tv_sec) &&
+#else
(dp->d_ttl < (tt.tv_sec+900)) &&
+#endif
!(dp->d_flags & DB_F_HINT)) {
dprintf(1, (ddt, "findns: stale entry '%s'\n",
np->n_dname));
/* Cache invalidate the NS RR's. */
+#ifndef DATUMREFCNT
if (dp->d_ttl < tt.tv_sec)
+#endif
delete_all(np, class, T_NS);
goto try_parent;
}
@@ -1888,7 +2207,7 @@ try_parent:
p_class(class)));
if ((unsigned)class < MAXCLASS && norootlogged[class] == 0) {
norootlogged[class] = 1;
- syslog(LOG_ERR, "No root nameservers for class %s\n",
+ syslog(LOG_INFO, "No root nameservers for class %s\n",
p_class(class));
}
return (SERVFAIL);
@@ -1936,6 +2255,10 @@ finddata(np, class, type, hp, dnamep, lenp, countp)
#endif /*ROUND_ROBIN*/
buflen = *lenp;
+#ifdef DEBUG
+ if (buflen > PACKETSZ)
+ dprintf(1, (ddt, "finddata(): buflen=%d\n", buflen));
+#endif
cp = ((char *)hp) + *countp;
for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
if (!wanted(dp, class, type)) {
@@ -1986,9 +2309,9 @@ finddata(np, class, type, hp, dnamep, lenp, countp)
/*
* This should not happen, yet it does...
*/
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"NODATA & data for \"%s\" type %d class %d",
- *dnamep, type, class);
+ *dnamep, type, class);
continue;
}
if (type != T_ANY) {
@@ -2005,9 +2328,9 @@ finddata(np, class, type, hp, dnamep, lenp, countp)
/*
* This should not happen, yet it might...
*/
- syslog(LOG_WARNING,
+ syslog(LOG_INFO,
"NXDOMAIN & data for \"%s\" type %d class %d",
- *dnamep, type, class);
+ *dnamep, type, class);
continue;
}
if (type != T_ANY) {
@@ -2040,7 +2363,7 @@ finddata(np, class, type, hp, dnamep, lenp, countp)
if (dp->d_type == T_CNAME) {
if (type != T_ANY) { /* or T_NS? */
*dnamep = (caddr_t) dp->d_data;
- if (dp->d_zone &&
+ if (dp->d_zone != DB_Z_CACHE &&
(zones[dp->d_zone].z_flags & Z_AUTH) &&
class != C_ANY) /* XXX */
hp->aa = 1; /* XXX */
@@ -2074,9 +2397,9 @@ wanted(dp, class, type)
struct databuf *dp;
int class, type;
{
-
- dprintf(3, (ddt, "wanted(%x, %d, %d) %d, %d\n", dp, class, type,
- dp->d_class, dp->d_type));
+ dprintf(3, (ddt, "wanted(%#lx, %d, %d) [%s %s]\n",
+ (u_long)dp, class, type,
+ p_class(dp->d_class), p_type(dp->d_type)));
if (dp->d_class != class && class != C_ANY)
return (0);
@@ -2145,7 +2468,7 @@ add_data(np, dpp, cp, buflen)
register int n, count = 0;
getname(np, dname, sizeof(dname));
- for(dp = *dpp++; dp != NULL; dp = *dpp++) {
+ for (dp = *dpp++; dp != NULL; dp = *dpp++) {
if (stale(dp))
continue; /* ignore old cache entry */
#ifdef NCACHE
@@ -2174,8 +2497,8 @@ delete_all(np, class, type)
{
register struct databuf *dp, *pdp;
- dprintf(3, (ddt, "delete_all: '%s' 0x%x class %d type %d\n",
- np->n_dname, np, class, type));
+ dprintf(3, (ddt, "delete_all(%#lx:\"%s\" %s %s)\n",
+ (u_long)np, np->n_dname, p_class(class), p_type(type)));
pdp = NULL;
dp = np->n_data;
while (dp != NULL) {
diff --git a/usr.sbin/named/ns_sort.c b/usr.sbin/named/ns_sort.c
index 6e77de695536b..70da7fee30e2d 100644
--- a/usr.sbin/named/ns_sort.c
+++ b/usr.sbin/named/ns_sort.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_sort.c 4.10 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: ns_sort.c,v 1.1.1.1 1994/09/22 19:46:13 pst Exp $";
+static char rcsid[] = "$Id: ns_sort.c,v 1.2 1995/05/30 03:48:59 rgrimes Exp $";
#endif /* not lint */
/*
@@ -124,8 +124,8 @@ sort_rr(cp, count, ntp, eom)
#ifdef DEBUG
if (debug > 2) {
inaddr.s_addr = ntp->addr;
- fprintf(ddt, "sort_rr(x%x, %d, [%s])\n",
- cp, count, inet_ntoa(inaddr));
+ fprintf(ddt, "sort_rr(%#lx, %d, [%s])\n",
+ (u_long)cp, count, inet_ntoa(inaddr));
}
#endif
rr1 = NULL;
diff --git a/usr.sbin/named/ns_stats.c b/usr.sbin/named/ns_stats.c
index 4a1182074b9c7..b4c8958d501ca 100644
--- a/usr.sbin/named/ns_stats.c
+++ b/usr.sbin/named/ns_stats.c
@@ -1,12 +1,12 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_stats.c 4.10 (Berkeley) 6/27/90";
-static char rcsid[] = "$Id: ns_stats.c,v 1.1.1.1 1994/09/22 19:46:14 pst Exp $";
+static char rcsid[] = "$Id: ns_stats.c,v 1.2 1995/05/30 03:49:00 rgrimes Exp $";
#endif /* not lint */
/*
- * ++Copyright++ 1986
+ * ++Copyright++ 1986,1994
* -
- * Copyright (c) 1986
+ * Copyright (c) 1986,1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,7 @@ static char rcsid[] = "$Id: ns_stats.c,v 1.1.1.1 1994/09/22 19:46:14 pst Exp $";
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
+#include <arpa/inet.h>
#include <stdio.h>
#include <syslog.h>
#include <errno.h>
@@ -80,8 +81,10 @@ static const char *typenames[T_ANY+1] = {
"CNAME", "SOA", "MB", "MG", "MR",
"NULL", "WKS", "PTR", "HINFO", "MINFO",
"MX", "TXT", "RP", "AFSDB", "X25",
- "ISDN", "RT", "NSAP", 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "ISDN", "RT", "NSAP", "NSAP_PTR", "SIG",
+ "KEY", "PX", "invalid(GPOS)", "AAAA", "LOC",
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
/* 20 per line */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -109,21 +112,24 @@ static void nameserStats __P((FILE *));
void
ns_stats()
{
- time_t timenow;
+ time_t timenow = time(NULL);
register FILE *f;
register int i;
+ syslog(LOG_NOTICE, "dumping nameserver stats\n");
+
if (!(f = fopen(statsfile, "a"))) {
- dprintf(1, (ddt, "can't open stat file, \"%s\"\n", statsfile));
- syslog(LOG_ERR, "cannot open stat file, \"%s\"\n", statsfile);
+ syslog(LOG_NOTICE, "cannot open stat file, \"%s\"\n",
+ statsfile);
return;
}
- time(&timenow);
fprintf(f, "+++ Statistics Dump +++ (%ld) %s",
(long)timenow, ctime(&timenow));
- fprintf(f, "%d\ttime since boot (secs)\n", timenow - boottime);
- fprintf(f, "%d\ttime since reset (secs)\n", timenow - resettime);
+ fprintf(f, "%ld\ttime since boot (secs)\n",
+ (long)(timenow - boottime));
+ fprintf(f, "%ld\ttime since reset (secs)\n",
+ (long)(timenow - resettime));
#ifdef DMALLOC
/* malloc statistics */
@@ -131,15 +137,15 @@ ns_stats()
#endif
/* query type statistics */
- fprintf(f, "%d\tUnknown query types\n", typestats[0]);
+ fprintf(f, "%lu\tUnknown query types\n", (u_long)typestats[0]);
for(i=1; i < T_ANY+1; i++)
if (typestats[i])
if (typenames[i])
- fprintf(f, "%lu\t%s queries\n", typestats[i],
- typenames[i]);
+ fprintf(f, "%lu\t%s queries\n",
+ (u_long)typestats[i], typenames[i]);
else
fprintf(f, "%lu\ttype %d queries\n",
- typestats[i], i);
+ (u_long)typestats[i], i);
/* name server statistics */
nameserStats(f);
@@ -147,6 +153,7 @@ ns_stats()
fprintf(f, "--- Statistics Dump --- (%ld) %s",
(long)timenow, ctime(&timenow));
(void) my_fclose(f);
+ syslog(LOG_NOTICE, "done dumping nameserver stats\n");
}
void
@@ -187,6 +194,12 @@ static const char *statNames[nssLast] = {
"SDupQ", /* sent them a retry */
"SFail", /* sent them a SERVFAIL */
"SFErr", /* sent them a FORMERR */
+ "SErr", /* sent failed (in sendto) */
+#ifdef XSTATS
+ "RNotNsQ", /* received from remote port != ns_port */
+ "SNaAns", /* sent them a non autoritative answer */
+ "SNXD", /* sent them a negative response */
+#endif
};
#endif /*STATS*/
@@ -268,10 +281,10 @@ nameserStatsOut(f, stats)
u_long stats[];
{
int i;
- char *pre = "\t";
+ const char *pre = "\t";
for (i = 0; i < (int)nssLast; i++) {
- fprintf(f, "%s%u", pre, stats[i]);
+ fprintf(f, "%s%lu", pre, (u_long)stats[i]);
pre = ((i+1) % 5) ? " " : " ";
}
fputc('\n', f);
@@ -282,7 +295,7 @@ nameserStatsHdr(f)
FILE *f;
{
int i;
- char *pre = "\t";
+ const char *pre = "\t";
fprintf(f, "(Legend)\n");
for (i = 0; i < (int)nssLast; i++) {
@@ -323,3 +336,63 @@ nameserStats(f)
nameserStatsFile = NULL;
#endif /*STATS*/
}
+
+#ifdef XSTATS
+/* Benoit Grange, log minimal statistics, called from ns_maint */
+void
+ns_logstats()
+{
+ char buffer[1024];
+ char buffer2[32], header[64];
+ time_t timenow = time(NULL);
+ int i;
+
+#ifdef HAVE_GETRUSAGE
+# define tv_float(tv) ((tv).tv_sec + ((tv).tv_usec / 1000000.0))
+ struct rusage usage, childu;
+
+ getrusage(RUSAGE_SELF, &usage);
+ getrusage(RUSAGE_CHILDREN, &childu);
+
+ sprintf(buffer, "CPU=%gu/%gs CHILDCPU=%gu/%gs",
+ tv_float(usage.ru_utime), tv_float(usage.ru_stime),
+ tv_float(childu.ru_utime), tv_float(childu.ru_stime));
+ syslog(LOG_INFO, "USAGE %lu %lu %s", timenow, boottime, buffer);
+# undef tv_float
+#endif
+
+ sprintf(header, "NSTATS %lu %lu", timenow, boottime);
+ strcpy(buffer, header);
+
+ for (i = 0; i < T_ANY+1; i++) {
+ if (typestats[i]) {
+ if (typenames[i])
+ sprintf(buffer2, " %s=%lu",
+ typenames[i], typestats[i]);
+ else
+ sprintf(buffer2, " %d=%lu", i, typestats[i]);
+ if (strlen(buffer) + strlen(buffer2) >
+ sizeof(buffer) - 1) {
+ syslog(LOG_INFO, buffer);
+ strcpy(buffer, header);
+ }
+ strcat(buffer, buffer2);
+ }
+ }
+ syslog(LOG_INFO, buffer);
+
+ sprintf(header, "XSTATS %lu %lu", (u_long)timenow, (u_long)boottime);
+ strcpy(buffer, header);
+ for (i = 0; i < (int)nssLast; i++) {
+ sprintf(buffer2, " %s=%lu",
+ statNames[i]?statNames[i]:"?", (u_long)globalStats[i]);
+ if (strlen(buffer) + strlen(buffer2) > sizeof(buffer) - 1) {
+ syslog(LOG_INFO, buffer);
+ strcpy(buffer, header);
+ }
+ strcat(buffer, buffer2);
+ }
+ syslog(LOG_INFO, buffer);
+}
+
+#endif /*XSTATS*/
diff --git a/usr.sbin/named/ns_validate.c b/usr.sbin/named/ns_validate.c
index 46095180f6f49..358fcb8557deb 100644
--- a/usr.sbin/named/ns_validate.c
+++ b/usr.sbin/named/ns_validate.c
@@ -52,21 +52,21 @@ static int VQcount;
* pseudocode for function validate is as follows:
* validate(domain, server, type, class, data, dlen, rcode) {
*
- * if(dname or a higher level name not found in cache)
+ * if (dname or a higher level name not found in cache)
* return INVALID;
* if (NS records for "domain" found in cache){
*
- * if(we are authoritative) /findns() returned NXDOMAIN;/
- * if(we did not have an exact match on names)
+ * if (we are authoritative) /findns() returned NXDOMAIN;/
+ * if (we did not have an exact match on names)
* =>the name does not exist in our database
* => data is bad: return INVALID
- * if(data agrees with what we have)
+ * if (data agrees with what we have)
* return VALID_NO_CACHE;
* else return INVALID;
*
- * if(we are not authoritative) /findns() returned OK;/
+ * if (we are not authoritative) /findns() returned OK;/
* if (address records for NS's found in cache){
- * if("server" = one of the addresses){
+ * if ("server" = one of the addresses){
* return VALID_CACHE;
* }else{
* stick in queue of "to_validate" data;
@@ -121,7 +121,7 @@ validate(dname, server, type, class, data, dlen
/* everything from forwarders is the GOSPEL */
for (fwd = fwdtab; fwd != NULL; fwd = fwd->next) {
if (server->sin_addr.s_addr == fwd->fwdaddr.sin_addr.s_addr)
- return(VALID_CACHE);
+ return (VALID_CACHE);
}
htp = hashtab;
@@ -138,16 +138,15 @@ validate(dname, server, type, class, data, dlen
fname[0] = '\0';
}
dprintf(5, (ddt,
- "validate:namebuf found np:0x%x, d:\"%s\", f:\"%s\"\n",
- np, dname, fname));
+ "validate:namebuf found np:%#lx, d:\"%s\", f:\"%s\"\n",
+ (u_long)np, dname, fname));
/* save the namebuf if we were able to locate the exact dname */
if (!strcasecmp(dname, fname)) {
dnamep = np;
exactmatch = 1;
}
- if (np == NULL && fname != NULL) {
+ if (np == NULL && fname != NULL)
free((char *)fname);
- }
switch (findns(&np, class, nsp, &count, 0)) {
case NXDOMAIN:
/** we are authoritative for this domain, lookup name
@@ -162,19 +161,19 @@ validate(dname, server, type, class, data, dlen
needs_prime_cache = 0;
#ifdef NCACHE
- if(rcode == NXDOMAIN) {
+ if (rcode == NXDOMAIN) {
/* If we had an exactmatch on the name, we found the
* name in our authority database, so this couldn't
* have been a bad name. INVALID data, say so
*/
if (exactmatch)
- return INVALID;
+ return (INVALID);
else
/* we did not have an exactmatch, the data is
* good, we do not NCACHE stuff we are
* authoritative for, though.
*/
- return VALID_NO_CACHE;
+ return (VALID_NO_CACHE);
}
#endif
if (!strcasecmp(dname, np->n_dname)) {
@@ -185,9 +184,9 @@ validate(dname, server, type, class, data, dlen
* doesn't, invalid.
*/
if (isvalid(np, type, class, data, dlen))
- return VALID_NO_CACHE;
+ return (VALID_NO_CACHE);
else
- return INVALID;
+ return (INVALID);
}
/* we found ns records in a higher level, if we were unable to
@@ -196,16 +195,16 @@ validate(dname, server, type, class, data, dlen
* this name. this name is obviously invalid
*/
if (!exactmatch)
- return INVALID;
+ return (INVALID);
/* we found the exact name earlier and we are obviously
* authoritative so check for data records and see if any
* match.
*/
if (isvalid(dnamep, type, class, data, dlen))
- return VALID_NO_CACHE;
+ return (VALID_NO_CACHE);
else
- return INVALID;
+ return (INVALID);
case SERVFAIL:/* could not find name server records*/
/* stick_in_queue(dname, type, class, data); */
@@ -214,7 +213,7 @@ validate(dname, server, type, class, data, dlen
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return INVALID;
+ return (INVALID);
case OK: /*proceed */
dprintf(5,
@@ -226,19 +225,19 @@ validate(dname, server, type, class, data, dlen
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return VALID_CACHE;
+ return (VALID_CACHE);
}
/* server is not one of those we know of */
/* stick_in_queue(dname, type, class, data); */
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return INVALID;
+ return (INVALID);
default:
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
- return INVALID;
+ return (INVALID);
} /*switch*/
} /*validate*/
@@ -262,7 +261,7 @@ isvalid(np, type, class, data, dlen)
if (!wanted(dp, class, type)) {
if ((type == T_CNAME) && (class == dp->d_class)) {
/* if a cname exists, any other will not */
- return(0);
+ return (0);
/* we come here only for zone info,
* so -ve $ed info can't be
*/
@@ -277,12 +276,10 @@ isvalid(np, type, class, data, dlen)
* we should return FAILURE since we should not have found
* data here.
*/
- if ((data == NULL) || (dlen == 0)) {
- return 0;
- }
+ if ((data == NULL) || (dlen == 0))
+ return (0);
- /* XXX: why aren't we just calling db_cmp() ?
- */
+ /* XXX: why aren't we just calling db_cmp()? */
switch (type) {
char *td;
@@ -298,6 +295,7 @@ isvalid(np, type, class, data, dlen)
case T_TXT:
case T_X25:
case T_ISDN:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -378,6 +376,29 @@ isvalid(np, type, class, data, dlen)
break;
return (1);
+ case T_PX:
+ x = memcmp(dp->d_data, data,
+ INT16SZ);
+ if (x != 0)
+ break;
+ td = data + INT16SZ;
+ tdp = dp->d_data + INT16SZ;
+
+ /* compare first string */
+ x = strncasecmp(td, (char *)tdp,
+ strlen((char *)td) + 1);
+ if (x != 0)
+ break;
+ td += (strlen(td) + 1);
+ tdp += (strlen(tdp) + 1);
+
+ /* compare second string */
+ x = strncasecmp(td, (char *)tdp,
+ strlen((char *)td+1));
+ if (x != 0)
+ break;
+ return (1);
+
default:
dprintf(3, (ddt, "unknown type %d\n", type));
return (0);
@@ -390,7 +411,7 @@ isvalid(np, type, class, data, dlen)
*/
if ((data == NULL) || (dlen == 0)) {
/* negative data, report success */
- return 1;
+ return (1);
}
/* positive data, no such RR, validation failed */
return (0);
@@ -512,7 +533,7 @@ check_in_tables(nsp, server, syslogdname)
void
store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
char *servername;
- struct in_addr *serveraddr;
+ struct in_addr serveraddr;
char *syslogdname;
char *sysloginfo;
{
@@ -520,21 +541,21 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
dprintf(3, (ddt,
"store_name_addr:s:%s, a:[%s]\n",
- servername, inet_ntoa(*serveraddr)));
+ servername, inet_ntoa(serveraddr)));
/* if we already have the name address pair in cache, return */
for (i = lastNA; i != firstNA; i = (i+1) % MAXNAMECACHE) {
if (strcasecmp(servername, nameaddrlist[i].nsname) == 0) {
- if (serveraddr->s_addr
+ if (serveraddr.s_addr
==
nameaddrlist[i].ns_addr.s_addr) {
dprintf(5, (ddt,
"store_name_addr:found n and a [%s] [%s] in our $\n",
inet_ntoa(nameaddrlist[i].ns_addr),
- inet_ntoa(*serveraddr)));
+ inet_ntoa(serveraddr)));
return;
} /* if */
- } else if (serveraddr->s_addr
+ } else if (serveraddr.s_addr
==
nameaddrlist[i].ns_addr.s_addr) {
#ifdef BAD_IDEA
@@ -543,20 +564,15 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
* replace old name by new, next query likely to have
* NS record matching new
*/
- if (!haveComplained(
- (char*)dhash((u_char*)nameaddrlist[i].nsname,
- strlen(nameaddrlist[i].nsname)),
- (char*)dhash((u_char*)servername,
- strlen(servername))
- )
- ) {
+ if (!haveComplained((char*)
+ nhash(nameaddrlist[i].nsname),
+ (char*)nhash(servername)))
syslog(LOG_INFO,
"%s: server name mismatch for [%s]: (%s != %s) (server for %s)",
sysloginfo,
- inet_ntoa(*serveraddr),
+ inet_ntoa(serveraddr),
nameaddrlist[i].nsname, servername,
syslogdname);
- }
#endif
free(nameaddrlist[i].nsname);
nameaddrlist[i].nsname =
@@ -570,7 +586,7 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
nameaddrlist[firstNA].nsname =
(char *)malloc((unsigned)strlen(servername)+1);
strcpy(nameaddrlist[firstNA].nsname, servername);
- bcopy((char *)serveraddr,
+ bcopy((char *)&serveraddr,
(char *)&(nameaddrlist[firstNA].ns_addr),
INADDRSZ);
@@ -616,7 +632,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
zone, flags));
#ifdef DEBUG
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, msglen, ddt);
#endif
cp = rrp;
@@ -646,6 +662,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
case T_TXT:
case T_X25:
case T_ISDN:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -714,7 +731,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
(char *)cp1, sizeof(data) - INT16SZ);
if (n < 0) {
hp->rcode = FORMERR;
- return(-1);
+ return (-1);
}
cp += n;
@@ -725,6 +742,35 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
cp1 = data;
break;
+ case T_PX:
+ /* grab preference */
+ bcopy((char *)cp, data, INT16SZ);
+ cp1 = data + INT16SZ;
+ cp += INT16SZ;
+
+ /* get first name */
+ n = dn_expand(msg, msg + msglen, cp,
+ (char *)cp1, sizeof(data) - INT16SZ);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += (n = strlen((char *)cp1) + 1);
+ n1 = sizeof(data) - n;
+
+ /* get second name */
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += strlen((char *)cp1) + 1;
+ n = cp1 - data;
+ cp1 = data;
+ break;
+
default:
dprintf(3, (ddt, "unknown type %d\n", type));
return ((cp - rrp) + dlen);
@@ -733,8 +779,8 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
dprintf(2, (ddt,
"update type %d: %d bytes is too much data\n",
type, n));
- hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */
- return(-1);
+ hp->rcode = FORMERR;
+ return (-1);
}
*VCode = validate(dname, server, type, class,(char *)cp1, n
@@ -751,7 +797,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
"validation succeeded d:%s, t:%d, c:%d\n",
dname, type, class));
}
- return(cp -rrp);
+ return (cp - rrp);
}
#if 0
@@ -871,7 +917,7 @@ update_msg(msg, msglen, Vlist, c)
if (debug) {
fprintf(ddt, "update_msg: msglen:%d, c:%d\n", *msglen, c);
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, *msglen, ddt);
}
#endif
/* just making sure we do not do all the work for nothing */
@@ -942,7 +988,7 @@ update_msg(msg, msglen, Vlist, c)
dprintf(3, (ddt,
"newlen:%d, if no RR is INVALID == msglen\n", newlen));
newmsg = (u_char *)calloc(1,newlen + MAXDNAME);
- if(newmsg == NULL)
+ if (newmsg == NULL)
goto badend;
dpp = dnptrs;
*dpp++ = newmsg;
@@ -1022,6 +1068,7 @@ update_msg(msg, msglen, Vlist, c)
case T_TXT:
case T_X25:
case T_ISDN:
+ case T_LOC:
#ifdef ALLOW_T_UNSPEC
case T_UNSPEC:
#endif
@@ -1128,6 +1175,44 @@ update_msg(msg, msglen, Vlist, c)
rembuflen -= n_new+INT16SZ;
break;
+ case T_PX:
+ /* grab preference */
+ bcopy(cp, newcp, INT16SZ);
+ cp += INT16SZ;
+ newcp += INT16SZ;
+
+ /* get first name */
+ n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ goto badend;
+ }
+ cp += n;
+ n_new = dn_comp((char *)data, newcp, rembuflen,
+ dnptrs, edp);
+ if (n_new < 0)
+ goto badend;
+ newcp += n_new;
+ newlen += n_new+INT16SZ;
+ rembuflen -= n_new+INT16SZ;
+ dlen = n_new+INT16SZ;
+ n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ goto badend;
+ }
+ cp += n;
+ n_new = dn_comp((char *)data, newcp, rembuflen,
+ dnptrs, edp);
+ if (n_new < 0)
+ goto badend;
+ newcp += n_new;
+ newlen += n_new;
+ rembuflen -= n_new;
+ dlen += n_new;
+ PUTSHORT(dlen, tempcp);
+ break;
+
default:
dprintf(3, (ddt, "unknown type %d\n", type));
goto badend;
@@ -1148,14 +1233,14 @@ update_msg(msg, msglen, Vlist, c)
#ifdef DEBUG
if (debug >= 10)
- fp_query(msg, ddt);
+ fp_nquery(msg, *msglen, ddt);
#endif
free((char *)RRlen);
- return(n);
+ return (n);
badend:
dprintf(2, (ddt, "encountered problems: UPDATE_MSG\n"));
free((char *)RRlen);
- return(-1);
+ return (-1);
}
#endif /*VALIDATE*/
diff --git a/usr.sbin/named/options.h b/usr.sbin/named/options.h
index 7c3440717fe08..b6be5048dbf54 100644
--- a/usr.sbin/named/options.h
+++ b/usr.sbin/named/options.h
@@ -1,7 +1,7 @@
/* options.h - specify the conditionally-compiled features
* vix 28mar92 [moved out of the Makefile because they were getting too big]
*
- * $Id: options.h,v 1.2 1995/05/09 12:48:17 rgrimes Exp $
+ * $Id: options.h,v 1.3 1995/05/30 03:49:02 rgrimes Exp $
*/
/*
@@ -70,6 +70,9 @@
* mpa = Mark Andrews of CSIRO - DMS
* rossc = Ross Cartlidge of The Univeritsy of Sydney
* mtr = Marshall Rose of TPC.INT
+ * bg = Benoit Grange of INRIA
+ * ckd = Christopher Davis of Kapor Enterprises
+ * gns = Greg Shapiro of WPI
*/
#define DEBUG /* enable -d flag and SIGUSR[12] support (ucb) */
@@ -92,16 +95,17 @@
#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 NCACHE /* negative caching (anant@isi.edu) */
-#define VALIDATE /* validation procedure (anant@isi.edu) */
+/*#define VALIDATE*/ /* validation procedure (anant@isi.edu) (DO NOT USE!)*/
/*#define SHORT_FNAMES*//* file names used in named-xfer need to be short */
#define RESOLVSORT /* allow sorting of addresses in gethostbyname (mpa) */
-#define STUBS /* allow transfers of NS only for a zone (mpa) (EXP) */
-/*#define SUNSECURITY*/ /* obscure fix for sunos (see below) */
+#define STUBS /* allow transfers of NS only for a zone (mpa) */
+#ifndef LOGFAC
#define LOGFAC LOG_DAEMON /* what syslog facility should named use? */
-/*#define SECURE_ZONES*//* if you want to inhibit world access to zone(s) */
+#endif
+#define SECURE_ZONES /* if you want to inhibit world access to zones (gns)*/
#define ROUND_ROBIN /* rotate databuf list after each access (mtr) */
#define ADDAUTH /* return NS and glue w/ authorative answers (mpa) */
-#define RFC1535 /* use RFC 1535 default for "search" list (vix) */
+/*#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)*/
@@ -109,8 +113,12 @@
#define GETSER_LOGGING LOG_INFO /* log errors/timeouts getting serial number */
/*#define RETURNSOA*/ /* good code that the world isn't ready for yet */
#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 RENICE*/ /* named-xfer should run at normal priority */
+#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) */
/*--------------------------------------------*
* no user-servicable parts beyond this point *
@@ -149,12 +157,10 @@
# endif
#endif
-#if defined(SUNOS4) || (defined(sun) && defined(SYSV))
-# ifndef SUNSECURITY
-# define SUNSECURITY /* mandatory on suns and rlogin etc. depend on this */
-# endif
-#endif
-
#ifdef LAME_LOGGING
# define LAME_DELEGATION
#endif
+
+#if defined(XSTATS) && !defined(STATS)
+# define STATS
+#endif
diff --git a/usr.sbin/named/portability.h b/usr.sbin/named/portability.h
index fa257cd31af32..a673279abdba0 100644
--- a/usr.sbin/named/portability.h
+++ b/usr.sbin/named/portability.h
@@ -1,7 +1,7 @@
/* defs.h - include or define things that aren't present on all systems
* vixie@decwrl 26dec92 [new]
*
- * $Id: portability.h,v 1.1 1994/09/22 20:45:08 pst Exp $
+ * $Id: portability.h,v 1.2 1995/05/30 03:49:04 rgrimes Exp $
*/
/*
@@ -69,6 +69,22 @@
# define TIME_H_INCLUDED
#endif
+#ifdef ISC
+# ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+# endif
+# define SYSV
+# define SVR3
+# define _SYSV3
+# define NEED_STRTOUL
+# define NEED_FTRUNCATE
+# define USE_POSIX
+# include <sys/bsdtypes.h>
+# include <sys/sioctl.h>
+# include <sys/stream.h>
+# include <net/errno.h>
+#endif
+
#if defined(__convex__)
# if !defined(_POSIX_SOURCE)
# define _POSIX_SOURCE
@@ -85,6 +101,14 @@
# define setitimer(a,b,c) __setitimer(a,b,c)
#endif
+/* This is defined in the Makefile for ISC compiles. */
+#if defined(ISC)
+# define ftruncate(a,b) __ftruncate(a,b)
+# define USE_MEMCPY
+# define USE_UTIME
+# define HAVE_FCHMOD 0
+#endif
+
/* SCO UNIX defines only this unique symbol, apparently. */
#if defined(M_UNIX)
/* XXX - why is this POSIX_SOURCE instead of _POSIX_SOURCE? */
@@ -109,13 +133,26 @@
# define BSD 43
#endif
-#if defined(_POSIX_SOURCE) || defined(__sgi) || defined(ultrix) || \
+#if defined(_AUX_SOURCE)
+# define vfork fork
+# define NEED_STRERROR
+# define NEED_STRTOUL
+# define SIG_FN void
+# define USE_MEMCPY
+#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))
# define USE_POSIX
#endif
-#if defined(ultrix) && !defined(BSD)
+#if defined(__ultrix) && !defined(BSD)
# define BSD 42
#endif
@@ -123,28 +160,50 @@
# define RISCOS_BSD
#endif
-#if defined(SVR4) && !defined(SYSV)
-# define SYSV
+#if defined(SYSV) || defined(__ultrix) || defined(__osf__) \
+ || (defined(BSD) && BSD >= 199306) || defined(linux)
+# define USE_UTIME
+# define HAVE_SETVBUF
#endif
-#if defined(SYSV) || defined(ultrix) || (defined(BSD) && BSD >= 199306)
-# define USE_UTIME
+#if defined(SYSV) && !defined(SVR4)
+# define vfork fork
+#endif
+
+#if defined(sun) || defined(SVR4)
+# define NETREAD_BROKEN
#endif
#if defined(BSD) && BSD >= 199006 && !defined(i386) && !defined(RISCOS_BSD)
# define HAVE_DAEMON
#endif
+#if !defined(BSD) || (BSD <= 199006)
+# if !defined(NeXT)
+# define NEED_INETADDR
+# endif
+# define NEED_INETATON
+#endif
+
#if defined(__hpux)
# if defined(__STDC__)
# define select(a,b,c,d,e) select(a, (int *)b, (int *)c, (int *)d, e)
# define ctime(x) ctime((const time_t *)x)
# endif /*__STDC__*/
-# ifndef SYSV
-# define USE_UTIME
-# define setlinebuf(x) setvbuf(x, NULL, _IOLBF, BUFSIZ)
-# define SIGWINCH SIGWINDOW
+# if !defined(SYSV)
+# define USE_UTIME
+# define setlinebuf(x) setvbuf(x, NULL, _IOLBF, BUFSIZ)
+# if !defined(SIGWINCH) /*pre 9.0*/
+# define SIGWINCH SIGWINDOW
+# endif
# endif /*SYSV*/
+/* XXX: better autodetection of the need for "struct linger" would be nice */
+# if 0
+struct linger {
+ int l_onoff; /* option on/off */
+ int l_linger; /* linger time */
+};
+# endif
#endif /*__hpux*/
#if defined(_SEQUENT_)
@@ -219,6 +278,10 @@ extern long pathconf __P((const char *path, int name));
# define INT_MAX 2147483647 /* max decimal value of an "int" */
#endif
+#ifndef RAND_MAX
+# define RAND_MAX 0x7fffffff
+#endif
+
#ifndef IN_LOOPBACKNET
# define IN_LOOPBACKNET 127
#endif
@@ -245,8 +308,10 @@ int strcasecmp __P((const char *, const char *));
!defined(NeXT) && \
!defined(__convex__) && \
!defined(USE_POSIX)
-extern void syslog();
-extern char *ctime __P((const time_t *clock));
+# if !defined(NCR)
+extern void syslog();
+# endif
+extern char *ctime __P((const time_t *clock));
extern int close(), setitimer(), recv(), sendto(), sigsetmask(),
atoi(), getpid(), fork(), read(), ioctl(),
setsockopt(), socket(), bind();
@@ -260,7 +325,11 @@ extern int close(), setitimer(), recv(), sendto(), sigsetmask(),
* define them in terms of bcopy et al if !defined(__STDC__)
* but that's more work.
*/
+#if defined(USE_MEMCPY)
+# define bcopy(a,b,c) memcpy(b,a,c)
+#else
# define bcopy(a,b,c) memmove(b,a,c)
+#endif
# define bzero(a,b) memset(a,0,b)
# define bcmp(a,b,c) memcmp(a,b,c)
# else
@@ -274,19 +343,27 @@ extern int bcmp();
&& !defined(USE_POSIX) && !defined(apollo) && !defined(sequent) \
&& !defined(M_UNIX)
# define NEED_STRERROR
+#if !defined(ultrix) && !defined(NCR)
# define NEED_PUTENV
#endif
+#endif
#if defined(SUNOS4)
# define NEED_STRERROR
+# if defined(sun386)
+# define pid_t int
+# define NEED_STRCASECMP
+# endif
#endif
#if (!defined(BSD) || (BSD < 43))
# define NEED_MKSTEMP
-# if !defined(ultrix) && !defined(apollo)
+# if !defined(__ultrix) && !defined(apollo)
# define NEED_STRCASECMP
# define NEED_MKTEMP
-# define NEED_STRPBRK
+# if !defined(SVR4)
+# define NEED_STRPBRK
+# endif
# endif
#endif
@@ -302,7 +379,7 @@ extern int bcmp();
#ifndef SIG_FN
# ifdef BSD
# if (BSD >= 199006) || defined(NeXT) || defined(__osf__) || defined(sun) \
- || defined(ultrix) || defined(apollo) || defined(POSIX_SIGNALS)
+ || defined(__ultrix) || defined(apollo) || defined(POSIX_SIGNALS)
# define SIG_FN void /* signal-catching functions return void */
# else
# define SIG_FN int /* signal-catching functions return int */
@@ -319,7 +396,7 @@ extern u_long htonl(), ntohl();
#endif
#if defined(USE_POSIX) && !defined(sun) && !defined(__sgi) \
- && !defined(__convex__) && !defined(ultrix)
+ && !defined(__convex__) && !defined(__ultrix) && !defined(_AUX_SOURCE)
# define PORT_NONBLOCK O_NONBLOCK
# define PORT_WOULDBLK EAGAIN
#else
@@ -339,7 +416,7 @@ extern u_long htonl(), ntohl();
#define waitpid(x,y,z) (wait3(y,z,(struct rusage *)NULL))
#endif
-#if defined(NeXT) || defined(_AIX)
+#if defined(NeXT) || defined(_AIX) || defined(sun386)
# undef WIFEXITED
# undef WEXITSTATUS
# undef WIFSIGNALED
@@ -352,13 +429,13 @@ extern u_long htonl(), ntohl();
#endif /* sequent */
#if !defined(WIFEXITED)
-# define WIFEXITED(x) (!(x & 0200))
+# define WIFEXITED(x) (!(x & 0177))
#endif
#if !defined(WEXITSTATUS)
# define WEXITSTATUS(x) (x >> 8)
#endif
#if !defined(WIFSIGNALED)
-# define WIFSIGNALED(x) ((x & 0200) && ((x & 0200) != 0177))
+# define WIFSIGNALED(x) ((x & 0177) && ((x & 0377) != 0177))
#endif
#if !defined(WTERMSIG)
# define WTERMSIG(x) (x & 0177)
@@ -394,11 +471,12 @@ extern u_long htonl(), ntohl();
# define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO)
#endif
-#if (defined(ultrix) || defined(__osf__)) && defined(NEED_STRTOUL)
+#if defined(NEED_STRTOUL) && \
+ (defined(__ultrix) || defined(__osf__) || defined(NeXT))
# undef NEED_STRTOUL
#endif
-#if defined(ultrix) || defined(__osf__)
+#if defined(__ultrix) || defined(__osf__)
# define MAYBE_HESIOD
#endif
@@ -428,6 +506,15 @@ extern u_long htonl(), ntohl();
# endif
#endif
+#if defined(BSD) || defined(__osf__) || defined(__convex__)
+# define HAVE_GETRUSAGE
+#endif
+
+/* May be set in the Makefile. */
+#if defined(HAVE_GETRUSAGE)
+# include <sys/resource.h>
+#endif
+
/*
* Because Convex has true library function feof() which is
* patently wrong (it test bit _IOREAD) we need feof() as
@@ -437,6 +524,10 @@ extern u_long htonl(), ntohl();
# define feof(p) ((p)->_flag&_IOEOF)
#endif
+#if defined(M_UNIX) || defined(linux)
+# define SPURIOUS_ECONNREFUSED
+#endif
+
/*
* Assume that a system has fchmod() unless something above says otherwise.
*/
diff --git a/usr.sbin/named/storage.c b/usr.sbin/named/storage.c
index 294c80ab30259..15623f4580b76 100644
--- a/usr.sbin/named/storage.c
+++ b/usr.sbin/named/storage.c
@@ -56,6 +56,10 @@
#include <sys/param.h>
#include <syslog.h>
+#include "portability.h"
+#include "options.h"
+extern void panic __P((int, const char *));
+
#ifdef DSTORAGE
/*
* S T O R A G E . C
@@ -81,7 +85,7 @@
* All rights reserved.
*/
#ifndef lint
-static char RCSid[] = "$Id: storage.c,v 1.2 1994/09/22 20:45:09 pst Exp $";
+static char RCSid[] = "$Id: storage.c,v 1.3 1995/05/30 03:49:05 rgrimes Exp $";
#endif
#undef malloc
@@ -108,8 +112,7 @@ unsigned int cnt;
ptr = malloc(cnt);
if( ptr==(char *)0 ) {
- syslog(LOG_ERR, "rt_malloc: malloc failure");
- abort();
+ panic(errno, "rt_malloc: malloc failure");
} else {
register struct memdebug *mp = rt_mdb;
for( ; mp < &rt_mdb[MDB_SIZE]; mp++ ) {
@@ -142,18 +145,14 @@ char *ptr;
if( mp->mdb_addr != ptr ) continue;
{
register int *ip = (int *)(ptr+mp->mdb_len-sizeof(int));
- if( *ip != MDB_MAGIC ) {
- syslog(LOG_ERR, "ERROR rt_free(x%x, %s) corrupted! x%x!=x%x\n", ptr, "???", *ip, MDB_MAGIC);
- abort();
- }
+ if( *ip != MDB_MAGIC )
+ panic(-1, "rt_free: corrupt magic");
}
mp->mdb_len = 0; /* successful free */
goto ok;
}
- syslog(LOG_ERR, "ERROR rt_free(x%x, %s) bad pointer!\n", ptr, "???");
- abort();
-ok: ;
-
+ panic(-1, "rt_free: bad pointer");
+ ok:
*((int *)ptr) = -1; /* zappo! */
free(ptr);
}
diff --git a/usr.sbin/named/tools/Makefile b/usr.sbin/named/tools/Makefile
index 4c6be8580db2c..fa23e68407ebb 100644
--- a/usr.sbin/named/tools/Makefile
+++ b/usr.sbin/named/tools/Makefile
@@ -1,5 +1,5 @@
# @(#)Makefile 4.10 (Berkeley) 5/29/90
-SUBDIR= named.reload named.restart nsquery nstest
+SUBDIR= named.reload named.restart ndc
.include <bsd.subdir.mk>
diff --git a/usr.sbin/named/tools/named.reload/Makefile b/usr.sbin/named/tools/named.reload/Makefile
index 5ebc77f1d922e..bb71c64ff5f0a 100644
--- a/usr.sbin/named/tools/named.reload/Makefile
+++ b/usr.sbin/named/tools/named.reload/Makefile
@@ -5,13 +5,17 @@ CLEANFILES+=named.reload
PIDDIR=/var/run
INDOT=
+DESTSBIN=${DESTDIR}${BINDIR}
-beforeinstall: named.reload
- install -c -o ${BINOWN} -g ${BINGRP} -m 555 \
+beforeinstall:
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 555 \
named.reload ${DESTDIR}${BINDIR}
+all: named.reload
+
named.reload: named.reload.sh Makefile
- sed -e "s|%PIDDIR%|${PIDDIR}|" \
+ sed -e "s|%DESTSBIN%|${DESTSBIN}|" \
+ -e "s|%INDOT%|${INDOT}|" \
< ${.CURDIR}/named.reload.sh > named.reload
.include "${.CURDIR}/../../../Makefile.inc"
diff --git a/usr.sbin/named/tools/named.reload/named.reload.sh b/usr.sbin/named/tools/named.reload/named.reload.sh
index a25de1b87f616..c800023ec63ff 100644
--- a/usr.sbin/named/tools/named.reload/named.reload.sh
+++ b/usr.sbin/named/tools/named.reload/named.reload.sh
@@ -1,6 +1,7 @@
#!/bin/sh -
#
# from named.reload 5.2 (Berkeley) 6/27/89
-# $Id: named.reload.sh,v 4.9.1.2 1993/09/08 00:01:17 vixie Exp $
+# $Id: named.reload.sh,v 1.2 1994/09/22 20:45:23 pst Exp $
#
-kill -HUP `cat %PIDDIR%/named.pid`
+
+exec %DESTSBIN%/%INDOT%ndc reload
diff --git a/usr.sbin/named/tools/named.restart/Makefile b/usr.sbin/named/tools/named.restart/Makefile
index 30e02c60aa06c..bbeec2ab11928 100644
--- a/usr.sbin/named/tools/named.restart/Makefile
+++ b/usr.sbin/named/tools/named.restart/Makefile
@@ -1,21 +1,21 @@
# @(#)Makefile 5.1 (Berkeley) 5/28/90
-# $Id$
+# $Id: Makefile,v 1.3 1995/05/03 03:26:53 rgrimes Exp $
MAN8= named.restart.8
CLEANFILES+=named.restart
PIDDIR=/var/run
INDOT=
+DESTSBIN=${DESTDIR}${DESTBIN}
beforeinstall:
- install -c -o ${BINOWN} -g ${BINGRP} -m 555 \
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 555 \
named.restart ${DESTDIR}${BINDIR}
all: named.restart
named.restart: named.restart.sh Makefile
- sed -e "s|%PIDDIR%|${PIDDIR}|" \
- -e "s|%INDOT%|${INDOT}|" \
+ sed -e "s|%INDOT%|${INDOT}|" \
-e "s|%DESTSBIN%|${BINDIR}|" \
< ${.CURDIR}/named.restart.sh > named.restart
diff --git a/usr.sbin/named/tools/named.restart/named.restart.sh b/usr.sbin/named/tools/named.restart/named.restart.sh
index a51cf54378440..eb4c7ecb6ba0c 100644
--- a/usr.sbin/named/tools/named.restart/named.restart.sh
+++ b/usr.sbin/named/tools/named.restart/named.restart.sh
@@ -1,23 +1,7 @@
#!/bin/sh -
#
# from named.restart 5.4 (Berkeley) 6/27/89
-# $Id: named.restart.sh,v 1.2 1994/09/22 20:45:26 pst Exp $
+# $Id: named.restart.sh,v 1.3 1995/05/03 03:26:59 rgrimes Exp $
#
-# If there is a global system configuration file, suck it in.
-if [ -f /etc/sysconfig ]; then
- . /etc/sysconfig
-fi
-
-PATH=%DESTSBIN%:/bin:/usr/bin
-
-if [ -f %PIDDIR%/named.pid ]; then
- pid=`cat %PIDDIR%/named.pid`
- kill $pid
- sleep 5
-fi
-
-# $namedflags is imported from /etc/sysconfig
-if [ "X${namedflags}" != "XNO" ]; then
- exec %INDOT%named ${namedflags}
-fi
+exec %DESTSBIN%/%INDOT%ndc restart
diff --git a/usr.sbin/named/xfer/Makefile b/usr.sbin/named/xfer/Makefile
index 505747c808f61..cbc8c820768dd 100644
--- a/usr.sbin/named/xfer/Makefile
+++ b/usr.sbin/named/xfer/Makefile
@@ -2,10 +2,22 @@
PROG= named-xfer
SRCS= named-xfer.c db_glue.c
+OBJS+= version.o
+CLEANFILES+=version.c version.o
CFLAGS+=-I${.CURDIR}/..
.PATH: ${.CURDIR}/..
BINDIR= /usr/libexec
MAN8= named-xfer.8
+
+VER = LOCAL-`date +%y%m%d.%H%M%S`
+
+version.c: ${.CURDIR}/../Version.c ${.CURDIR}/Makefile ${SRCS}
+ (u=$${USER-root} d=`pwd |sed -e 's|/obj/|/src/|'` \
+ h=`hostname` t=`date`; \
+ sed -e "s|%WHEN%|$${t}|" -e "s|%VERSION%|"${VER}"|" \
+ -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \
+ < ${.CURDIR}/../Version.c > version.c)
+
.include "../../Makefile.inc"
.include <bsd.prog.mk>
diff --git a/usr.sbin/named/xfer/named-xfer.c b/usr.sbin/named/xfer/named-xfer.c
index 74f65ea1f5fdf..f9533a751b785 100644
--- a/usr.sbin/named/xfer/named-xfer.c
+++ b/usr.sbin/named/xfer/named-xfer.c
@@ -70,17 +70,24 @@ char copyright[] =
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)named-xfer.c 4.18 (Berkeley) 3/7/91";
-static char rcsid[] = "$Id: named-xfer.c,v 1.2 1994/09/22 20:45:34 pst Exp $";
+static char rcsid[] = "$Id: named-xfer.c,v 1.3 1995/05/30 03:49:10 rgrimes Exp $";
#endif /* not lint */
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/socket.h>
-#include <sys/time.h>
#include <netinet/in.h>
#include <netiso/iso.h>
+#if defined(__osf__)
+# include <sys/mbuf.h>
+# include <net/route.h>
+#endif
+#if defined(_AIX)
+# include <sys/time.h>
+# define TIME_H_INCLUDED
+#endif
#include <net/if.h>
#include <netdb.h>
#include <arpa/inet.h>
@@ -91,6 +98,7 @@ static char rcsid[] = "$Id: named-xfer.c,v 1.2 1994/09/22 20:45:34 pst Exp $";
#include <stdio.h>
#include <syslog.h>
#include <math.h>
+#include <ctype.h>
#include <signal.h>
#define MAIN_PROGRAM
@@ -110,18 +118,20 @@ static char ddtfilename[] = _PATH_TMPXFER,
static int quiet = 0,
read_interrupted = 0,
+ curclass,
domain_len; /* strlen(domain) */
static FILE *fp = NULL,
*dbfp = NULL;
+static char *ProgName;
+
static void usage __P((const char *));
static int getzone __P((struct zoneinfo *, u_int32_t, int)),
- soa_zinfo __P((struct zoneinfo *, u_char *, u_char *)),
print_output __P((u_char *, int, u_char *)),
netread __P((int, char *, int, int));
-static SIG_FN read_alarm __P((void));
-static char *ProgName;
+static SIG_FN read_alarm __P(());
+static const char *soa_zinfo __P((struct zoneinfo *, u_char *, u_char*));
extern char *optarg;
extern int optind, getopt();
@@ -257,7 +267,7 @@ main(argc, argv)
perror(tmpname);
if (!quiet)
syslog(LOG_ERR, "can't make tmpfile (%s): %m\n",
- tmpname);
+ tmpname);
exit(XFER_FAIL);
}
#if HAVE_FCHMOD
@@ -269,7 +279,7 @@ main(argc, argv)
perror(tmpname);
if (!quiet)
syslog(LOG_ERR, "can't [f]chmod tmpfile (%s): %m\n",
- tmpname);
+ tmpname);
exit(XFER_FAIL);
}
if ((dbfp = fdopen(dbfd, "r+")) == NULL) {
@@ -297,7 +307,7 @@ main(argc, argv)
perror(ddtfile);
debug = 0;
} else {
-#if defined(SYSV)
+#ifdef HAVE_SETVBUF
setvbuf(ddt, NULL, _IOLBF, BUFSIZ);
#else
setlinebuf(ddt);
@@ -333,7 +343,7 @@ main(argc, argv)
dprintf(1, (ddt,
"domain `%s'; file `%s'; serial %lu; closed %d\n",
- domain, dbfile, serial_no, closed));
+ domain, dbfile, (u_long)serial_no, closed));
buildservicelist();
buildprotolist();
@@ -360,7 +370,7 @@ main(argc, argv)
: zp->z_origin,
zp->z_source));
- for (; optind != argc; optind++, zp->z_addrcnt++) {
+ for (; optind != argc; optind++) {
tm = argv[optind];
if (!inet_aton(tm, &zp->z_addr[zp->z_addrcnt])) {
hp = gethostbyname(tm);
@@ -368,7 +378,6 @@ main(argc, argv)
syslog(LOG_NOTICE,
"uninterpretable server (%s) for %s\n",
tm, zp->z_origin);
- zp->z_addrcnt--; /* hack */
continue;
}
bcopy(hp->h_addr,
@@ -378,12 +387,11 @@ main(argc, argv)
}
if (zp->z_addr[zp->z_addrcnt].s_addr == 0) {
syslog(LOG_NOTICE,
- "SOA query to localhost (%s) for %s",
+ "SOA query to 0.0.0.0 (%s) for %s",
tm, zp->z_origin);
- zp->z_addrcnt--; /* hack */
continue;
}
- if (zp->z_addrcnt >= NSMAX) {
+ if (++zp->z_addrcnt >= NSMAX) {
zp->z_addrcnt = NSMAX;
dprintf(1, (ddt, "NSMAX reached\n"));
break;
@@ -401,7 +409,7 @@ main(argc, argv)
perror("rename");
if (!quiet)
syslog(LOG_ERR, "rename %s to %s: %m",
- tmpname, dbfile);
+ tmpname, dbfile);
exit(XFER_FAIL);
}
exit(XFER_SUCCESS);
@@ -477,10 +485,11 @@ getzone(zp, serial_no, port)
HEADER *hp;
u_int16_t len;
u_int32_t serial;
- int s, n, l, cnt, nscnt, soacnt, error = 0;
+ int s, n, l, nscnt, soacnt, error = 0;
+ u_int cnt;
u_char *cp, *nmp, *eom, *tmp ;
u_char *buf = NULL;
- int bufsize;
+ u_int bufsize;
char name[MAXDNAME], name2[MAXDNAME];
struct sockaddr_in sin;
struct zoneinfo zp_start, zp_finish;
@@ -489,8 +498,9 @@ getzone(zp, serial_no, port)
#else
struct sigvec sv, osv;
#endif
- int ancount, aucount;
- int Class;
+ int qdcount, ancount, aucount, class, type;
+ const char *badsoa_msg = "Nil";
+
#ifdef DEBUG
if (debug) {
(void)fprintf(ddt,"getzone() %s ", zp->z_origin);
@@ -507,15 +517,16 @@ getzone(zp, serial_no, port)
}
#endif
#ifdef POSIX_SIGNALS
- sv.sa_handler = read_alarm;
+ bzero((char *)&sv, sizeof sv);
+ sv.sa_handler = (SIG_FN (*)()) read_alarm;
/* SA_ONSTACK isn't recommended for strict POSIX code */
/* is it absolutely necessary? */
/* sv.sa_flags = SA_ONSTACK; */
sigfillset(&sv.sa_mask);
(void) sigaction(SIGALRM, &sv, &osv);
#else
+ bzero((char *)&sv, sizeof sv);
sv.sv_handler = read_alarm;
- sv.sv_onstack = 0;
sv.sv_mask = ~0;
(void) sigvec(SIGALRM, &sv, &osv);
#endif
@@ -527,14 +538,14 @@ getzone(zp, serial_no, port)
for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {
#ifdef GEN_AXFR
- Class = zp->z_class;
+ curclass = zp->z_class;
#else
- Class = C_IN;
+ curclass = C_IN;
#endif
error = 0;
if (buf == NULL) {
if ((buf = (u_char *)malloc(2 * PACKETSZ)) == NULL) {
- syslog(LOG_ERR, "malloc(%u) failed",
+ syslog(LOG_INFO, "malloc(%u) failed",
2 * PACKETSZ);
error++;
break;
@@ -546,7 +557,7 @@ getzone(zp, serial_no, port)
sin.sin_port = (u_int16_t)port;
sin.sin_addr = zp->z_addr[cnt];
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- syslog(LOG_ERR, "socket: %m");
+ syslog(LOG_INFO, "socket: %m");
error++;
break;
}
@@ -554,18 +565,22 @@ getzone(zp, serial_no, port)
cnt+1, inet_ntoa(sin.sin_addr),
ntohs(sin.sin_port)));
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- syslog(LOG_ERR, "connect(%s) failed: %m",
- inet_ntoa(sin.sin_addr));
+ if (!quiet)
+ syslog(LOG_INFO,
+ "connect(%s) for zone %s failed: %m",
+ inet_ntoa(sin.sin_addr), zp->z_origin);
error++;
(void) my_close(s);
continue;
- }
-tryagain:
- n = res_mkquery(QUERY, zp->z_origin, Class,
+ }
+#ifndef GEN_AXFR
+ tryagain:
+#endif
+ n = res_mkquery(QUERY, zp->z_origin, curclass,
T_SOA, NULL, 0, NULL, buf, bufsize);
if (n < 0) {
if (!quiet)
- syslog(LOG_NOTICE,
+ syslog(LOG_INFO,
"zone %s: res_mkquery T_SOA failed",
zp->z_origin);
(void) my_close(s);
@@ -580,7 +595,7 @@ tryagain:
* Send length & message for SOA query
*/
if (writemsg(s, buf, n) < 0) {
- syslog(LOG_ERR, "writemsg: %m");
+ syslog(LOG_INFO, "writemsg: %m");
error++;
(void) my_close(s);
continue;
@@ -599,7 +614,7 @@ tryagain:
}
if (len > bufsize) {
if ((buf = (u_char *)realloc(buf, len)) == NULL) {
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"malloc(%u) failed for SOA from server [%s], zone %s\n",
len,
inet_ntoa(sin.sin_addr),
@@ -617,29 +632,31 @@ tryagain:
#ifdef DEBUG
if (debug >= 3) {
(void)fprintf(ddt,"len = %d\n", len);
- fp_query(buf, ddt);
+ fp_nquery(buf, len, ddt);
}
#endif
hp = (HEADER *) buf;
+ qdcount = ntohs(hp->qdcount);
ancount = ntohs(hp->ancount);
aucount = ntohs(hp->nscount);
/*
- * close socket if:
+ * close socket if any of these apply:
* 1) rcode != NOERROR
* 2) not an authority response
- * 3) both the number of answers and authority count < 1)
+ * 3) not an answer to our question
+ * 4) both the number of answers and authority count < 1)
*/
- if (hp->rcode != NOERROR || !(hp->aa) ||
+ if (hp->rcode != NOERROR || !hp->aa || qdcount != 1 ||
(ancount < 1 && aucount < 1)) {
#ifndef GEN_AXFR
- if (Class == C_IN) {
+ if (curclass == C_IN) {
dprintf(1, (ddt, "SOA failed, trying C_HS\n"));
- Class = C_HS;
+ curclass = C_HS;
goto tryagain;
}
#endif
- syslog(LOG_NOTICE,
+ syslog(LOG_INFO,
"%s from [%s], zone %s: rcode %d, aa %d, ancount %d, aucount %d\n",
"bad response to SOA query",
inet_ntoa(sin.sin_addr), zp->z_origin,
@@ -649,37 +666,88 @@ tryagain:
continue;
}
zp_start = *zp;
- if (len < HFIXEDSZ + QFIXEDSZ) {
- badsoa:
- syslog(LOG_NOTICE,
- "malformed SOA from [%s], zone %s: too short\n",
- inet_ntoa(sin.sin_addr), zp->z_origin);
+ if ((int)len < HFIXEDSZ + QFIXEDSZ) {
+ badsoa_msg = "too short";
+ badsoa:
+ syslog(LOG_INFO,
+ "malformed SOA from [%s], zone %s: %s",
+ inet_ntoa(sin.sin_addr), zp->z_origin,
+ badsoa_msg);
error++;
(void) my_close(s);
continue;
}
+ /*
+ * Step through response.
+ */
tmp = buf + HFIXEDSZ;
eom = buf + len;
- if ((n = dn_skipname(tmp, eom)) == -1)
+ /* Query Section. */
+ n = dn_expand(buf, eom, tmp, name2, sizeof name2);
+ if (n < 0) {
+ badsoa_msg = "qname error";
goto badsoa;
- tmp += n + QFIXEDSZ;
- if ((n = dn_skipname(tmp, eom)) == -1)
+ }
+ tmp += n;
+ GETSHORT(type, tmp);
+ GETSHORT(class, tmp);
+ if (class != curclass || type != T_SOA ||
+ strcasecmp(zp->z_origin, name2) != 0) {
+ syslog(LOG_INFO,
+ "wrong query in resp from [%s], zone %s: [%s %s %s]\n",
+ inet_ntoa(sin.sin_addr), zp->z_origin,
+ name2, p_class(class), p_type(type));
+ error++;
+ (void) my_close(s);
+ continue;
+ }
+ /* ... Answer Section. */
+ n = dn_expand(buf, eom, tmp, name2, sizeof name2);
+ if (n < 0) {
+ badsoa_msg = "aname error";
goto badsoa;
+ }
tmp += n;
- if (soa_zinfo(&zp_start, tmp, eom) == -1)
+ if (strcasecmp(zp->z_origin, name2) != 0) {
+ syslog(LOG_INFO,
+ "wrong answer in resp from [%s], zone %s: [%s %s %s]\n",
+ inet_ntoa(sin.sin_addr), zp->z_origin,
+ name2, p_class(class), p_type(type));
+ error++;
+ (void) my_close(s);
+ continue;
+ }
+ badsoa_msg = soa_zinfo(&zp_start, tmp, eom);
+ if (badsoa_msg)
goto badsoa;
if (SEQ_GT(zp_start.z_serial, serial_no) || !serial_no) {
- dprintf(1, (ddt, "need update, serial %d\n",
- zp_start.z_serial));
+ const char *l, *nl;
+ dprintf(1, (ddt, "need update, serial %lu\n",
+ (u_long)zp_start.z_serial));
hp = (HEADER *) buf;
soacnt = 0;
nscnt = 0;
- gettime (&tt);
- (void) fprintf (dbfp, "; zone '%s' last serial %lu\n",
- domain, serial_no);
- (void) fprintf (dbfp, "; from %s at %s",
- inet_ntoa (sin.sin_addr),
- ctime (&tt.tv_sec));
+ gettime(&tt);
+ for (l = Version; l; l = nl) {
+ size_t len;
+ if ((nl = strchr(l, '\n')) != NULL) {
+ len = nl - l;
+ nl = nl + 1;
+ } else {
+ len = strlen(l);
+ nl = NULL;
+ }
+ while (isspace((unsigned char) *l))
+ l++;
+ if (*l)
+ fprintf(dbfp, "; BIND version %.*s\n",
+ (int)len, l);
+ }
+ fprintf(dbfp, "; zone '%s' last serial %lu\n",
+ domain, (u_long)serial_no);
+ fprintf(dbfp, "; from %s at %s",
+ inet_ntoa(sin.sin_addr),
+ ctimel(tt.tv_sec));
for (;;) {
if ((soacnt == 0) || (zp->z_type == Z_STUB)) {
int type;
@@ -695,20 +763,21 @@ tryagain:
#endif
type = T_AXFR;
n = res_mkquery(QUERY, zp->z_origin,
- Class, type, NULL, 0,
+ curclass, type,
+ NULL, 0,
NULL, buf, bufsize);
if (n < 0) {
if (!quiet) {
#ifdef STUBS
if (zp->z_type == Z_STUB)
- syslog(LOG_NOTICE,
+ syslog(LOG_INFO,
(type == T_SOA)
? "zone %s: res_mkquery T_SOA failed"
: "zone %s: res_mkquery T_NS failed",
zp->z_origin);
else
#endif
- syslog(LOG_NOTICE,
+ syslog(LOG_INFO,
"zone %s: res_mkquery T_AXFR failed",
zp->z_origin);
}
@@ -726,7 +795,8 @@ tryagain:
* Send length & msg for zone transfer
*/
if (writemsg(s, buf, n) < 0) {
- syslog(LOG_ERR,"writemsg: %m");
+ syslog(LOG_INFO,
+ "writemsg: %m");
error++;
(void) my_close(s);
break;
@@ -752,15 +822,15 @@ tryagain:
#ifdef DEBUG
if (debug >= 3) {
(void)fprintf(ddt,"len = %d\n", len);
- fp_query(buf, ddt);
+ fp_nquery(buf, len, ddt);
}
if (fp)
- fp_query(buf, fp);
+ fp_nquery(buf, len, fp);
#endif
if (len < HFIXEDSZ) {
badrec:
error++;
- syslog(LOG_NOTICE,
+ syslog(LOG_INFO,
"record too short from [%s], zone %s\n",
inet_ntoa(sin.sin_addr),
zp->z_origin);
@@ -799,8 +869,8 @@ tryagain:
cp += n;
}
if (cp != eom) {
- syslog(LOG_ERR,
- "print_output: short answer (%d, %d), zone %s",
+ syslog(LOG_INFO,
+ "print_output: short answer (%d, %d), zone %s",
cp - buf, n, zp->z_origin);
error++;
break;
@@ -810,8 +880,8 @@ tryagain:
#endif /*STUBS*/
n = print_output(buf, bufsize, cp);
if (cp + n != eom) {
- syslog(LOG_ERR,
- "print_output: short answer (%d, %d), zone %s",
+ syslog(LOG_INFO,
+ "print_output: short answer (%d, %d), zone %s",
cp - buf, n, zp->z_origin);
error++;
break;
@@ -823,46 +893,63 @@ tryagain:
if (n == T_SOA) {
if (soacnt == 0) {
soacnt++;
- if (dn_expand(buf, buf + 512, nmp,
- name, sizeof name) == -1)
+ if (dn_expand(buf, buf+PACKETSZ, nmp,
+ name, sizeof name) < 0) {
+ badsoa_msg = "soa name error";
goto badsoa;
+ }
+ if (strcasecmp(name, zp->z_origin)!=0){
+ syslog(LOG_INFO,
+ "wrong zone name in AXFR (wanted \"%s\", got \"%s\")",
+ zp->z_origin, name);
+ badsoa_msg = "wrong soa name";
+ goto badsoa;
+ }
if (eom - tmp
- <= 2 * INT16SZ
- + INT32SZ) {
+ <= 2 * INT16SZ + INT32SZ) {
+ badsoa_msg = "soa header";
goto badsoa;
}
- tmp += 2 * INT16SZ
- + INT32SZ;
- if ((n = dn_skipname(tmp, eom)) == -1)
+ tmp += 2 * INT16SZ + INT32SZ;
+ if ((n = dn_skipname(tmp, eom)) < 0) {
+ badsoa_msg = "soa mname";
goto badsoa;
+ }
tmp += n;
- if ((n = dn_skipname(tmp, eom)) == -1)
+ if ((n = dn_skipname(tmp, eom)) < 0) {
+ badsoa_msg = "soa hname";
goto badsoa;
+ }
tmp += n;
- if (eom - tmp <= INT32SZ)
+ if (eom - tmp <= INT32SZ) {
+ badsoa_msg = "soa dlen";
goto badsoa;
+ }
GETLONG(serial, tmp);
dprintf(3, (ddt,
- "first SOA for %s, serial %d\n",
- name, serial));
+ "first SOA for %s, serial %lu\n",
+ name, (u_long)serial));
continue;
}
- if (dn_expand(buf, buf + 512, nmp,
- name2, sizeof name2) == -1)
+ if (dn_expand(buf, buf+PACKETSZ, nmp,
+ name2, sizeof name2) == -1) {
+ badsoa_msg = "soa name error#2";
goto badsoa;
+ }
if (strcasecmp((char *)name,
(char *)name2) != 0) {
- dprintf(2, (ddt,
- "extraneous SOA for %s\n",
- name2));
+ syslog(LOG_INFO,
+ "got extra SOA for \"%s\" in zone \"%s\"",
+ name2, name);
continue;
}
- tmp -= INT16SZ;
- if (soa_zinfo(&zp_finish, tmp, eom) == -1)
+ tmp -= INT16SZ; /* Put TYPE back. */
+ badsoa_msg = soa_zinfo(&zp_finish, tmp, eom);
+ if (badsoa_msg)
goto badsoa;
dprintf(2, (ddt,
- "SOA, serial %d\n",
- zp_finish.z_serial));
+ "SOA, serial %lu\n",
+ (u_long)zp_finish.z_serial));
if (serial != zp_finish.z_serial) {
soacnt = 0;
got_soa = 0;
@@ -879,9 +966,9 @@ tryagain:
fflush(dbfp);
if (ftruncate(fileno(dbfp), 0) != 0) {
if (!quiet)
- syslog(LOG_ERR,
- "ftruncate %s: %m\n",
- tmpname);
+ syslog(LOG_INFO,
+ "ftruncate %s: %m\n",
+ tmpname);
return (XFER_FAIL);
}
fseek(dbfp, 0L, 0);
@@ -952,7 +1039,7 @@ netread(fd, buf, len, timeout)
static const char setitimerStr[] = "setitimer: %m";
struct itimerval ival, zeroival;
register int n;
-#if defined(sun)
+#if defined(NETREAD_BROKEN)
int retries = 0;
#endif
@@ -961,64 +1048,86 @@ netread(fd, buf, len, timeout)
ival.it_value.tv_sec = timeout;
while (len > 0) {
if (setitimer(ITIMER_REAL, &ival, NULL) < 0) {
- syslog(LOG_ERR, setitimerStr);
+ syslog(LOG_INFO, setitimerStr);
return (-1);
}
errno = 0;
n = recv(fd, buf, len, 0);
- if (n <= 0) {
+ if (n == 0 && errno == 0) {
+#if defined(NETREAD_BROKEN)
+ if (++retries < 42) /* doug adams */
+ continue;
+#endif
+ syslog(LOG_INFO, "premature EOF, fetching \"%s\"",
+ domain);
+ return (-1);
+ }
+ if (n < 0) {
if (errno == 0) {
-#if defined(sun)
+#if defined(NETREAD_BROKEN)
if (++retries < 42) /* doug adams */
continue;
#endif
- syslog(LOG_ERR,
+ syslog(LOG_INFO,
"recv(len=%d): n=%d && !errno",
len, n);
return (-1);
}
- if (errno == EINTR && !read_interrupted) {
- /* Some other signal returned; ignore it. */
- continue;
+ if (errno == EINTR) {
+ if (!read_interrupted) {
+ /* It wasn't a timeout; ignore it. */
+ continue;
+ }
+ errno = ETIMEDOUT;
}
- syslog(LOG_ERR, "recv(len=%d): %m", len);
+ syslog(LOG_INFO, "recv(len=%d): %m", len);
return (-1);
}
buf += n;
len -= n;
}
if (setitimer(ITIMER_REAL, &zeroival, NULL) < 0) {
- syslog(LOG_ERR, setitimerStr);
+ syslog(LOG_INFO, setitimerStr);
return (-1);
}
return (0);
}
-static int
+static const char *
soa_zinfo(zp, cp, eom)
register struct zoneinfo *zp;
register u_char *cp;
u_char *eom;
{
register int n;
+ int type, class;
+ u_long ttl;
+ /* Are type, class, and ttl OK? */
if (eom - cp < 3 * INT16SZ + INT32SZ)
- return (-1);
- cp += 3 * INT16SZ + INT32SZ;
+ return ("zinfo too short");
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ GETLONG(ttl, cp);
+ cp += INT16SZ; /* dlen */
+ if (type != T_SOA || class != curclass || ttl == 0)
+ return ("zinfo wrong typ/cla/ttl");
+ /* Skip master name and contact name, we can't validate them. */
if ((n = dn_skipname(cp, eom)) == -1)
- return (-1);
+ return ("zinfo mname");
cp += n;
if ((n = dn_skipname(cp, eom)) == -1)
- return (-1);
+ return ("zinfo hname");
cp += n;
+ /* Grab the data fields. */
if (eom - cp < 5 * INT32SZ)
- return (-1);
+ return ("zinfo dlen");
GETLONG(zp->z_serial, cp);
GETLONG(zp->z_refresh, cp);
GETLONG(zp->z_retry, cp);
GETLONG(zp->z_expire, cp);
GETLONG(zp->z_minimum, cp);
- return (0);
+ return (NULL);
}
/*
@@ -1041,9 +1150,6 @@ print_output(msg, msglen, rrp)
u_char *cp1, *cp2, *temp_ptr;
char *cdata, *origin, *proto, dname[MAXDNAME];
char *ignore = "";
-#ifdef NO_GLUE
- int lend, lenn;
-#endif /*NO_GLUE*/
cp = rrp;
n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname);
@@ -1076,6 +1182,8 @@ print_output(msg, msglen, rrp)
case T_TXT:
case T_X25:
case T_ISDN:
+ case T_LOC:
+ case T_NSAP:
case T_UID:
case T_GID:
cp1 = cp;
@@ -1154,15 +1262,42 @@ print_output(msg, msglen, rrp)
cp1 = (u_char *)data;
break;
+ case T_PX:
+ /* grab preference */
+ bcopy((char *)cp, data, INT16SZ);
+ cp1 = (u_char *)data + INT16SZ;
+ cp += INT16SZ;
+
+ /* get MAP822 name */
+ n = dn_expand(msg, msg + msglen, cp,
+ (char *)cp1, sizeof data - INT16SZ);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ cp1 += (n = (strlen((char *) cp1) + 1));
+ n1 = sizeof data - n;
+
+ /* get MAPX400 name */
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
+ if (n < 0)
+ return (-1);
+
+ cp1 += strlen((char *) cp1) + 1;
+ n = cp1 - (u_char *)data;
+ cp1 = (u_char *)data;
+ break;
+
default:
- dprintf(3, (ddt, "unknown type %d\n", type));
- return ((cp - rrp) + dlen);
+ syslog(LOG_INFO, "\"%s %s %s\" - unknown type (%d)",
+ dname, p_class(class), p_type(type), type);
+ hp->rcode = NOTIMP;
+ return (-1);
}
if (n > MAXDATA) {
dprintf(1, (ddt,
"update type %d: %d bytes is too much data\n",
type, n));
- hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */
+ hp->rcode = FORMERR;
return (-1);
}
cdata = (char *) cp1;
@@ -1261,7 +1396,7 @@ print_output(msg, msglen, rrp)
ignore, origin); /* ??? */
} else
(void) fprintf(dbfp, "%s%s\t", ignore, dname);
- if (strlen(dname) < 8)
+ if (strlen(dname) < (size_t)8)
tab = 1;
} else {
(void) fprintf(dbfp, "%s\t", ignore);
@@ -1287,8 +1422,7 @@ print_output(msg, msglen, rrp)
case C_HS:
GETLONG(n, cp);
n = htonl(n);
- (void) fprintf(dbfp, "%s",
- inet_ntoa(*(struct in_addr *) & n));
+ fputs(inet_ntoa(*(struct in_addr *) &n), dbfp);
break;
}
(void) fprintf(dbfp, "\n");
@@ -1317,37 +1451,31 @@ print_output(msg, msglen, rrp)
case T_HINFO:
case T_ISDN:
cp2 = cp + n;
- n = *cp++;
- cp1 = cp + n;
- if (cp1 > cp2)
- cp1 = cp2;
- (void) putc('"', dbfp);
- while (cp < cp1) {
- if (*cp == '\0') {
- cp = cp1;
- break;
- }
- if ((*cp == '\n') || (*cp == '"')) {
- (void) putc('\\', dbfp);
- }
- (void) putc(*cp++, dbfp);
- }
- (void) fputs("\" \"", dbfp);
- n = *cp++;
- cp1 = cp + n;
- if (cp1 > cp2)
- cp1 = cp2;
- while (cp < cp1) {
- if (*cp == '\0') {
- cp = cp1;
- break;
- }
- if ((*cp == '\n') || (*cp == '"')) {
- (void) putc('\\', dbfp);
+ for (i = 0; i < 2; i++) {
+ if (i != 0)
+ (void) putc(' ', dbfp);
+ n = *cp++;
+ cp1 = cp + n;
+ if (cp1 > cp2)
+ cp1 = cp2;
+ (void) putc('"', dbfp);
+ j = 0;
+ while (cp < cp1) {
+ if (*cp == '\0') {
+ cp = cp1;
+ break;
+ }
+ if ((*cp == '\n') || (*cp == '"')) {
+ (void) putc('\\', dbfp);
+ }
+ (void) putc(*cp++, dbfp);
+ j++;
}
- (void) putc(*cp++, dbfp);
+ if (j == 0 && (type != T_ISDN || i == 0))
+ (void) putc('?', dbfp);
+ (void) putc('"', dbfp);
}
- (void) fputs("\"\n", dbfp);
+ (void) putc('\n', dbfp);
break;
case T_SOA:
@@ -1356,22 +1484,30 @@ print_output(msg, msglen, rrp)
(void) fprintf(dbfp, " %s. (\n", cp);
cp += strlen((char *) cp) + 1;
GETLONG(n, cp);
- (void) fprintf(dbfp, "%s\t\t%lu", ignore, n);
+ (void) fprintf(dbfp, "%s\t\t%lu", ignore, (u_long)n);
GETLONG(n, cp);
- (void) fprintf(dbfp, " %lu", n);
+ (void) fprintf(dbfp, " %lu", (u_long)n);
GETLONG(n, cp);
- (void) fprintf(dbfp, " %lu", n);
+ (void) fprintf(dbfp, " %lu", (u_long)n);
GETLONG(n, cp);
- (void) fprintf(dbfp, " %lu", n);
+ (void) fprintf(dbfp, " %lu", (u_long)n);
GETLONG(n, cp);
- (void) fprintf(dbfp, " %lu )\n", n);
+ (void) fprintf(dbfp, " %lu )\n", (u_long)n);
break;
case T_MX:
case T_AFSDB:
case T_RT:
GETSHORT(n, cp);
- (void) fprintf(dbfp, "%lu", n);
+ (void) fprintf(dbfp, "%lu", (u_long)n);
+ (void) fprintf(dbfp, " %s.\n", cp);
+ break;
+
+ case T_PX:
+ GETSHORT(n, cp);
+ (void) fprintf(dbfp, "%lu", (u_long)n);
+ (void) fprintf(dbfp, " %s.", cp);
+ cp += strlen((char *) cp) + 1;
(void) fprintf(dbfp, " %s.\n", cp);
break;
@@ -1404,19 +1540,25 @@ print_output(msg, msglen, rrp)
(void) fprintf(dbfp, "\"%s\"\n", cp);
break;
+#ifdef LOC_RR
+ case T_LOC:
+ (void) fprintf(dbfp, "%s\n", loc_ntoa(cp, NULL));
+ break;
+#endif /* LOC_RR */
+
case T_UID:
case T_GID:
if (n == INT32SZ) {
GETLONG(n, cp);
- (void) fprintf(dbfp, "%lu\n", n);
+ (void) fprintf(dbfp, "%lu\n", (u_long)n);
}
break;
case T_WKS:
GETLONG(addr, cp);
addr = htonl(addr);
- (void) fprintf(dbfp, "%s ",
- inet_ntoa(*(struct in_addr *) & addr));
+ fputs(inet_ntoa(*(struct in_addr *) &addr), dbfp);
+ fputc(' ', dbfp);
proto = protocolname(*cp);
cp += sizeof(char);
(void) fprintf(dbfp, "%s ", proto);
@@ -1426,7 +1568,7 @@ print_output(msg, msglen, rrp)
do {
if (j & 0200)
(void) fprintf(dbfp, " %s",
- servicename(i, proto));
+ servicename(i, proto));
j <<= 1;
} while (++i & 07);
}
diff --git a/usr.sbin/nslookup/debug.c b/usr.sbin/nslookup/debug.c
index 9f63873c1ecea..24a5ca7e60fc0 100644
--- a/usr.sbin/nslookup/debug.c
+++ b/usr.sbin/nslookup/debug.c
@@ -55,7 +55,7 @@
#ifndef lint
static char sccsid[] = "@(#)debug.c 5.26 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: debug.c,v 1.2 1994/09/22 21:50:31 pst Exp $";
+static char rcsid[] = "$Id: debug.c,v 1.3 1995/05/30 03:49:13 rgrimes Exp $";
#endif /* not lint */
/*
@@ -140,8 +140,6 @@ Fprint_query(msg, eom, printHeader,file)
fprintf(file,", want recursion");
if (hp->ra)
fprintf(file,", recursion avail.");
- if (hp->pr)
- fprintf(file,", primary");
fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
fprintf(file,", answers = %d", ntohs(hp->ancount));
fprintf(file,", authority records = %d", ntohs(hp->nscount));
@@ -335,6 +333,15 @@ Print_rr(cp, msg, eom, file)
cp += INT16SZ;
fprintf(file,", mail exchanger = ");
goto doname;
+ case T_PX:
+ fprintf(file,"\tpreference = %u",_getshort((u_char*)cp));
+ cp += INT16SZ;
+ fprintf(file,", RFC 822 = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ fprintf(file,"\nX.400 = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ (void) putc('\n', file);
+ break;
case T_RT:
fprintf(file,"\tpreference = %u",_getshort((u_char*)cp));
cp += INT16SZ;
@@ -356,22 +363,24 @@ doname:
break;
case T_HINFO:
+ cp2 = cp + dlen;
if (n = *cp++) {
fprintf(file,"\tCPU = %.*s", n, cp);
cp += n;
}
- if (n = *cp++) {
+ if ((cp < cp2) && (n = *cp++)) {
fprintf(file,"\tOS = %.*s\n", n, cp);
cp += n;
- }
+ } else fprintf(file, "\n*** Warning *** OS-type missing\n");
break;
case T_ISDN:
+ cp2 = cp + dlen;
if (n = *cp++) {
fprintf(file,"\tISDN = \"%.*s", n, cp);
cp += n;
}
- if (n = *cp++) {
+ if ((cp < cp2) && (n = *cp++)) {
fprintf(file,"-%.*s\"\n", n, cp);
cp += n;
} else fprintf(file,"\"\n");
@@ -427,7 +436,7 @@ doname:
while (cp < cp2) {
if (n = (unsigned char) *cp++) {
for (c = n; c > 0 && cp < cp2; c--)
- if (*cp == '\n') {
+ if ((*cp == '\n') || (*cp == '"')) {
(void) putc('\\', file);
(void) putc(*cp++, file);
} else
diff --git a/usr.sbin/nslookup/list.c b/usr.sbin/nslookup/list.c
index bc187fad8ddc7..da9c7e07fb8bf 100644
--- a/usr.sbin/nslookup/list.c
+++ b/usr.sbin/nslookup/list.c
@@ -55,7 +55,7 @@
#ifndef lint
static char sccsid[] = "@(#)list.c 5.23 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: list.c,v 1.2 1994/09/22 21:50:34 pst Exp $";
+static char rcsid[] = "$Id: list.c,v 1.3 1995/05/30 03:49:15 rgrimes Exp $";
#endif /* not lint */
/*
@@ -204,6 +204,8 @@ ListHosts(string, putToFile)
qtype = T_HINFO;
} else if (strcmp("-m", option) == 0) {
qtype = T_MX;
+ } else if (strcmp("-p", option) == 0) {
+ qtype = T_PX;
} else if (strcmp("-s", option) == 0) {
qtype = T_WKS;
} else if (strcmp("-d", option) == 0) {
@@ -357,6 +359,9 @@ ListSubr(qtype, domain, cmd)
case T_MX:
fprintf(filePtr, " %-30s\n", "Metric & Host");
break;
+ case T_PX:
+ fprintf(filePtr, " %-30s\n", "Mapping information");
+ break;
case T_AFSDB:
fprintf(filePtr, " %-30s\n", "Subtype & Host");
break;
@@ -402,6 +407,9 @@ ListSubr(qtype, domain, cmd)
case T_NSAP:
fprintf(filePtr, " %-30s\n", "NSAP address");
break;
+ case T_NSAP_PTR:
+ fprintf(filePtr, " %-30s\n", "NSAP pointer");
+ break;
case T_NS:
fprintf(filePtr, " %-30s\n", "Name Servers");
break;
@@ -446,7 +454,7 @@ ListSubr(qtype, domain, cmd)
* The server sent too much data to fit the existing buffer --
* allocate a new one.
*/
- if (len > answerLen) {
+ if (len > (u_int)answerLen) {
if (answerLen != 0) {
free(answer);
}
@@ -688,6 +696,7 @@ PrintListInfo(file, msg, eom, qtype, domain)
case T_NS:
case T_PTR:
+ case T_NSAP_PTR:
putc(' ', file);
if (qtype != T_ANY)
fprintf(file,"%s = ", type == T_PTR ? "host" : "server");
@@ -696,16 +705,21 @@ PrintListInfo(file, msg, eom, qtype, domain)
case T_HINFO:
case T_ISDN:
- if (n = *cp++) {
- (void)sprintf(name,"%.*s", n, cp);
- fprintf(file," %-10s", name);
- cp += n;
- } else {
- fprintf(file," %-10s", " ");
- }
- if (n = *cp++) {
- fprintf(file," %.*s", n, cp);
- cp += n;
+ {
+ u_char *cp2 = cp + dlen;
+ if (n = *cp++) {
+ (void)sprintf(name,"%.*s", n, cp);
+ fprintf(file," %-10s", name);
+ cp += n;
+ } else {
+ fprintf(file," %-10s", " ");
+ }
+ if (cp == cp2)
+ break;
+ if (n = *cp++) {
+ fprintf(file," %.*s", n, cp);
+ cp += n;
+ }
}
break;
@@ -748,6 +762,25 @@ PrintListInfo(file, msg, eom, qtype, domain)
fprintf(file, " %s", name2);
break;
+ case T_PX:
+ pref = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ fprintf(file," %-3d ",pref);
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ fprintf(file, " %s", name2);
+ cp += strlen((char *)cp) + 1;
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ fprintf(file, " %s", name2);
+ break;
+
case T_TXT:
case T_X25:
{
@@ -758,7 +791,7 @@ PrintListInfo(file, msg, eom, qtype, domain)
while (cp < cp2) {
if (n = (unsigned char) *cp++) {
for (c = n; c > 0 && cp < cp2; c--)
- if (*cp == '\n') {
+ if ((*cp == '\n') || (*cp == '"')) {
(void) putc('\\', file);
(void) putc(*cp++, file);
} else
diff --git a/usr.sbin/nslookup/nslookup.help b/usr.sbin/nslookup/nslookup.help
index 2c17d4d1b4869..1e8b97c9d814e 100644
--- a/usr.sbin/nslookup/nslookup.help
+++ b/usr.sbin/nslookup/nslookup.help
@@ -1,4 +1,4 @@
-$Id: nslookup.help,v 4.9.1.3 1993/12/06 00:43:17 vixie Exp $
+$Id: nslookup.help,v 1.1.1.1 1994/09/22 21:36:02 pst Exp $
Commands: (identifiers are shown in uppercase, [] means optional)
NAME - print info about the host/domain NAME using default server
@@ -16,12 +16,12 @@ set OPTION - set an option
root=NAME - set root server to NAME
retry=X - set number of retries to X
timeout=X - set initial time-out interval to X seconds
- querytype=X - set query type, e.g., A,ANY,CNAME,HINFO,MX,NS,PTR,SOA,TXT,WKS
+ querytype=X - set query type, e.g., A,ANY,CNAME,HINFO,MX,PX,NS,PTR,SOA,TXT,WKS
type=X - synonym for querytype
class=X - set query class to one of IN (Internet), CHAOS, HESIOD or ANY
server NAME - set default server to NAME, using current default server
lserver NAME - set default server to NAME, using initial server
-finger [USER] - finger the optional NAME at the current default host
+finger [USER] - finger the optional USER at the current default host
root - set current default server to the root
ls [opt] DOMAIN [> FILE] - list addresses in DOMAIN (optional: output to FILE)
-a - list canonical names and aliases
diff --git a/usr.sbin/nslookup/subr.c b/usr.sbin/nslookup/subr.c
index 9f86d1502e9d0..d7cca0e2a66a2 100644
--- a/usr.sbin/nslookup/subr.c
+++ b/usr.sbin/nslookup/subr.c
@@ -55,7 +55,7 @@
#ifndef lint
static char sccsid[] = "@(#)subr.c 5.24 (Berkeley) 3/2/91";
-static char rcsid[] = "$Id: subr.c,v 1.2 1994/09/22 21:50:41 pst Exp $";
+static char rcsid[] = "$Id: subr.c,v 1.3 1995/05/30 03:49:20 rgrimes Exp $";
#endif /* not lint */
/*
@@ -372,7 +372,9 @@ DecodeError(result)
case NXDOMAIN: return("Non-existent host/domain"); break;
case NOTIMP: return("Not implemented"); break;
case REFUSED: return("Query refused"); break;
+#ifdef NOCHANGE
case NOCHANGE: return("No change"); break;
+#endif
case TIME_OUT: return("Timed out"); break;
case NO_INFO: return("No information"); break;
case ERROR: return("Unspecified error"); break;
@@ -428,6 +430,8 @@ StringToType(type, dflt, errorfile)
return(T_NS); /* authoritative server */
if (strcasecmp(type, "MX") == 0)
return(T_MX); /* mail exchanger */
+ if (strcasecmp(type, "PX") == 0)
+ return(T_PX); /* mapping information */
if (strcasecmp(type, "CNAME") == 0)
return(T_CNAME); /* canonical name */
if (strcasecmp(type, "SOA") == 0)
@@ -474,6 +478,8 @@ StringToType(type, dflt, errorfile)
return(T_AFSDB); /* DCE or AFS server */
if (strcasecmp(type, "NSAP") == 0)
return(T_NSAP); /* NSAP address */
+ if (strcasecmp(type, "NSAP_PTR") == 0)
+ return(T_NSAP_PTR); /* NSAP reverse pointer */
if (errorfile)
fprintf(errorfile, "unknown query type: %s\n", type);
return(dflt);
@@ -524,6 +530,8 @@ DecodeType(type)
return("mailbox information");
case T_MX:
return("mail exchanger");
+ case T_PX:
+ return("mapping information");
case T_TXT:
return("text");
case T_RP:
@@ -538,6 +546,8 @@ DecodeType(type)
return("router");
case T_NSAP:
return("nsap address");
+ case T_NSAP_PTR:
+ return("domain name pointer");
case T_UINFO:
return("user information");
case T_UID: